{"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/survey-generator.ts","../src/rhf-generator.ts","../src/validator.ts","../src/schema/unified-form.schema.json","../src/form-field-category.ts","../src/form-field.ts","../src/form-spec.ts","../src/jurisdiction.ts","../src/form-field-validator.ts","../src/data/form-field-base-specs.json","../src/data/form-field-types.json","../src/data/form-field-validators.json","../src/catalogs.ts","../src/ihs-types.ts","../src/document-types.ts","../src/data/adapter-categories.json","../src/adapter-categories.ts","../src/data/v1-migration-map.json","../src/v1-migration-map.ts","../src/data/form-field-display-names.json","../src/ihs-processing.ts","../src/roles.ts","../src/extraction.ts","../src/ihs-status.ts","../src/extraction-status.ts","../src/adapter.ts","../src/adapter-aggregation.ts","../src/adapter-manifest.ts","../src/subject-canonical-view.ts"],"sourcesContent":["/*\n * Copyright 2025 Sisters Inspire Sdn Bhd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * @finsys/core\n * Convert unified form configurations into Zod schemas, React Hook Form defaults, and SurveyJS JSON\n */\n\n// Functions\nexport {\n  generateSurveyJson,\n  resolvePageFields,\n  getCategoryName,\n  groupFieldsByCategory,\n  applyDynamicTitles\n} from \"./survey-generator.js\";\n\nexport { getPastMonthLabel, getPastYearLabel, evaluateExpression } from \"./utils.js\";\n\nexport { \n  generateRHFSchema,\n  getStepSchema,\n  getStepDefaultValues\n} from \"./rhf-generator.js\";\n\nexport { validateFormConfig } from \"./validator.js\";\n\n// Unified Form Config types\nexport type {\n  Category,\n  Choice,\n  Validator,\n  FieldData,\n  FieldReference,\n  PageConfig,\n  UnifiedFormConfig,\n  ResolvedField,\n  FieldGroup,\n} from \"./survey-generator.js\";\n\n// Output types (SurveyJS JSON compatible)\nexport type { SurveyElementJSON, SurveyPageJSON, SurveyJSON } from \"./survey-generator.js\";\n\n// RHF Generator types\nexport type { RHFStep, RHFSchemaOutput } from \"./rhf-generator.js\";\n\n// Form domain classes\nexport { FormSpec } from \"./form-spec.js\";\n\n// SYS-3263: the jurisdiction registry. Shared contract — finsys-api's own\n// copy (src/domain/constants/jurisdiction.ts, SYS-2872) should import from\n// here rather than keep its own; that de-duplication is SYS-3258's.\nexport {\n  JURISDICTION,\n  DEFAULT_JURISDICTION,\n  JURISDICTION_CODES,\n  isJurisdiction,\n  resolveJurisdiction,\n  checkJurisdictionCompatibility,\n  describeIncompatibility,\n  IncompatibilityReason,\n  type Jurisdiction,\n  type JurisdictionCompatibility,\n} from \"./jurisdiction.js\";\nexport { default as FormField, BasicFormField, FileFormField, FieldType } from \"./form-field.js\";\nexport type { FormFieldType, FormFieldInputType, FormFieldTypeDefinitions, DropdownOption, EditorValidator } from \"./form-field.js\";\nexport { FormFieldCategory } from \"./form-field-category.js\";\nexport { FormFieldValidator } from \"./form-field-validator.js\";\nexport type { FormValidatorDefinitions } from \"./form-field-validator.js\";\n\n// Catalogs\nexport {\n  BASE_FIELD_SPECS,\n  DEFAULT_VALIDATOR_DEFINITIONS,\n  FIELD_TYPE_DEFINITIONS,\n  getBaseFieldSpecs,\n  getBaseCategories,\n  getBaseFieldNames,\n  getBaseFieldSpecMap,\n} from \"./catalogs.js\";\n\n// IHS data processing\nexport {\n  getDisplayNames,\n  getDisplayName,\n  getGroupDisplayNames,\n  extractTimePeriods,\n  groupColumnsByTimePeriod,\n  groupColumnsByInstance,\n  groupFieldsByPattern,\n  buildFileFieldTables,\n  buildFileFieldTablesFromInstances,\n  processIhsDetails,\n  groupDetailsByCategory,\n  // SYS-3334: the instance-shaped path — same output types, fed by a CanonicalView\n  processIhsDetailsFromView,\n  documentCategoryIds,\n  extractionCategoryOf,\n  buildDocumentRowsFromView,\n  documentsOfType,\n  documentHashOfKey,\n  documentHashOfPath,\n  legacyOrdinalOfKey,\n  // SYS-3334: buildFileFieldTables's instance-shaped sibling — the fourth\n  // and last flat file-field function to get one.\n  instanceRowsFromView,\n  buildFileFieldTablesFromView,\n  // SYS-3334 F3 (round 2 review): the provenance synthesis hoisted out of\n  // buildFileFieldTablesFromView — collision-aware, and usable on its own.\n  fieldProvenanceFromView,\n  // SYS-3334: the v1-shape bridge — the migration map run FORWARD (v1 key ->\n  // address -> value), so a consumer walking every flat key (an evaluation\n  // data factory, MatchingUtil, jurisdictionOf, the SSM panel) reads a\n  // CanonicalView through one map instead of each growing its own reverse walk.\n  flatRecordFromView,\n  APPLICATION_RECORD_CURRENCY_FIELDS,\n  registryMoneyLegacyNames,\n  buildDocumentRows,\n  parseFileField,\n  getDocDisplayNames,\n  getExtractableDocTypes,\n  getReuploadableDocTypes,\n  formatDocumentType,\n  formatDocumentSize,\n  formatDocumentUploaded,\n} from './ihs-processing.js'\n\nexport { IhsValueFormat, FileFieldTableType, isValidIhsFieldOrigin, IHS_FIELD_ORIGINS } from './ihs-types.js'\nexport {\n  JURISDICTION_DISPLAY_CURRENCY,\n  JURISDICTION_NATIONAL_ID_ENCODES_BIRTH_DATE,\n  NO_JURISDICTION_BASIS,\n  nationalIdEncodesBirthDate,\n  resolveDisplayCurrency,\n} from './jurisdiction.js'\nexport { formatMoney } from './ihs-processing.js'\nexport type { IhsFieldOrigin } from './ihs-types.js'\n\n// Roles\nexport { Role } from './roles.js'\n\n// Extraction\nexport { ExtractionJobStatus } from './extraction.js'\nexport type { ExtractionFileType } from './extraction.js'\nexport {\n  getDocumentTypeGroups,\n  isDocumentType,\n  assertDocumentType,\n} from './document-types.js'\nexport type { DocumentTypeGroup, WireFormat, TaggedFieldData, TimePeriodUnit } from './document-types.js'\n\n// IHS status (canonical enum, mirrors finsys-api)\nexport {\n  IhsStatus,\n  IHS_VALID_STATUSES,\n  IHS_TERMINAL_STATUSES,\n  IHS_FAILURE_STATUSES,\n  isValidIhsStatus,\n  isTerminalIhsStatus,\n  isFailureIhsStatus,\n} from './ihs-status.js'\n\n// Extraction status\nexport {\n  resolveExtractionStatus,\n  resolveExtractionStatusFromView,\n  DocExtractionStatus,\n} from './extraction-status.js'\n\nexport type {\n  ExtractionJobRecord,\n  DocExtractionResult,\n  ExtractionStatusResult,\n} from './extraction-status.js'\n\nexport type {\n  IhsFieldDetail,\n  IhsDetailCategory,\n  FileFieldTableData,\n  FileFieldTableItem,\n  IhsFieldProvenance,\n  // SYS-3334 F3 (round 2 review): IhsFieldProvenance + the overlay-replaced\n  // value, for fieldProvenanceFromView's return shape.\n  IhsFieldProvenanceWithOriginal,\n  DocumentRow,\n  DocumentRowCapabilities,\n  DocumentFileMetadata,\n  InstanceRow,\n} from './ihs-types.js'\n\nexport type { CategorySpec } from './ihs-processing.js'\n\n// SYS-3174: the shape of one entry inside a document-pointer field. Exported\n// so the host can name what it is attesting as `document-intake` rows rather\n// than declaring a private copy of it.\nexport type { ParsedDocFile } from './ihs-processing.js'\n\n// SYS-3334: the v1-shape bridge's own types — the record half of the v2 read\n// pair (structural, so core need not import the SDK) and its return shape.\nexport type { ApplicationRecordLike, FlatRecordFromView } from './ihs-processing.js'\n// SYS-3438: `ViewDocument` (documentsOfType's return type) was declared and\n// documented as exported in 8.1.0 and never added here — TS2459 for consumers.\nexport type { ViewDocument } from './ihs-processing.js'\n\n// ── Source Adapter framework (SYS-2440) ──────────────────────────────\n// The contract for ingesting unstructured / partner-specific data\n// sources and producing canonical credit signals. Vendor-specific\n// adapter implementations live OUTSIDE this open-source package, in\n// private extension directories loaded by the host app at runtime.\n// finsys-core publishes the contract + the category catalogue.\n\nexport type {\n  RawPayload,\n  CanonicalFieldValue,\n  CanonicalFieldValues,\n  AdapterExtraction,\n  PeriodValues,\n  SourceAdapter,\n  AdapterErrorReason,\n  ApplicantIdentity,\n} from './adapter.js'\n\nexport { AdapterError } from './adapter.js'\n\nexport type { AggregationOp, InstanceValue } from './adapter-aggregation.js'\nexport { applyAggregation, ALL_AGGREGATION_OPS } from './adapter-aggregation.js'\n\nexport type {\n  AdapterCategory,\n  CanonicalFieldName,\n  CanonicalFieldSpec,\n  CategorySchema,\n} from './adapter-categories.js'\n\n// NB: `buildCategoryRegistry` + the `CategoryRegistry` shape are\n// intentionally NOT re-exported here. They're the internal loader (and\n// its return type, which carries mutable Maps that `ReadonlyMap` only\n// guards at compile time). Keeping them out of the package's public API\n// avoids exposing a corruptible view of the shared singleton registry.\n// They remain module-exported for finsys-core's own tests. Promote to a\n// public, defensively-immutable API only when a consumer (e.g. host-side\n// category merging in a future phase) actually needs it.\nexport {\n  ADAPTER_CATEGORY_IDS,\n  categorySchemaOf,\n  categoryFieldsOf,\n  allCategories,\n  categoryForField,\n  factOf,\n  categoriesAttestingFact,\n  resolveCanonicalFieldName,\n  resolveCanonicalCategoryId,\n  isLegacyCategoryId,\n  isFieldSensitive,\n  sensitiveFieldsOf,\n  isAdapterCategory,\n  assertAdapterCategory,\n} from './adapter-categories.js'\n\nexport type {\n  AdapterManifest,\n  DeclarativeImplementation,\n  TypescriptImplementation,\n  FormIntakeImplementation,\n  FormIntakeFieldMapEntry,\n  ManualOverrideImplementation,\n  ExtractionPipelineImplementation,\n  ExternalAssertionImplementation,\n  FieldAuthorization,\n  FieldMapEntry,\n  PeriodDeclaration,\n} from './adapter-manifest.js'\n\n// SYS-3036: execution-mode classification, published so every host\n// classifies manifests identically instead of re-deriving the switch.\nexport { AdapterExecutionMode, executionModeOf } from './adapter-manifest.js'\n\n// SYS-3414: where every v1 flat-IHS key goes in v2 — including the ones with\n// no destination, which is the half a rename table omits and the half that\n// loses data. A migration instrument, not a runtime shim.\nexport type {\n  V1Disposition,\n  V1ResolutionSource,\n  V1Address,\n  V1MigrationEntry,\n} from './v1-migration-map.js';\n\nexport {\n  V1_MIGRATION_MAP_VERSION,\n  v1MigrationKeys,\n  v1MigrationEntry,\n  v1Addresses,\n  v1KeysByDisposition,\n  v1KeyForAddress,\n  v1AddressHasKeyedEntries,\n  v1LegacyBaseNameOf,\n} from './v1-migration-map.js';\n\n// SYS-3334: the v2 canonical envelope. Owned here rather than in the lender\n// SDK, because it is the wire shape of a published API and every consumer\n// needs it — finhub through its own gateway, FHD's portal later, not only\n// external lenders holding @finsys/lender-client (which re-exports these).\nexport type {\n  CanonicalFieldEnvelope,\n  // SYS-3421: declared in 8.1.0's first candidate but left out of this list —\n  // finsys-api's resolver found it (TS2305) and had to mirror the interface\n  // locally. Every member of the envelope is exported, or the wire shape is\n  // not owned here at all.\n  CanonicalAttestation,\n  CanonicalInstance,\n  CanonicalCategory,\n  CanonicalView,\n  CanonicalAddress,\n  // SYS-3542 (SYS-3463a): the subject-scoped counterpart CanonicalView's own\n  // doc anticipates by name. See canonical-view.ts for why these cannot be\n  // interchangeable with the application-scoped types above.\n  SubjectInstance,\n  SubjectCanonicalCategory,\n  SubjectCanonicalView,\n  // SYS-3554: the (furnisherId, recordRef) pair that identifies a contributed\n  // observation, replacing SubjectInstance's old `{ sourceIhsId: number }`.\n  SubjectSource,\n  // SYS-3464: one canonical field's winning observation, carrying THAT\n  // observation's provenance rather than the row's. Reached through\n  // SubjectCanonicalCategory.fieldsByInstanceKey, which is what a consumer\n  // reads for a field's value instead of spreading instances[0].fields flat.\n  SubjectFieldSelection,\n} from './canonical-view.js';\n\n// SYS-3542 (SYS-3463a): the one merge that builds a SubjectCanonicalView out\n// of several applications' CanonicalViews. Kept in its own module rather\n// than canonical-view.ts — see that file's \"WHAT THIS FILE IS NOT\" note and\n// subject-canonical-view.ts's own doc for why instance-selection logic lives\n// apart from the types it selects over.\nexport type { SubjectViewRecord, SubjectViewErrorCode } from './subject-canonical-view.js';\n// SYS-3554: `sameSubjectSource` is the supported way to ask whether two\n// SubjectInstances came from the same furnished record — exported so that no\n// consumer builds a joined `${furnisherId}#${recordRef}` key to do it, which\n// is ambiguous because both halves are opaque. See SubjectSource's own doc.\nexport { subjectViewFromRecords, sameSubjectSource, SubjectViewError } from './subject-canonical-view.js';\n","/*\n * Copyright 2025 Sisters Inspire Sdn Bhd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Utility functions for @finsys/core\n */\n\nexport function getPastMonthLabel(monthsAgo: number): string {\n  const date = new Date();\n  date.setDate(1); // Avoid day-of-month rollover (e.g. Mar 31 → \"February\" would roll to March)\n  date.setMonth(date.getMonth() - monthsAgo);\n  return date.toLocaleString('default', { month: 'long' });\n}\n\nexport function getPastYearLabel(yearsAgo: number): string {\n  const date = new Date();\n  return (date.getFullYear() - yearsAgo).toString();\n}\n\n/**\n * Evaluate a SurveyJS-style expression against a data object.\n * e.g. \"{totalFinancing} > 50000\"\n * \n * NOTE: This is a simplified evaluator that replaces {key} with data[key] access.\n * It does not support complex SurveyJS functions like age() or complicated nested paths unless handled by JS.\n */\nexport function evaluateExpression(expression: string, data: any): boolean {\n  if (!expression) return true;\n  \n  try {\n    // 1. Replace {variable} with this['variable'] safely\n    let jsExpression = expression.replace(/\\{([^}]+)\\}/g, (_, key) => {\n      // Clean key if needed (trim)\n      return `this['${key.trim()}']`;\n    });\n\n    // 2. Map SurveyJS comparison operators to JS operators FIRST\n    //    (before array operator transforms inject JS code containing '=' assignments)\n    // Replace single '=' with '==' if it's not already '==' or '!=' or '>=' or '<='\n    jsExpression = jsExpression.replace(/(?<![<>!=])=(?![=])/g, '==');\n\n    // 3. Map SurveyJS array operators to JS equivalents\n    //    These run AFTER the '=' transform so their generated JS won't be mangled.\n\n    //    \"anyof\" → value is one of the items in the array\n    //    e.g. this['employmentType'] anyof ['01','08','09']\n    //      → (['01','08','09']).includes(this['employmentType'])\n    jsExpression = jsExpression.replace(\n      /(this\\['[^']+'\\])\\s+anyof\\s+(\\[[^\\]]+\\])/gi,\n      (_, ref, arr) => `(${arr}).includes(${ref})`\n    );\n\n    //    \"allof\" → value (expected to be an array) contains all items\n    //    e.g. this['skills'] allof ['a','b']\n    //      → ['a','b'].every(item => (this['skills'] || []).includes(item))\n    //    Arrow functions inherit `this` from enclosing scope (the new Function call),\n    //    so this works correctly with Function.call(data).\n    jsExpression = jsExpression.replace(\n      /(this\\['[^']+'\\])\\s+allof\\s+(\\[[^\\]]+\\])/gi,\n      (_, ref, arr) => `${arr}.every(item => (${ref} || []).includes(item))`\n    );\n\n    //    \"contains\" → string/array contains value\n    //    e.g. this['roles'] contains 'admin'\n    //    Uses || [] fallback to handle both string and array values correctly.\n    //    (|| '' would stringify arrays causing false positives)\n    jsExpression = jsExpression.replace(\n      /(this\\['[^']+'\\])\\s+contains\\s+'([^']+)'/gi,\n      (_, ref, val) => `(${ref} || []).includes('${val}')`\n    );\n\n    //    \"notcontains\" → string/array does not contain value\n    jsExpression = jsExpression.replace(\n      /(this\\['[^']+'\\])\\s+notcontains\\s+'([^']+)'/gi,\n      (_, ref, val) => `!(${ref} || []).includes('${val}')`\n    );\n\n    // 4. Execute with Function, binding 'data' as 'this'\n    const func = new Function(`return ${jsExpression};`);\n    return !!func.call(data || {});\n  } catch (e) {\n    // console.warn(`Failed to evaluate expression: \"${expression}\"`, e);\n    return false;\n  }\n}\n","/*\n * Copyright 2025 Sisters Inspire Sdn Bhd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Survey Generator - Converts unified form configurations into SurveyJS-compatible JSON\n *\n * This module converts a unified form-config.json into SurveyJS-compatible JSON,\n * resolving field references, applying dynamic titles, and grouping by category.\n */\n\nimport type { Jurisdiction } from \"./jurisdiction.js\";\nimport { getPastMonthLabel, getPastYearLabel } from \"./utils.js\";\n\n// ============ Unified Form Config Types ============\n\nexport interface Category {\n  id: string;\n  name: string;\n}\n\nexport interface Choice {\n  value: string;\n  text: string;\n}\n\nexport interface Validator {\n  type: \"regex\" | \"email\" | \"numeric\" | \"text\" | \"expression\" | \"answercount\" | \"custom\";\n  text?: string;\n  regex?: string;\n  minValue?: number;\n  maxValue?: number;\n  minLength?: number;\n  maxLength?: number;\n  minCount?: number;\n  maxCount?: number;\n  expression?: string;\n  validator?: string; // For custom validator name\n}\n\n/**\n * FieldData - Field definition in the unified form config\n */\nexport interface FieldData {\n  name?: string;  // Optional in fields{} (key is name), required in arrays\n  displayName?: string;\n  type: string;\n  inputType?: \"text\" | \"number\" | \"tel\" | \"date\" | \"email\" | \"password\" | \"url\";\n  category?: string;  // Category ID (strictly string)\n  maxLength?: number | string;\n  min?: number | string;\n  max?: number | string;\n  step?: number;\n  html?: string;\n  choices?: Choice[];\n  validators?: Validator[];\n  visible?: boolean;\n  visibleIf?: string;\n  required?: boolean;\n  isRequired?: boolean;  // SurveyJS compat alias\n  placeholder?: string;\n  defaultValue?: string | number | boolean | string[];\n  readOnly?: boolean;\n  startWithNewLine?: boolean;\n  enableIf?: string;\n  titleLocation?: \"default\" | \"top\" | \"bottom\" | \"left\" | \"hidden\";\n  /**\n   * Semantic refinement of `type`, using the SAME vocabulary as the\n   * canonical field registry's `CanonicalFieldSpec.kind` (SYS-3249). One\n   * word, one meaning, on both halves of the system.\n   *\n   * `kind: \"money\"` says the field holds an amount of money. It does NOT\n   * say WHICH money — the denomination comes from the program's\n   * jurisdiction at render time, or from the value's own provenance\n   * envelope once it has one.\n   *\n   * The point is that a label must never carry the currency. Writing\n   * \"Financing Amount (RM)\" makes the field Malaysian by typography: it\n   * renders identically under a Vietnamese program, where it is simply\n   * false, and no code can correct it because the currency is prose. A\n   * declared kind is something a renderer can act on.\n   */\n  kind?: \"money\";\n  // FinSys-specific fields\n  ihs_column_names?: string[];\n  requiredForEvaluation?: boolean;\n  [key: string]: unknown;\n}\n\n/**\n * FieldReference - How fields are referenced in pages\n */\nexport type FieldReference = \n  | string  // Simple field name reference\n  | { ref: string; [key: string]: unknown }  // Reference with overrides\n  | { definition: FieldData & { name: string } };  // Inline definition\n\nexport interface PageConfig {\n  id: string;\n  title?: string;\n  description?: string;\n  showTOC?: boolean;\n  showProgressBar?: boolean;\n  showCategoryHeadings?: boolean;\n  layout?: \"default\" | \"grid\" | \"vertical\";\n  fields: FieldReference[];\n}\n\n/**\n * UnifiedFormConfig - The main configuration type for the unified form format\n */\nexport interface UnifiedFormConfig {\n  $schema?: string;\n  schemaVersion?: string;\n  displayName?: string;\n  templateIcon?: string;  // Icon identifier for form template editors\n  categories: Category[];\n  fields: Record<string, FieldData>;\n  pages?: PageConfig[];  // Optional when used in editor-only mode (no rendered form)\n  /**\n   * SYS-3263: the single jurisdiction this form is valid for; absent means\n   * Malaysia. Declared HERE and not only on FormSpec because FinHub never\n   * constructs a FormSpec — it handles form configs exclusively as raw\n   * UnifiedFormConfig (validates, stores in a JSONB column, ships to React).\n   * Without this the declaration is invisible to two of the three consumers,\n   * and SYS-3265 enforcement would need a cast to read it.\n   */\n  jurisdiction?: Jurisdiction;\n}\n\n\n// ============ Output Types (SurveyJS JSON compatible) ============\n\nexport interface SurveyElementJSON {\n  type: string;\n  name: string;\n  title?: string;\n  isRequired?: boolean;\n  maxLength?: number;\n  storeDataAsText?: boolean;\n  category?: string;\n  [key: string]: unknown;\n}\n\nexport interface SurveyPageJSON {\n  name: string;\n  title: string;\n  elements: Array<{\n    type: string;\n    name: string;\n    elements: SurveyElementJSON[];\n  }>;\n}\n\nexport interface SurveyJSON {\n  title: string;\n  logoPosition?: string;\n  pages: SurveyPageJSON[];\n  showQuestionNumbers?: string;\n  questionErrorLocation?: string;\n  completedHtml?: string;\n  showTOC?: boolean;\n  completeText?: string;\n  showPreviewBeforeComplete?: string;\n  showProgressBar?: string;\n  widthMode?: string;\n  width?: string;\n}\n\n// ============ Helper Types ============\n\nexport interface ResolvedField extends FieldData {\n  name: string;\n}\n\n/**\n * Normalize a field to ensure backward compatibility\n * - Sets both `required` and `isRequired` to the same value\n */\nfunction normalizeField(field: ResolvedField): ResolvedField {\n  // Spec: Fields are required by default unless explicitly false\n  const isRequired = field.isRequired !== false && field.required !== false;\n  return {\n    ...field,\n    required: isRequired,\n    isRequired: isRequired\n  };\n}\n\n/**\n * Resolve a field reference to a full field definition\n */\nfunction resolveFieldReference(\n  ref: FieldReference, \n  fields: Record<string, FieldData>\n): ResolvedField | null {\n  if (typeof ref === \"string\") {\n    // Simple string reference\n    const fieldDef = fields[ref];\n    if (!fieldDef) {\n      console.warn(`Field \"${ref}\" not found in fields definition`);\n      return null;\n    }\n    return normalizeField({ name: ref, ...fieldDef });\n  }\n  \n  if (\"definition\" in ref) {\n    // Inline definition\n    return normalizeField(ref.definition as ResolvedField);\n  }\n  \n  if (\"ref\" in ref) {\n    // Reference with overrides\n    const fieldDef = fields[ref.ref];\n    if (!fieldDef) {\n      console.warn(`Field \"${ref.ref}\" not found in fields definition`);\n      return null;\n    }\n    const { ref: fieldName, ...overrides } = ref;\n    return normalizeField({ name: fieldName, ...fieldDef, ...overrides });\n  }\n  \n  return null;\n}\n\n/**\n * Apply dynamic title logic (e.g., bank statements with dynamic month labels,\n * financial statements with dynamic year labels)\n */\nexport function applyDynamicTitles(field: ResolvedField): ResolvedField {\n  const bankStatementMatch = field.name.match(/^bank_statement_t(\\d+)$/);\n  if (bankStatementMatch) {\n    const monthsAgo = parseInt(bankStatementMatch[1], 10);\n    return {\n      ...field,\n      displayName: `Bank Statement (${getPastMonthLabel(monthsAgo)})`\n    };\n  }\n  if (field.name === \"financials\") {\n    return {\n      ...field,\n      displayName: `Audited Financial Statement (${getPastYearLabel(1)})`\n    };\n  }\n  return field;\n}\n\n/**\n * Generate SurveyJS JSON from unified form config\n */\nexport function generateSurveyJson(config: UnifiedFormConfig): SurveyJSON | Record<string, never> {\n  if (!config.pages || config.pages.length === 0) return {};\n  \n  const firstPage = config.pages.find(p => p.id !== \"success-message\");\n  if (!firstPage) return {};\n\n  const categories = config.categories || [];\n  const categoryMap: Record<string, string> = categories.reduce((acc, cat) => {\n    acc[cat.id] = cat.name;\n    return acc;\n  }, {} as Record<string, string>);\n\n  // Process all fields from the first page\n  const processedFields = firstPage.fields\n    .map(ref => resolveFieldReference(ref, config.fields))\n    .filter((f): f is ResolvedField => f !== null)\n    .map(f => applyDynamicTitles(f))\n    .map(f => mapFieldToSurveyJS(f));\n\n  // Group by Category\n  const grouped = processedFields.reduce((acc: Record<string, SurveyElementJSON[]>, field) => {\n    const catName = categoryMap[field.category as string] || \"Default\";\n    if (!acc[catName]) acc[catName] = [];\n    acc[catName].push(field);\n    return acc;\n  }, {} as Record<string, SurveyElementJSON[]>);\n\n  // Build Pages (One Page per Category for Wizard effect)\n  const pages: SurveyPageJSON[] = Object.entries(grouped).map(([categoryName, elements]) => ({\n    name: categoryName.toLowerCase().replace(/\\s+/g, \"-\"),\n    title: firstPage.showCategoryHeadings === false ? \"\" : categoryName,\n    elements: [\n      {\n        type: \"panel\",\n        name: `${categoryName.toLowerCase().replace(/\\s+/g, \"-\")}-panel`,\n        elements: elements,\n      },\n    ],\n  }));\n\n  return {\n    title: config.displayName || \"Flexible Financing Program\",\n    logoPosition: \"right\",\n    pages,\n    showQuestionNumbers: \"off\",\n    questionErrorLocation: \"bottom\",\n    completedHtml: \"<h3>Thank you for completing the form</h3>\",\n    showTOC: firstPage.showTOC ?? true,\n    completeText: \"Submit\",\n    showPreviewBeforeComplete: \"showAllQuestions\",\n    showProgressBar: firstPage.showProgressBar === false ? \"off\" : \"top\",\n    widthMode: \"responsive\",\n    width: \"100%\",\n  };\n}\n\n/**\n * Map a field definition to SurveyJS element format\n */\nfunction mapFieldToSurveyJS(field: ResolvedField): SurveyElementJSON {\n  const element: SurveyElementJSON = {\n    type: field.type,\n    name: field.name,\n    ...(field.displayName && { title: field.displayName }),\n    isRequired: field.isRequired ?? field.required ?? false,\n    ...(field.maxLength && { maxLength: Number(field.maxLength) }),\n  };\n\n  if (field.type === \"file\") {\n    element.storeDataAsText = false;\n  }\n\n  // Copy other properties\n  const excludeKeys = [\"displayName\", \"required\", \"category\"];\n  Object.keys(field).forEach((key) => {\n    if (!(key in element) && !excludeKeys.includes(key) && field[key] !== undefined) {\n      element[key] = field[key];\n    }\n  });\n\n  // Store category for grouping\n  element.category = field.category ?? \"\";\n\n  return element;\n}\n\n/**\n * Resolve all fields from a page to full field definitions\n */\nexport function resolvePageFields(\n  page: PageConfig,\n  fields: Record<string, FieldData>\n): ResolvedField[] {\n  return page.fields\n    .map(ref => resolveFieldReference(ref, fields))\n    .filter((f): f is ResolvedField => f !== null)\n    .map(f => applyDynamicTitles(f));\n}\n\n/**\n * Get category name from category ID (supports string or number IDs)\n */\nexport function getCategoryName(\n  categoryId: string | undefined,\n  categories: Category[]\n): string {\n  if (categoryId === undefined) return \"Other\";\n  const cat = categories.find(c => c.id === categoryId);\n  return cat?.name || \"Other\";\n}\n\n/**\n * Group fields by their category, maintaining order and creating section breaks\n */\nexport interface FieldGroup {\n  category: string;\n  categoryName: string;\n  fields: ResolvedField[];\n}\n\nexport function groupFieldsByCategory(\n  fields: ResolvedField[],\n  categories: Category[]\n): FieldGroup[] {\n  const groups: FieldGroup[] = [];\n  let currentGroup: FieldGroup | null = null;\n\n  for (const field of fields) {\n    const category = field.category ?? \"\";\n    \n    if (!currentGroup || currentGroup.category !== category) {\n      currentGroup = {\n        category,\n        categoryName: getCategoryName(category, categories),\n        fields: []\n      };\n      groups.push(currentGroup);\n    }\n    \n    currentGroup.fields.push(field);\n  }\n\n  return groups;\n}\n","/*\n * Copyright 2025 Sisters Inspire Sdn Bhd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { z } from \"zod\";\nimport {\n  type UnifiedFormConfig,\n  type PageConfig,\n  type FieldData,\n  type FieldReference,\n  type ResolvedField,\n  type Category,\n  resolvePageFields,\n  groupFieldsByCategory,\n  applyDynamicTitles,\n  type FieldGroup\n} from \"./survey-generator.js\";\nimport { evaluateExpression } from \"./utils.js\";\n\nexport interface RHFStep {\n  id: number;\n  title: string;\n  description?: string;\n  fields: ResolvedField[];\n  showCategoryHeadings: boolean;\n  layout?: \"default\" | \"grid\" | \"vertical\";\n}\n\nexport interface RHFSchemaOutput {\n  zodSchema: z.ZodTypeAny; // Can be ZodEffects\n  baseSchema: z.ZodObject<any>;\n  defaultValues: Record<string, any>;\n  fields: ResolvedField[];\n  groupedFields: FieldGroup[];\n  steps: RHFStep[];\n  displayName: string;\n  categories: Category[];\n  templateIcon?: string;\n}\n\n/**\n * Apply visibility-aware validation to a Zod schema\n */\nfunction applyVisibilityValidation(\n  baseObject: z.ZodObject<any>, \n  fields: ResolvedField[]\n): z.ZodTypeAny {\n  return baseObject.superRefine((data, ctx) => {\n    fields.forEach((field) => {\n      const isRequired = field.isRequired !== false && field.required !== false && field.type !== \"html\";\n      if (!isRequired) return;\n\n      // Determine Visibility\n      let isVisible = field.visible !== false;\n      if (isVisible && field.visibleIf) {\n        isVisible = evaluateExpression(field.visibleIf, data);\n      }\n\n      if (isVisible) {\n        const value = data[field.name];\n        const isEmpty = \n          value === undefined || \n          value === null || \n          value === \"\" || \n          (Array.isArray(value) && value.length === 0);\n\n        if (isEmpty) {\n          ctx.addIssue({\n            code: z.ZodIssueCode.custom,\n            message: \"This field is required\",\n            path: [field.name],\n          });\n        }\n      }\n    });\n  });\n}\n\nexport function generateRHFSchema(config: UnifiedFormConfig): RHFSchemaOutput {\n  // ... (existing logic for collecting fields/building shape)\n  const pages = config.pages || [];\n  const categories = config.categories || [];\n  const fieldsMap = config.fields || {};\n\n  if (pages.length === 0) {\n    throw new Error(\"v2.0.0 templates must include a 'pages' configuration.\");\n  }\n\n  // 1. Collect all fields from all pages\n  const allFields: ResolvedField[] = [];\n  \n  for (const page of pages) {\n    const pageFields = resolvePageFields(page, fieldsMap);\n    allFields.push(...pageFields);\n  }\n\n  // Apply dynamic titles\n  const mergedFields = allFields.map(applyDynamicTitles);\n\n  // 2. Build Zod Shape & Default Values\n  const shape: Record<string, z.ZodTypeAny> = {};\n  const defaultValues: Record<string, any> = {};\n\n  mergedFields.forEach((field) => {\n    let schema: z.ZodTypeAny = z.string();\n\n    // Track base type before validators/wrapping transform it via .refine()\n    // (instanceof checks won't work after .refine() converts ZodString → ZodEffects)\n    let baseType: \"string\" | \"number\" | \"array\" | \"boolean\" | \"any\" = \"string\";\n\n    // --- Base Type Handling ---\n    if (field.inputType === \"number\" || field.type === \"number\" || field.type === \"slider\" || field.type === \"range\") {\n      schema = z.coerce.number();\n      baseType = \"number\";\n      defaultValues[field.name] = field.defaultValue !== undefined ? Number(field.defaultValue) : \"\";\n    } else if (field.type === \"checkbox\") {\n      schema = z.array(z.string());\n      baseType = \"array\";\n      defaultValues[field.name] = [];\n    } else if (field.type === \"file\") {\n      schema = z.array(z.any());\n      baseType = \"array\";\n      defaultValues[field.name] = [];\n    } else if (field.type === \"boolean\") {\n      schema = z.boolean();\n      baseType = \"boolean\";\n      defaultValues[field.name] = field.defaultValue ?? false;\n    } else if (field.type === \"html\") {\n      schema = z.any().optional();\n      baseType = \"any\";\n      defaultValues[field.name] = \"\";\n    } else {\n      if (Array.isArray(field.defaultValue)) {\n        defaultValues[field.name] = field.defaultValue[0] || \"\";\n      } else {\n        defaultValues[field.name] = field.defaultValue ?? \"\";\n      }\n    }\n\n    // --- Validation Constraints ---\n\n    // Min/Max for Numbers\n    if (baseType === \"number\" && schema instanceof z.ZodNumber) {\n      let numSchema = schema;\n      if (field.min !== undefined) numSchema = numSchema.min(Number(field.min), { message: `Minimum value is ${field.min}` });\n      if (field.max !== undefined) numSchema = numSchema.max(Number(field.max), { message: `Maximum value is ${field.max}` });\n      schema = numSchema;\n    }\n\n    const isRequired = field.isRequired !== false && field.required !== false && field.type !== \"html\";\n    const isAlwaysVisible = field.visible !== false && !field.visibleIf;\n    const isActuallyInput = field.type !== \"html\";\n\n    // --- Required .min(1) for always-visible fields ---\n    // Must be applied BEFORE validators (.refine) which change the schema type.\n    if (isRequired && isAlwaysVisible && isActuallyInput) {\n      if (baseType === \"string\" && schema instanceof z.ZodString) {\n        schema = schema.min(1, { message: \"This field is required\" });\n      } else if (baseType === \"array\" && schema instanceof z.ZodArray) {\n        schema = schema.min(1, { message: \"Please select at least one option\" });\n      }\n    }\n\n    // --- Enhancements: Validators ---\n    // Applied BEFORE optional wrapping so instanceof checks still work on the\n    // base type. The .refine() calls here will transform the schema to ZodEffects,\n    // which is why we use baseType for subsequent decisions instead of instanceof.\n\n    // Email\n    const hasExplicitEmailValidator = field.validators?.some(v => v.type === \"email\");\n    if ((field.inputType === \"email\" || field.name === \"email\") && baseType === \"string\" && schema instanceof z.ZodString && !hasExplicitEmailValidator) {\n      schema = schema.refine(val => val === \"\" || z.string().email().safeParse(val).success, {\n        message: \"Invalid email address\"\n      });\n    }\n\n    // Legacy Validators (Regex / Numeric)\n    if (field.validators) {\n      field.validators.forEach((v) => {\n        if (v.type === \"regex\" && v.regex) {\n          try {\n            const regex = new RegExp(v.regex);\n            if (baseType === \"string\") {\n              schema = schema.refine((val: any) => val === \"\" || regex.test(val), {\n                message: v.text || \"Invalid format\"\n              });\n            }\n          } catch (e) {\n            console.warn(`Invalid regex pattern for field ${field.name}:`, v.regex);\n          }\n        }\n        if (v.type === \"email\" && baseType === \"string\") {\n          schema = schema.refine((val: any) => val === \"\" || z.string().email().safeParse(val).success, {\n            message: v.text || \"Invalid email\"\n          });\n        }\n        if (v.type === \"numeric\" && schema instanceof z.ZodNumber) {\n          let numSchema = schema;\n          if (v.minValue !== undefined) numSchema = numSchema.min(v.minValue, { message: v.text });\n          if (v.maxValue !== undefined) numSchema = numSchema.max(v.maxValue, { message: v.text });\n          schema = numSchema;\n        }\n      });\n    }\n\n    // --- Final Wrapper: Optional for conditional/hidden fields ---\n    // Uses baseType instead of instanceof since validators may have transformed the schema.\n    if (!(isRequired && isAlwaysVisible && isActuallyInput)) {\n      if (baseType === \"number\") {\n        schema = schema.optional().or(z.literal(\"\")).or(z.null());\n      } else if (baseType === \"array\") {\n        schema = schema.optional();\n      } else if (baseType === \"boolean\") {\n        schema = schema.optional();\n      } else if (baseType === \"string\") {\n        schema = schema.optional().or(z.literal(\"\"));\n      }\n    }\n\n    shape[field.name] = schema;\n  });\n\n  // 3. Group Fields by Category\n  const groupedFields = groupFieldsByCategory(mergedFields, categories);\n\n  // 4. Build Steps (Dynamic Wizard)\n  const steps: RHFStep[] = pages.map((page, idx) => {\n    const pageFields = resolvePageFields(page, fieldsMap);\n\n    return {\n      id: idx,\n      title: page.title || \"\",\n      description: page.description,\n      fields: pageFields,\n      showCategoryHeadings: page.showCategoryHeadings ?? false,\n      layout: page.layout\n    };\n  });\n\n  // 5. Build Final Schema with Visibility-Aware Validation\n  const baseObject = z.object(shape);\n  const zodSchema = applyVisibilityValidation(baseObject, mergedFields);\n\n  return {\n    zodSchema,\n    baseSchema: baseObject,\n    defaultValues,\n    fields: mergedFields,\n    groupedFields,\n    steps,\n    displayName: config.displayName || \"Application Form\",\n    categories,\n    templateIcon: config.templateIcon\n  };\n}\n\n/**\n * Get Zod schema for a specific step\n */\nexport function getStepSchema(step: RHFStep, fullSchema: any): z.ZodTypeAny {\n  const stepFieldNames = step.fields.map(f => f.name);\n  const stepShape: Record<string, z.ZodTypeAny> = {};\n  \n  // 1. Determine the base ZodObject\n  let baseObj: z.ZodObject<any> | undefined;\n\n  if (fullSchema instanceof z.ZodObject) {\n    baseObj = fullSchema;\n  } else if (fullSchema && typeof fullSchema === \"object\" && \"baseSchema\" in fullSchema) {\n    baseObj = fullSchema.baseSchema as z.ZodObject<any>;\n  } else if (fullSchema && \"_def\" in fullSchema && fullSchema._def.schema instanceof z.ZodObject) {\n    // Basic Unwrap for ZodEffects\n    baseObj = fullSchema._def.schema;\n  }\n\n  if (!baseObj) {\n    console.warn(\"[RHF Generator] Could not extract ZodObject shape for step validation\");\n    return z.object({});\n  }\n\n  const shape = baseObj.shape;\n  const stepFields: ResolvedField[] = [];\n  \n  stepFieldNames.forEach(name => {\n    if (name in shape) {\n      stepShape[name] = shape[name];\n      // Keep track of which fields are in this step\n      const fieldDef = step.fields.find(f => f.name === name);\n      if (fieldDef) stepFields.push(fieldDef);\n    }\n  });\n  \n  const stepBaseObject = z.object(stepShape);\n  return applyVisibilityValidation(stepBaseObject, stepFields);\n}\n\n/**\n * Extract default values for a specific step\n */\nexport function getStepDefaultValues(\n  step: RHFStep, \n  allDefaults: Record<string, any>\n): Record<string, any> {\n  const stepDefaults: Record<string, any> = {};\n  \n  step.fields.forEach(field => {\n    if (field.name in allDefaults) {\n      stepDefaults[field.name] = allDefaults[field.name];\n    }\n  });\n  \n  return stepDefaults;\n}\n","/*\n * Copyright 2025 Sisters Inspire Sdn Bhd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport AjvModule, { ErrorObject } from \"ajv\";\nimport addFormats from \"ajv-formats\";\nimport unifiedFormSchema from \"./schema/unified-form.schema.json\" with { type: \"json\" };\n\n// Interop for Ajv which can be exported differently in ESM/CJS\nconst Ajv = (AjvModule as any).default || AjvModule;\nconst ajv = new Ajv({ allErrors: true, strict: false });\n\n// Interop for ajv-formats\nconst addFormatsFn = (addFormats as any).default || addFormats;\naddFormatsFn(ajv);\n\n// Register the unified schema\najv.addSchema(unifiedFormSchema, \"unified-form.schema.json\");\n\nexport interface ValidationResult {\n  valid: boolean;\n  errors?: ErrorObject[];\n  message?: string;\n}\n\n/**\n * Validates a unified form-config.json object against its schema\n */\nexport function validateFormConfig(data: unknown): ValidationResult {\n  const validate = ajv.getSchema(\"unified-form.schema.json\");\n  if (!validate) {\n    return { valid: false, message: \"Could not load unified form schema\" };\n  }\n\n  const valid = validate(data);\n  return {\n    valid: !!valid,\n    errors: validate.errors || undefined,\n  };\n}\n\n","{\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"title\": \"Unified Form Configuration Schema\",\n  \"description\": \"A unified schema combining field definitions and page layout configuration for multi-step forms.\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"$schema\": {\n      \"type\": \"string\",\n      \"description\": \"Reference to this JSON schema file\"\n    },\n    \"schemaVersion\": {\n      \"type\": \"string\",\n      \"pattern\": \"^v?[0-9]+\\\\.[0-9]+\\\\.[0-9]+$\",\n      \"description\": \"Semantic version of the schema format (e.g., 'v2.0.0' or '2.0.0')\"\n    },\n    \"displayName\": {\n      \"type\": \"string\",\n      \"description\": \"The human-readable name of the loan product or form\"\n    },\n    \"templateIcon\": {\n      \"type\": \"string\",\n      \"description\": \"Icon identifier or path for the form template (used in FinSys editor)\"\n    },\n    \"categories\": {\n      \"type\": \"array\",\n      \"description\": \"Category definitions for field organization and grouping\",\n      \"items\": {\n        \"$ref\": \"#/definitions/category\"\n      }\n    },\n    \"fields\": {\n      \"type\": \"object\",\n      \"description\": \"Master field definitions keyed by field name\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/fieldData\"\n      }\n    },\n    \"pages\": {\n      \"type\": \"array\",\n      \"description\": \"Ordered list of pages in the form wizard. Optional for FinSys editor mode.\",\n      \"items\": {\n        \"$ref\": \"#/definitions/pageConfig\"\n      }\n    },\n    \"jurisdiction\": {\n      \"type\": \"string\",\n      \"description\": \"SYS-3263: the single jurisdiction this form is valid for (ISO 3166-1 alpha-2). Optional; absent means Malaysia. A form may be used by many programs sharing its jurisdiction, and must not be used to submit to a program in another. The enum is a SECOND source of truth for the code set, pinned against JURISDICTION_CODES by a drift test — adding a jurisdiction means editing both. Kept despite that cost because FinHub validates form configs ONLY through this schema (it never constructs a FormSpec), so without the enum an unknown jurisdiction would reach FinHub storage unchecked.\",\n      \"enum\": [\n        \"MY\",\n        \"VN\",\n        \"TH\"\n      ]\n    }\n  },\n  \"required\": [\n    \"categories\",\n    \"fields\",\n    \"pages\"\n  ],\n  \"definitions\": {\n    \"category\": {\n      \"type\": \"object\",\n      \"description\": \"A category for grouping related form fields\",\n      \"properties\": {\n        \"id\": {\n          \"type\": \"string\",\n          \"description\": \"Unique identifier for the category (string)\"\n        },\n        \"name\": {\n          \"type\": \"string\",\n          \"description\": \"Display name for the category heading\"\n        }\n      },\n      \"required\": [\n        \"id\",\n        \"name\"\n      ]\n    },\n    \"choice\": {\n      \"type\": \"object\",\n      \"description\": \"A selectable option for dropdown or radiogroup fields\",\n      \"properties\": {\n        \"value\": {\n          \"type\": \"string\",\n          \"description\": \"Value submitted when this choice is selected\"\n        },\n        \"text\": {\n          \"type\": \"string\",\n          \"description\": \"Display text for this choice\"\n        }\n      },\n      \"required\": [\n        \"value\",\n        \"text\"\n      ]\n    },\n    \"validator\": {\n      \"type\": \"object\",\n      \"description\": \"Validation rule for a form field\",\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"regex\",\n            \"email\",\n            \"numeric\",\n            \"text\",\n            \"expression\",\n            \"answercount\",\n            \"custom\"\n          ],\n          \"description\": \"Type of validation to perform\"\n        },\n        \"text\": {\n          \"type\": \"string\",\n          \"description\": \"Error message to display on validation failure\"\n        },\n        \"regex\": {\n          \"type\": \"string\",\n          \"description\": \"Regular expression pattern (for type=regex)\"\n        },\n        \"minValue\": {\n          \"type\": \"number\",\n          \"description\": \"Minimum numeric value (for type=numeric)\"\n        },\n        \"maxValue\": {\n          \"type\": \"number\",\n          \"description\": \"Maximum numeric value (for type=numeric)\"\n        },\n        \"minLength\": {\n          \"type\": \"integer\",\n          \"description\": \"Minimum text length (for type=text)\"\n        },\n        \"maxLength\": {\n          \"type\": \"integer\",\n          \"description\": \"Maximum text length (for type=text)\"\n        },\n        \"minCount\": {\n          \"type\": \"integer\",\n          \"description\": \"Minimum selection count (for type=answercount)\"\n        },\n        \"maxCount\": {\n          \"type\": \"integer\",\n          \"description\": \"Maximum selection count (for type=answercount)\"\n        },\n        \"expression\": {\n          \"type\": \"string\",\n          \"description\": \"SurveyJS expression for custom validation\"\n        },\n        \"validator\": {\n          \"type\": \"string\",\n          \"description\": \"Name of the custom validator function (for type=custom)\"\n        }\n      },\n      \"required\": [\n        \"type\"\n      ]\n    },\n    \"fieldData\": {\n      \"type\": \"object\",\n      \"description\": \"Definition of a form field\",\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\",\n          \"description\": \"Field name (optional in fields{} since it's the key, required in arrays)\"\n        },\n        \"displayName\": {\n          \"type\": \"string\",\n          \"description\": \"Human-readable label for the field\"\n        },\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"text\",\n            \"number\",\n            \"email\",\n            \"file\",\n            \"dropdown\",\n            \"checkbox\",\n            \"boolean\",\n            \"comment\",\n            \"radiogroup\",\n            \"range\",\n            \"html\",\n            \"slider\"\n          ],\n          \"description\": \"Field type determining rendering and behavior\"\n        },\n        \"inputType\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"text\",\n            \"number\",\n            \"tel\",\n            \"date\",\n            \"email\",\n            \"password\",\n            \"url\"\n          ],\n          \"description\": \"HTML input type override for text fields\"\n        },\n        \"category\": {\n          \"type\": \"string\",\n          \"description\": \"Category ID this field belongs to (string to match category.id)\"\n        },\n        \"categoryId\": {\n          \"type\": \"integer\",\n          \"description\": \"Legacy integer category ID (deprecated, prefer 'category')\"\n        },\n        \"maxLength\": {\n          \"type\": [\n            \"integer\",\n            \"string\"\n          ],\n          \"description\": \"Maximum character length\"\n        },\n        \"min\": {\n          \"type\": [\n            \"integer\",\n            \"string\"\n          ],\n          \"description\": \"Minimum value for numeric/slider fields\"\n        },\n        \"max\": {\n          \"type\": [\n            \"integer\",\n            \"string\"\n          ],\n          \"description\": \"Maximum value for numeric/slider fields\"\n        },\n        \"step\": {\n          \"type\": \"number\",\n          \"description\": \"Step increment for slider/range fields\"\n        },\n        \"html\": {\n          \"type\": \"string\",\n          \"description\": \"HTML content for type=html fields\"\n        },\n        \"choices\": {\n          \"type\": \"array\",\n          \"description\": \"Options for dropdown or radiogroup fields\",\n          \"items\": {\n            \"$ref\": \"#/definitions/choice\"\n          }\n        },\n        \"validators\": {\n          \"type\": \"array\",\n          \"description\": \"Validation rules to apply to this field\",\n          \"items\": {\n            \"$ref\": \"#/definitions/validator\"\n          }\n        },\n        \"visible\": {\n          \"type\": \"boolean\",\n          \"default\": true,\n          \"description\": \"Whether the field is visible\"\n        },\n        \"visibleIf\": {\n          \"type\": \"string\",\n          \"description\": \"SurveyJS expression for conditional visibility\"\n        },\n        \"required\": {\n          \"type\": \"boolean\",\n          \"description\": \"Whether the field is required for form submission\"\n        },\n        \"isRequired\": {\n          \"type\": \"boolean\",\n          \"description\": \"Alias for 'required' (SurveyJS compatibility)\"\n        },\n        \"placeholder\": {\n          \"type\": \"string\",\n          \"description\": \"Placeholder text shown in empty field\"\n        },\n        \"defaultValue\": {\n          \"type\": [\n            \"string\",\n            \"number\",\n            \"boolean\",\n            \"array\"\n          ],\n          \"description\": \"Default value for the field\"\n        },\n        \"readOnly\": {\n          \"type\": \"boolean\",\n          \"description\": \"Whether the field is read-only\"\n        },\n        \"startWithNewLine\": {\n          \"type\": \"boolean\",\n          \"default\": true,\n          \"description\": \"If false, field appears on same line as previous field\"\n        },\n        \"enableIf\": {\n          \"type\": \"string\",\n          \"description\": \"SurveyJS expression for conditional enable/disable\"\n        },\n        \"titleLocation\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"default\",\n            \"top\",\n            \"bottom\",\n            \"left\",\n            \"hidden\"\n          ],\n          \"description\": \"Position of the field label\"\n        },\n        \"ihs_column_names\": {\n          \"type\": \"array\",\n          \"description\": \"FinSys IHS column mappings for file fields (used for data extraction)\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"requiredForEvaluation\": {\n          \"type\": \"boolean\",\n          \"default\": true,\n          \"description\": \"Whether this field is required for loan evaluation (FinSys specific)\"\n        }\n      },\n      \"required\": [\n        \"type\"\n      ]\n    },\n    \"fieldReference\": {\n      \"description\": \"Reference to a field in a page, supporting simple refs, refs with overrides, or inline definitions\",\n      \"oneOf\": [\n        {\n          \"type\": \"string\",\n          \"description\": \"Simple field name reference to a field defined in 'fields'\"\n        },\n        {\n          \"type\": \"object\",\n          \"description\": \"Field reference with optional property overrides\",\n          \"properties\": {\n            \"ref\": {\n              \"type\": \"string\",\n              \"description\": \"Reference to field name in 'fields' object\"\n            },\n            \"displayName\": {\n              \"type\": \"string\",\n              \"description\": \"Override display name for this page\"\n            },\n            \"type\": {\n              \"type\": \"string\",\n              \"description\": \"Override field type for this usage\"\n            },\n            \"defaultValue\": {\n              \"type\": [\n                \"string\",\n                \"number\",\n                \"boolean\",\n                \"array\"\n              ]\n            },\n            \"readOnly\": {\n              \"type\": \"boolean\"\n            },\n            \"visible\": {\n              \"type\": \"boolean\"\n            },\n            \"visibleIf\": {\n              \"type\": \"string\"\n            },\n            \"required\": {\n              \"type\": \"boolean\"\n            },\n            \"min\": {\n              \"type\": [\n                \"integer\",\n                \"string\"\n              ]\n            },\n            \"max\": {\n              \"type\": [\n                \"integer\",\n                \"string\"\n              ]\n            },\n            \"choices\": {\n              \"type\": \"array\",\n              \"items\": {\n                \"$ref\": \"#/definitions/choice\"\n              }\n            }\n          },\n          \"required\": [\n            \"ref\"\n          ]\n        },\n        {\n          \"type\": \"object\",\n          \"description\": \"Inline field definition (page-specific field not in master 'fields')\",\n          \"properties\": {\n            \"definition\": {\n              \"allOf\": [\n                {\n                  \"$ref\": \"#/definitions/fieldData\"\n                },\n                {\n                  \"type\": \"object\",\n                  \"properties\": {\n                    \"name\": {\n                      \"type\": \"string\"\n                    }\n                  },\n                  \"required\": [\n                    \"name\"\n                  ]\n                }\n              ]\n            }\n          },\n          \"required\": [\n            \"definition\"\n          ]\n        }\n      ]\n    },\n    \"pageConfig\": {\n      \"type\": \"object\",\n      \"description\": \"Configuration for a single page/step in the form wizard\",\n      \"properties\": {\n        \"id\": {\n          \"type\": \"string\",\n          \"description\": \"Unique page identifier\"\n        },\n        \"title\": {\n          \"type\": \"string\",\n          \"description\": \"Page title displayed to user\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"description\": \"Optional page description or instructions\"\n        },\n        \"showTOC\": {\n          \"type\": \"boolean\",\n          \"default\": false,\n          \"description\": \"Show table of contents\"\n        },\n        \"showProgressBar\": {\n          \"type\": \"boolean\",\n          \"default\": false,\n          \"description\": \"Show progress indicator\"\n        },\n        \"showCategoryHeadings\": {\n          \"type\": \"boolean\",\n          \"default\": false,\n          \"description\": \"Render category names as section headings when category changes between fields\"\n        },\n        \"layout\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"default\",\n            \"grid\",\n            \"vertical\"\n          ],\n          \"description\": \"Layout mode for the page\"\n        },\n        \"fields\": {\n          \"type\": \"array\",\n          \"description\": \"Ordered list of field references to display on this page\",\n          \"items\": {\n            \"$ref\": \"#/definitions/fieldReference\"\n          }\n        }\n      },\n      \"required\": [\n        \"id\",\n        \"fields\"\n      ]\n    }\n  }\n}\n","/*\n * Copyright 2025 Sisters Inspire Sdn Bhd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport class FormFieldCategory {\n  private _id: string;\n  private _name: string;\n\n  constructor(id: string | number, name: string) {\n    this._id = String(id);\n    this._name = name;\n  }\n\n  get id(): string {\n    return this._id;\n  }\n\n  get name(): string {\n    return this._name;\n  }\n\n  set name(value: string) {\n    this._name = value;\n  }\n\n  toJSON() {\n    return {\n      id: this._id,\n      name: this._name,\n    };\n  }\n}\n","/*\n * Copyright 2025 Sisters Inspire Sdn Bhd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { FieldData, Choice, Validator } from \"./survey-generator.js\";\n\nexport enum FieldType {\n  FILE = 'file',\n  TEXT = 'text',\n  DROPDOWN = 'dropdown',\n  BOOLEAN = 'boolean',\n  CHECKBOX = 'checkbox',\n  RADIOGROUP = 'radiogroup',\n  SLIDER = 'slider',\n  HTML = 'html',\n  TAGBOX = 'tagbox',\n  NUMBER = 'number',\n  EMAIL = 'email',\n  COMMENT = 'comment',\n  RANGE = 'range',\n  UNKNOWN = 'unknown',\n}\n\nexport interface FormFieldType {\n  name: string;\n  displayName: string;\n}\n\nexport interface FormFieldInputType {\n  name: string;\n  displayName: string;\n}\n\nexport interface FormFieldTypeDefinitions {\n  version: number;\n  types: FormFieldType[];\n  input_types: FormFieldInputType[];\n}\n\nexport interface DropdownOption {\n  id: number;\n  name: string;\n  displayName: string;\n  choices: Choice[];\n}\n\nexport interface EditorValidator {\n  id: number;\n  displayName: string;\n  class: string;\n  description: string;\n  isRequired: boolean;\n  validators: Validator[];\n}\n\nfunction toFieldType(value: string): FieldType {\n  const typeMap: Record<string, FieldType> = {\n    [FieldType.FILE]: FieldType.FILE,\n    [FieldType.TEXT]: FieldType.TEXT,\n    [FieldType.DROPDOWN]: FieldType.DROPDOWN,\n    [FieldType.BOOLEAN]: FieldType.BOOLEAN,\n    [FieldType.CHECKBOX]: FieldType.CHECKBOX,\n    [FieldType.RADIOGROUP]: FieldType.RADIOGROUP,\n    [FieldType.SLIDER]: FieldType.SLIDER,\n    [FieldType.HTML]: FieldType.HTML,\n    [FieldType.TAGBOX]: FieldType.TAGBOX,\n    [FieldType.NUMBER]: FieldType.NUMBER,\n    [FieldType.EMAIL]: FieldType.EMAIL,\n    [FieldType.COMMENT]: FieldType.COMMENT,\n    [FieldType.RANGE]: FieldType.RANGE,\n  };\n  return typeMap[value] || FieldType.UNKNOWN;\n}\n\nexport default abstract class FormField {\n  fieldObject: FieldData;\n\n  constructor(name: string, displayName: string, type: string, category: string) {\n    this.fieldObject = {\n      name,\n      displayName,\n      type,\n      category,\n    };\n  }\n\n  static fromObject(fieldObject: FieldData): FormField {\n    if (!fieldObject.name) {\n      throw new Error('Field name is required');\n    }\n\n    if (!fieldObject.displayName || !fieldObject.category) {\n      throw new Error(\n        `Invalid field object: '${fieldObject.name}' field missing displayName or category`\n      );\n    }\n\n    const identifiedType = toFieldType(fieldObject.type as string);\n    if (identifiedType === FieldType.UNKNOWN) {\n      throw new Error(\n        `'${fieldObject.name}' field has unsupported or missing type: ${fieldObject.type}`\n      );\n    }\n\n    if (\n      fieldObject.choices &&\n      !['dropdown', 'checkbox', 'radiogroup', 'tagbox'].includes(fieldObject.type as string)\n    ) {\n      // Logic remained as is\n    }\n\n    if (fieldObject.type === 'dropdown' && !fieldObject.choices) {\n      throw new Error(\n        `Invalid field object: '${fieldObject.name}' field has type dropdown, but does not have choices`\n      );\n    }\n\n    let field: FormField;\n    if (fieldObject.type === 'file') {\n      field = new FileFormField(\n        fieldObject.name,\n        fieldObject.displayName || fieldObject.name,\n        fieldObject.type,\n        String(fieldObject.category),\n        fieldObject.ihs_column_names || []\n      );\n    } else {\n      field = new BasicFormField(\n        fieldObject.name,\n        fieldObject.displayName || fieldObject.name,\n        fieldObject.type || 'text',\n        String(fieldObject.category)\n      );\n    }\n\n    field.fieldObject = { ...fieldObject };\n    field.fieldObject.category = String(field.fieldObject.category);\n\n    // Remove legacy categoryId property\n    delete (field.fieldObject as any).categoryId;\n\n    return field;\n  }\n\n  abstract getFieldNames(): string[];\n\n  protected cleanObject(obj: any): any {\n    if (obj === null || obj === undefined) return obj;\n\n    let target = obj;\n    if (typeof obj.toJSON === 'function' && obj !== this) {\n      target = obj.toJSON();\n    }\n\n    if (Array.isArray(target)) {\n      return target.map((v: any) => (typeof v === 'object' ? this.cleanObject(v) : v));\n    }\n\n    if (typeof target !== 'object') return target;\n\n    const cleaned: any = {};\n    Object.keys(target).forEach((key) => {\n      const value = target[key];\n      if (value !== null && value !== undefined && value !== '') {\n        if (typeof value === 'object') {\n          cleaned[key] = this.cleanObject(value);\n        } else {\n          cleaned[key] = value;\n        }\n      }\n    });\n    return cleaned;\n  }\n\n  toJSON() {\n    return this.cleanObject({ ...this.fieldObject });\n  }\n\n  get displayName(): string {\n    return this.fieldObject.displayName || this.fieldObject.name || '';\n  }\n\n  set displayName(newDisplayName: string) {\n    this.fieldObject.displayName = newDisplayName;\n  }\n\n  get name(): string {\n    return this.fieldObject.name || '';\n  }\n\n  get type(): FieldType {\n    return toFieldType(this.fieldObject.type as string);\n  }\n\n  get inputType(): string {\n    return this.fieldObject.inputType ?? '';\n  }\n\n  get categoryId(): string {\n    return String(this.fieldObject.category || '');\n  }\n\n  set categoryId(categoryId: string) {\n    this.fieldObject.category = categoryId;\n  }\n\n  get defaultValue(): any {\n    return this.fieldObject.defaultValue;\n  }\n\n  set defaultValue(value: any) {\n    this.fieldObject.defaultValue = value;\n  }\n\n  get placeholder(): string | undefined {\n    return this.fieldObject.placeholder;\n  }\n\n  get validators(): Validator[] | undefined {\n    return this.fieldObject.validators as Validator[];\n  }\n\n  get choices(): Choice[] {\n    return (this.fieldObject.choices as Choice[]) ?? [];\n  }\n\n  set choices(choices: Choice[]) {\n    this.fieldObject.choices = choices;\n  }\n\n  get visible(): boolean {\n    return this.fieldObject.visible ?? true;\n  }\n\n  get visibleIf(): string | undefined {\n    return this.fieldObject.visibleIf;\n  }\n\n  get isRequired(): boolean {\n    return this.fieldObject.required ?? this.fieldObject.isRequired ?? true;\n  }\n\n  get startWithNewLine(): boolean {\n    return this.fieldObject.startWithNewLine ?? true;\n  }\n\n  get requiredForEvaluation(): boolean {\n    return this.fieldObject.requiredForEvaluation ?? true;\n  }\n\n  get maxLength(): number | undefined {\n    return typeof this.fieldObject.maxLength === 'string'\n      ? Number.parseInt(this.fieldObject.maxLength)\n      : this.fieldObject.maxLength;\n  }\n\n  get min(): number | undefined {\n    return typeof this.fieldObject.min === 'string'\n      ? Number.parseFloat(this.fieldObject.min)\n      : this.fieldObject.min;\n  }\n\n  get max(): number | undefined {\n    return typeof this.fieldObject.max === 'string'\n      ? Number.parseFloat(this.fieldObject.max)\n      : this.fieldObject.max;\n  }\n}\n\nexport class BasicFormField extends FormField {\n  constructor(name: string, displayName: string, type: string, category: string) {\n    super(name, displayName, type, category);\n  }\n\n  getFieldNames(): string[] {\n    if (this.fieldObject.requiredForEvaluation === false) {\n      return [];\n    }\n\n    return [this.fieldObject.name!];\n  }\n}\n\nexport class FileFormField extends FormField {\n  constructor(\n    name: string,\n    displayName: string,\n    type: string,\n    category: string,\n    ihs_column_names: string[]\n  ) {\n    super(name, displayName, type, category);\n    this.fieldObject.ihs_column_names = ihs_column_names;\n  }\n\n  getFieldNames(): string[] {\n    if (this.fieldObject.requiredForEvaluation === false) {\n      return [];\n    }\n\n    return this.fieldObject.ihs_column_names || [];\n  }\n}\n","/*\n * Copyright 2025 Sisters Inspire Sdn Bhd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FormFieldCategory } from \"./form-field-category.js\";\nimport FormField from \"./form-field.js\";\nimport type { FieldData, PageConfig, UnifiedFormConfig } from \"./survey-generator.js\";\nimport { validateFormConfig } from \"./validator.js\";\nimport semver from \"semver\";\nimport { JURISDICTION_CODES, resolveJurisdiction, type Jurisdiction } from \"./jurisdiction.js\";\n\nexport class FormSpec {\n  private _categories: FormFieldCategory[] = [];\n  private _fields: FormField[] = [];\n  private _displayName: string;\n  private _templateIcon?: string;\n  private _schemaVersion: string;\n  private _pages: PageConfig[] = [];\n  /**\n   * SYS-3263: the single jurisdiction this form is valid for.\n   *\n   * SINGLE, not a list, decided by Kain 2026-08-06: a form for jurisdiction X\n   * may be used by many programs in jurisdiction X. Forms are NOT scoped to a\n   * program and do not become so — the rule is that a form's jurisdiction and\n   * its target program's jurisdiction must AGREE.\n   *\n   * Optional, and absent means Malaysia. Every form authored before this\n   * shipped has no declaration, and none is being backfilled — the same\n   * null-means-MY precedent SYS-2872 set for Program and Ihs.\n   *\n   * The accepted cost of a single value: a genuinely jurisdiction-neutral\n   * form — a pure document-upload flow with no country-specific fields — has\n   * no way to say so, and must either pick one jurisdiction or be duplicated.\n   * No such form exists today. Widening a scalar to a list later is additive\n   * and needs no backfill, which is why the cheaper option is the one taken.\n   *\n   * Nothing ENFORCES agreement yet; SYS-3265 does that, and SYS-3264 supplies\n   * the missing half it needs (a submission does not currently record which\n   * form produced it). This field only makes the fact declarable.\n   */\n  private _jurisdiction?: Jurisdiction;\n\n  constructor(\n    displayName: string,\n    categories: FormFieldCategory[],\n    fields: FormField[],\n    pages: PageConfig[] = [],\n    templateIcon?: string,\n    schemaVersion: string = FormSpec.MAX_PARSER_SCHEMA_VERSION,\n    jurisdiction?: Jurisdiction\n  ) {\n    this._displayName = displayName;\n    this._templateIcon = templateIcon;\n    this._categories = categories;\n    this._fields = fields;\n    this._pages = pages;\n    this._schemaVersion = schemaVersion;\n    this._jurisdiction = jurisdiction;\n  }\n\n  static readonly MIN_PARSER_SCHEMA_VERSION = 'v1.0.0';\n  static readonly MAX_PARSER_SCHEMA_VERSION = 'v2.0.0';\n\n  get fieldNames(): string[] {\n    let names: string[] = [];\n\n    this.fields.forEach((field) => {\n      names = names.concat(field.getFieldNames());\n    });\n\n    return names;\n  }\n\n  get schemaVersion(): string {\n    return this._schemaVersion;\n  }\n\n  get requiresUpgrade(): boolean {\n    return semver.lt(this._schemaVersion, FormSpec.MAX_PARSER_SCHEMA_VERSION);\n  }\n\n  upgradeToV2(): void {\n    this._schemaVersion = FormSpec.MAX_PARSER_SCHEMA_VERSION;\n  }\n\n  get displayName(): string {\n    return this._displayName;\n  }\n\n  set displayName(newDisplayName: string) {\n    this._displayName = newDisplayName;\n  }\n\n  /**\n   * The declared jurisdiction, or undefined if the form does not declare one.\n   * Prefer `effectiveJurisdiction` for any decision — a reader that treats\n   * undefined as \"no jurisdiction\" rather than \"Malaysia\" will refuse every\n   * form authored before SYS-3263.\n   */\n  get jurisdiction(): Jurisdiction | undefined {\n    return this._jurisdiction;\n  }\n\n  set jurisdiction(value: Jurisdiction | undefined) {\n    this._jurisdiction = value;\n  }\n\n  /**\n   * The jurisdiction that actually applies: the declaration, or Malaysia when\n   * absent — and NULL when the declaration is present but unrecognized.\n   *\n   * Delegates rather than using `?? DEFAULT_JURISDICTION`. `??` is nullish-only,\n   * so it returned '' for an empty declaration and 'my' for a miscased one —\n   * values outside the Jurisdiction union, handed back typed AS Jurisdiction.\n   * This is the accessor SYS-3265 compares against a program's jurisdiction, so\n   * it was the one place the \"unknown is not the default\" rule failed open.\n   *\n   * Callers must handle null. It means \"this form declares something we do not\n   * recognize\", which is not the same as \"this form is Malaysian\".\n   */\n  get effectiveJurisdiction(): Jurisdiction | null {\n    return resolveJurisdiction(this._jurisdiction);\n  }\n\n  get templateIcon(): string | undefined {\n    return this._templateIcon;\n  }\n\n  set templateIcon(value: string | undefined) {\n    this._templateIcon = value;\n  }\n\n  get categories(): FormFieldCategory[] {\n    return this._categories;\n  }\n\n  set categories(categories: FormFieldCategory[]) {\n    this._categories = categories;\n  }\n\n  get fields(): FormField[] {\n    return this._fields;\n  }\n\n  set fields(fields: FormField[]) {\n    this._fields = fields;\n  }\n\n  get pages(): PageConfig[] {\n    return this._pages;\n  }\n\n  set pages(value: PageConfig[]) {\n    this._pages = value;\n  }\n\n  addField(field: FormField): void {\n    this._fields.push(field);\n  }\n\n  updateField(field: FormField): void {\n    const index = this._fields.findIndex((f) => f.name === field.name);\n    if (index !== -1) {\n      this._fields[index] = field;\n    } else {\n      throw new Error(\n        `${field.name} not found. Form Spec of ${this._displayName} cannot update ${field.name}`\n      );\n    }\n  }\n\n  removeField(fieldName: string): void {\n    const fieldIndex = this._fields.findIndex((f) => f.name === fieldName);\n    if (fieldIndex !== -1) {\n      this._fields.splice(fieldIndex, 1);\n\n      this._pages.forEach((page) => {\n        page.fields = page.fields.filter((fieldRef) => {\n          let refName: string | undefined;\n          if (typeof fieldRef === 'string') {\n            refName = fieldRef;\n          } else if ('ref' in fieldRef) {\n            refName = fieldRef.ref;\n          } else if ('definition' in fieldRef) {\n            refName = fieldRef.definition.name;\n          }\n          return refName !== fieldName;\n        });\n      });\n    }\n  }\n\n  getFieldsByCategory(categoryName: string): FormField[] {\n    const foundCategory = this.categories.find((category) => category.name === categoryName);\n\n    if (!foundCategory) {\n      return [];\n    }\n\n    return this._fields.filter((field) => field.categoryId === foundCategory.id);\n  }\n\n  validate(): { valid: boolean; errors?: any[] } {\n    const config = this.toJSON() as UnifiedFormConfig;\n    const result = validateFormConfig(config);\n    const errors: any[] = [];\n\n    if (result.errors) {\n      result.errors.forEach((err: any) => {\n        let path = err.instancePath || err.dataPath || '';\n        path = path.replace(/^\\//, '').replace(/\\//g, '.');\n        const prefix = path ? `${path}: ` : '';\n        errors.push({\n          message: `${prefix}${err.message}`,\n          path: path,\n        });\n      });\n    }\n\n    // SYS-3263: an unrecognized jurisdiction is an ERROR, not a value that\n    // quietly never matches anything. A typo'd \"VM\" would otherwise sit in\n    // the spec looking declared while failing every compatibility check\n    // SYS-3265 makes — and failing them for a reason nobody could see.\n    // Absent is fine and means Malaysia; only a PRESENT-but-unknown value\n    // is refused.\n    // One predicate, shared with effectiveJurisdiction and resolveJurisdiction,\n    // because three implementations of \"is this absent?\" disagreed on null and\n    // ''. null is what a JSONB column and a React \"not set\" actually write, and\n    // it is the shape SYS-2872's own precedent is written in.\n    if (resolveJurisdiction(this._jurisdiction ?? undefined) === null) {\n      errors.push({\n        message: `jurisdiction: unknown jurisdiction '${String(this._jurisdiction)}' — expected one of ${JURISDICTION_CODES.join(', ')}, or omit it to declare Malaysia`,\n        path: 'jurisdiction',\n      });\n    }\n\n    if (!this._displayName || this._displayName.trim() === '') {\n      errors.push({\n        message: 'displayName: Form display name is required',\n        path: 'displayName',\n      });\n    }\n\n    const categoryIds = new Set(this._categories.map((c) => String(c.id)));\n    this._fields.forEach((field) => {\n      if (field.categoryId && !categoryIds.has(String(field.categoryId))) {\n        errors.push({\n          message: `fields.${field.name}.category: references non-existent category '${field.categoryId}'`,\n          path: `fields.${field.name}.category`,\n        });\n      }\n    });\n\n    const fieldNames = new Set(this._fields.map((f) => f.name));\n    this._pages.forEach((page, pageIndex) => {\n      page.fields.forEach((fieldRef, fieldIndex) => {\n        let refName: string | undefined;\n        if (typeof fieldRef === 'string') {\n          refName = fieldRef;\n        } else if (fieldRef && (fieldRef as any).ref) {\n          refName = (fieldRef as any).ref;\n        } else if (fieldRef && (fieldRef as any).definition) {\n          refName = (fieldRef as any).definition.name;\n        }\n\n        if (refName && !fieldNames.has(refName)) {\n          errors.push({\n            message: `pages.${pageIndex}.fields.${fieldIndex}: references non-existent field '${refName}'`,\n            path: `pages.${pageIndex}.fields.${fieldIndex}`,\n          });\n        }\n      });\n    });\n\n    return {\n      valid: result.valid && errors.length === (result.errors?.length || 0),\n      errors: errors.length > 0 ? errors : undefined,\n    };\n  }\n\n  private cleanObject(obj: any): any {\n    if (obj === null || obj === undefined) return obj;\n\n    let target = obj;\n    if (typeof obj.toJSON === 'function' && obj !== this) {\n      target = obj.toJSON();\n    }\n\n    if (Array.isArray(target)) {\n      return target.map((v: any) => (typeof v === 'object' ? this.cleanObject(v) : v));\n    }\n\n    if (typeof target !== 'object') return target;\n\n    const cleaned: any = {};\n    Object.keys(target).forEach((key) => {\n      const value = target[key];\n      if (value !== null && value !== undefined && value !== '') {\n        if (typeof value === 'object') {\n          cleaned[key] = this.cleanObject(value);\n        } else {\n          cleaned[key] = value;\n        }\n      }\n    });\n    return cleaned;\n  }\n\n  toJSON(): object {\n    const fieldsMap: Record<string, any> = {};\n    this._fields.forEach((field) => {\n      fieldsMap[field.name] = field.toJSON();\n      delete fieldsMap[field.name].name;\n    });\n\n    return this.cleanObject({\n      $schema:\n        '../../../node_modules/@finsys/core/dist/schema/unified-form.schema.json',\n      schemaVersion: this._schemaVersion,\n      displayName: this._displayName,\n      templateIcon: this._templateIcon,\n      jurisdiction: this._jurisdiction,\n      categories: this._categories,\n      fields: fieldsMap,\n      pages: this._pages,\n    });\n  }\n\n  static fromJSON(jsonString: string): FormSpec {\n    let jsonData: any;\n    try {\n      jsonData = JSON.parse(jsonString);\n    } catch (error) {\n      console.error(`Error parsing JSON for Loantype with string: ${jsonString}`);\n      throw error;\n    }\n\n    if (!jsonData.schemaVersion) {\n      throw new Error('Invalid JSON: schemaVersion is missing or invalid');\n    }\n\n    if (semver.lt(jsonData.schemaVersion, FormSpec.MIN_PARSER_SCHEMA_VERSION)) {\n      throw new Error(\n        `This form spec file is using an outdated schema version ${jsonData.schemaVersion}. Minimum supported version is ${FormSpec.MIN_PARSER_SCHEMA_VERSION}`\n      );\n    }\n\n    if (!jsonData.displayName) {\n      throw new Error('Invalid JSON: displayName is missing or invalid');\n    }\n\n    if (!jsonData.categories) {\n      throw new Error('Invalid JSON: categories is missing or invalid');\n    }\n\n    if (!jsonData.fields) {\n      throw new Error('Invalid JSON: fields is missing or invalid');\n    }\n\n    if (!jsonData.pages || jsonData.pages.length === 0) {\n      if (semver.satisfies(jsonData.schemaVersion, '>=2.0.0')) {\n        console.warn(\n          `v2.0.0 template ${jsonData.displayName} is missing pages. Generating default pages.`\n        );\n      }\n    }\n\n    let fieldObjects: FieldData[] = [];\n    if (Array.isArray(jsonData.fields)) {\n      fieldObjects = jsonData.fields;\n    } else if (typeof jsonData.fields === 'object' && jsonData.fields !== null) {\n      fieldObjects = Object.entries(jsonData.fields).map(([name, data]: [string, any]) => {\n        return {\n          name,\n          ...data,\n        };\n      });\n    }\n\n    fieldObjects.forEach((f: any) => {\n      if (f.categoryId && !f.category) {\n        f.category = String(f.categoryId);\n      } else if (f.category) {\n        f.category = String(f.category);\n      }\n    });\n\n    const categories = (jsonData.categories || []).map((cat: any) => {\n      return new FormFieldCategory(String(cat.id), cat.name);\n    });\n\n    const fields: FormField[] = fieldObjects.map((fieldObject) => {\n      return FormField.fromObject(fieldObject);\n    });\n\n    let pages = jsonData.pages || [];\n    if (pages.length === 0) {\n      const categoriesMap: Record<string, string[]> = {};\n      fields.forEach((f) => {\n        const catId = f.categoryId;\n        if (!categoriesMap[catId]) {\n          categoriesMap[catId] = [];\n        }\n        categoriesMap[catId].push(f.name);\n      });\n\n      pages = categories\n        .map((cat: FormFieldCategory) => ({\n          id: `page-${cat.id}`,\n          title: cat.name,\n          fields: categoriesMap[cat.id] || [],\n        }))\n        .filter((p: PageConfig) => p.fields.length > 0);\n    }\n\n    return new FormSpec(\n      jsonData.displayName,\n      categories,\n      fields,\n      pages,\n      jsonData.templateIcon,\n      jsonData.schemaVersion,\n      jsonData.jurisdiction\n    );\n  }\n}\n","/*\n * Copyright 2025 Sisters Inspire Sdn Bhd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * SYS-3263: the jurisdiction registry, in the package that every app shares.\n *\n * WHY IT LIVES HERE AND NOT IN finsys-api\n *\n * finsys-api has carried `JURISDICTION` since SYS-2872, and that is where it\n * was needed first — extraction routing and spec dispatch. But finsys-api\n * predates this package: @finsys/core came later, to bridge contracts across\n * the apps that sit on it. A jurisdiction is now something a FORM declares\n * (below), something a PROGRAM declares, and something FinHub and\n * finsys-client both have to render. That makes it a shared contract, and a\n * shared contract stranded in one consumer is how two copies start.\n *\n * The definitive corrective example is one repo over: `IhsFieldProvenance` is\n * declared BOTH here and in finsys-api, with nothing detecting drift between\n * them. This registry is deliberately not going the same way.\n *\n * SO: finsys-api's copy must import from here rather than keep its own. That\n * de-duplication is SYS-3258's, not this ticket's — but it is the reason this\n * file exists here rather than being copied. Until it lands the two sets\n * agree by inspection, which is exactly the fragile state that ends the\n * moment somebody adds Thailand to one of them.\n *\n * A jurisdiction is a Program-level FIXED property: it determines which\n * document types exist, which extraction specs apply, and which regulations\n * govern. It is a different axis from document language (per-file, chooses an\n * extraction endpoint) and from display language (per-user i18n).\n */\nexport const JURISDICTION = {\n  MALAYSIA: 'MY',\n  VIETNAM: 'VN',\n  THAILAND: 'TH',\n} as const\n\nexport type Jurisdiction = (typeof JURISDICTION)[keyof typeof JURISDICTION]\n\n/**\n * The platform was Malaysia-only before SYS-2872, so an absent jurisdiction\n * always means Malaysia — on a program, on an IHS row, and now on a form\n * spec. Readers must treat absence as MY rather than expecting a backfill:\n * every form authored before this shipped has no declaration and none will\n * be added retroactively.\n */\nexport const DEFAULT_JURISDICTION: Jurisdiction = JURISDICTION.MALAYSIA\n\n/** Every declarable jurisdiction code, for validation and iteration. */\nexport const JURISDICTION_CODES: ReadonlyArray<Jurisdiction> = Object.freeze(\n  Object.values(JURISDICTION) as Jurisdiction[]\n)\n\n/**\n * Narrows an arbitrary value to a declarable jurisdiction code.\n *\n * Deliberately strict about case: \"my\" is not accepted as Malaysia. A form\n * spec is authored data, and silently normalising it would let two spellings\n * of the same jurisdiction coexist — which reads as agreement until something\n * compares them literally.\n */\nexport function isJurisdiction(value: unknown): value is Jurisdiction {\n  return typeof value === 'string' && (JURISDICTION_CODES as readonly string[]).includes(value)\n}\n\n/**\n * Resolves a possibly-absent declaration to the jurisdiction that actually\n * applies. Absent means Malaysia; a present-but-unknown value is NOT silently\n * defaulted — callers that accept unvalidated input should reject it instead,\n * because defaulting an unrecognized jurisdiction to MY would route a foreign\n * form into Malaysian handling, which is the failure this whole axis exists\n * to prevent.\n */\nexport function resolveJurisdiction(value: string | null | undefined): Jurisdiction | null {\n  // ABSENT is null/undefined only. An EMPTY STRING is deliberately NOT absent.\n  //\n  // finsys-api treats '' as unresolvable and fails closed — financialStatementSpecFor\n  // throws a ValidationError, and extractionApiService refuses the route. If this\n  // helper returned Malaysia for '', then SYS-3258 swapping finsys-api onto it would\n  // silently turn \"refuse extraction\" into \"extract as Malaysian\", which is a change\n  // in failure mode disguised as a de-duplication. Program.jurisdiction is a plain\n  // varchar(8), so '' is reachable.\n  if (value === null || value === undefined) return DEFAULT_JURISDICTION\n  return isJurisdiction(value) ? value : null\n}\n\n/**\n * SYS-3266: why a form and a program are not compatible.\n *\n * An enum rather than a string union — the set will grow (a form declaring a\n * jurisdiction the deployment has retired is the obvious next member), and a\n * consumer switching on it should get an exhaustiveness error rather than a\n * silently-unhandled string.\n */\nexport enum IncompatibilityReason {\n  /** Both resolved, and they are different jurisdictions. */\n  Mismatch = 'mismatch',\n  /** The FORM declares something that is not a jurisdiction we recognize. */\n  UnresolvableForm = 'unresolvable_form',\n  /** The PROGRAM declares something that is not a jurisdiction we recognize. */\n  UnresolvableProgram = 'unresolvable_program',\n}\n\n/**\n * The outcome of comparing a form's jurisdiction with a program's.\n *\n * Deliberately not a boolean. Every caller that refuses a pairing has to tell\n * somebody WHICH pairing and WHY — \"this form is declared MY, that program is\n * VN\" — and a bare boolean makes each of them re-derive that from inputs they\n * then have to keep in scope. Returning the resolved values means the message\n * is built from what the decision was actually made on, not from a caller's\n * second look at the same data.\n */\nexport type JurisdictionCompatibility =\n  | { readonly compatible: true; readonly jurisdiction: Jurisdiction }\n  | {\n      readonly compatible: false\n      readonly reason: IncompatibilityReason\n      /** Resolved where possible; the raw declaration where it could not be. */\n      readonly form: Jurisdiction | string | null | undefined\n      readonly program: Jurisdiction | string | null | undefined\n    }\n\n/**\n * SYS-3266: is this form usable to submit to this program?\n *\n * THE ONE PREDICATE. Kain's rule is symmetric, so this is called from three\n * places rather than reimplemented in each: filtering forms for a chosen\n * program, filtering programs for a chosen form, and refusing a mismatch at\n * submit. The first two are the reason nobody reaches the third.\n *\n * Consumed by FinHub (the manager tier, SYS-3265) and @finsys/borrower-client\n * (the SDK tier, SYS-3269). Raw HTTP callers are unguarded by design.\n *\n * ABSENCE resolves to Malaysia on both sides, via `resolveJurisdiction`, so\n * there is ONE definition of \"absent\" rather than a fourth — SYS-3263's review\n * found three implementations of that question disagreeing on null and ''.\n * Note that an empty string is NOT absent: finsys-api fails closed on it, and\n * a form or program carrying '' is unresolvable, not Malaysian.\n *\n * AN UNRECOGNIZED VALUE IS COMPATIBLE WITH NOTHING — including an identical\n * unrecognized value on the other side. Two forms both declaring \"VM\" are not\n * evidence of agreement, they are evidence of the same typo twice, and\n * treating them as a match would let a pair of mistakes authorise each other.\n */\nexport function checkJurisdictionCompatibility(\n  formJurisdiction: string | null | undefined,\n  programJurisdiction: string | null | undefined\n): JurisdictionCompatibility {\n  const form = resolveJurisdiction(formJurisdiction)\n  const program = resolveJurisdiction(programJurisdiction)\n\n  if (form === null) {\n    return {\n      compatible: false,\n      reason: IncompatibilityReason.UnresolvableForm,\n      form: formJurisdiction,\n      program: program ?? programJurisdiction,\n    }\n  }\n  if (program === null) {\n    return {\n      compatible: false,\n      reason: IncompatibilityReason.UnresolvableProgram,\n      form,\n      program: programJurisdiction,\n    }\n  }\n  if (form !== program) {\n    return { compatible: false, reason: IncompatibilityReason.Mismatch, form, program }\n  }\n  return { compatible: true, jurisdiction: form }\n}\n\n/**\n * A message a consumer can show without re-deriving the decision.\n *\n * Kept beside the predicate so every tier phrases a refusal identically —\n * FinHub, the SDK and any future caller. A user hitting the same wall in two\n * products should not have to work out that it is the same wall.\n */\nexport function describeIncompatibility(result: JurisdictionCompatibility): string | null {\n  if (result.compatible) return null\n  const shown = (v: unknown) =>\n    v === null || v === undefined || v === '' ? '(not set)' : `'${String(v)}'`\n  switch (result.reason) {\n    case IncompatibilityReason.Mismatch:\n      return `This form is for ${shown(result.form)} but the selected program is ${shown(result.program)}.`\n    case IncompatibilityReason.UnresolvableForm:\n      return `This form declares ${shown(result.form)}, which is not a jurisdiction this deployment recognizes.`\n    case IncompatibilityReason.UnresolvableProgram:\n      return `The selected program declares ${shown(result.program)}, which is not a jurisdiction this deployment recognizes.`\n  }\n}\n\n/**\n * SYS-3284/SYS-3285: the currency a jurisdiction's amounts are DISPLAYED in\n * when the value itself does not say.\n *\n * READ THIS BEFORE USING IT — it is narrower than it looks.\n *\n * SYS-3249 established that a currency belongs to the OBSERVATION, not to a\n * field, a table or a country: one document can legitimately report several\n * currencies, so nothing may stamp a currency across a record. That still\n * holds and this does not weaken it.\n *\n * What this map is: a DISPLAY DEFAULT for the case where a value carries no\n * recorded currency of its own. Today that is every value, because\n * `IhsFieldProvenance.currency` has no producer yet — so FinHub and\n * finsys-client were left choosing between printing a hardcoded \"RM\" (wrong\n * outside Malaysia) and printing a bare number (ambiguous everywhere). This\n * gives them a third option that is right in the common case and overridable\n * in the uncommon one.\n *\n * What it is NOT: a fact about the record. It must never be written to a\n * row, returned from an API as the record's currency, or used to decide\n * anything but rendering. The moment a value carries its own currency, that\n * wins — see `resolveDisplayCurrency`.\n *\n * A jurisdiction whose amounts are commonly reported in a currency other than\n * its own is exactly why the override exists rather than why this map should\n * grow conditionals.\n */\nexport const JURISDICTION_DISPLAY_CURRENCY: Readonly<Record<Jurisdiction, string>> = Object.freeze({\n  [JURISDICTION.MALAYSIA]: 'MYR',\n  [JURISDICTION.VIETNAM]: 'VND',\n  [JURISDICTION.THAILAND]: 'THB',\n})\n\n/**\n * Whether a jurisdiction's national identity number ENCODES THE HOLDER'S BIRTH\n * DATE in a position software can read.\n *\n * This exists because a Malaysia-specific parsing rule was running on every\n * application regardless of jurisdiction: the first six digits of an NRIC are\n * the birth date as YYMMDD, and that is true of no other national id we\n * accept. Measured against real id shapes (SYS-3257):\n *\n *   MY NRIC   900115085432   -> 1990-01-15     correct\n *   VN CCCD   001201123456   -> 2000-12-01     plausible and WRONG\n *   TH natID  1103701234567  -> \"Invalid date\"\n *   TH natID  5501200098765  -> 2055-01-20     a birth date thirty years hence\n *\n * A Vietnamese CCCD leads with a province code, a gender/century digit and a\n * two-digit birth YEAR — not a date. A Thai national id encodes no birth date\n * anywhere: digit 1 is person type, 2–5 province and district, the rest\n * sequence and a check digit. So the failure was silent in both directions —\n * sometimes an unparseable string written to a date column, sometimes a\n * believable date that is simply false.\n *\n * A registry entry rather than an equality check at the call site, so a fourth\n * jurisdiction is a line here instead of an edit to whatever function happens\n * to parse ids that week.\n */\nexport const JURISDICTION_NATIONAL_ID_ENCODES_BIRTH_DATE: Readonly<Record<Jurisdiction, boolean>> =\n  Object.freeze({\n    [JURISDICTION.MALAYSIA]: true,\n    [JURISDICTION.VIETNAM]: false,\n    [JURISDICTION.THAILAND]: false,\n  })\n\n/**\n * Whether a birth date may be derived from a national id under this\n * jurisdiction.\n *\n * ABSENCE RESOLVES TO MALAYSIA, deliberately, via `resolveJurisdiction` — the\n * same platform rule the rest of this module follows. That is load-bearing\n * here rather than merely consistent: rows created without a resolved program\n * carry `jurisdiction = null`, and every one of them is Malaysian. A literal\n * `=== 'MY'` check at the call site would silently stop deriving for all of\n * them, turning a fix for Vietnam into a regression for Malaysia.\n *\n * An UNRESOLVABLE jurisdiction returns false. Deriving on a code we do not\n * recognise is exactly the guess this replaces.\n */\nexport function nationalIdEncodesBirthDate(jurisdiction: string | null | undefined): boolean {\n  const resolved = resolveJurisdiction(jurisdiction)\n  if (resolved === null) return false\n  return JURISDICTION_NATIONAL_ID_ENCODES_BIRTH_DATE[resolved]\n}\n\n/**\n * The currency to render a value in: the value's own if it has one, otherwise\n * the jurisdiction's display default, otherwise nothing.\n *\n * Returning `undefined` is a real answer and callers must handle it — it means\n * \"no basis to name a currency\", and printing a bare number is then correct.\n * Substituting a guess here is how a Vietnamese figure ends up labelled MYR,\n * which is the bug this exists to fix.\n *\n * @param valueCurrency ISO 4217 recorded on the observation, when one exists.\n * @param jurisdiction  the record's jurisdiction; absence resolves to Malaysia\n *                      the same way it does everywhere else on this axis.\n */\n/**\n * What a caller passes as `jurisdiction` when it has NO BASIS to name one.\n *\n * There are two different \"I don't have a jurisdiction\", and collapsing them\n * is a real bug:\n *\n *   - A RECORD whose jurisdiction column is null. The platform rule says\n *     Malaysia, and that rule is right — the column predates jurisdictions\n *     and every such row is Malaysian. Pass `null`.\n *\n *   - A CALL SITE with no record at all: a form with no program selected, a\n *     total spanning several countries, a page that simply was not given one.\n *     Malaysia is not a default here, it is a fabrication. Pass this.\n *\n * Both consumers of the 5.4.0 money helpers invented this concept privately\n * before it existed — one made the parameter required with a warning comment,\n * the other defined its own empty-string sentinel — which is what naming it\n * here is a response to. Two independent workarounds for one missing idea.\n *\n * It is the empty string because `resolveJurisdiction('')` already fails\n * closed; this gives that behavior a name and a contract instead of leaving\n * it an implementation detail two repos happened to discover.\n */\nexport const NO_JURISDICTION_BASIS = ''\n\nexport function resolveDisplayCurrency(\n  valueCurrency: string | null | undefined,\n  jurisdiction: string | null | undefined\n): string | undefined {\n  const own = valueCurrency?.trim().toUpperCase()\n  if (own) return own\n\n  const resolved = resolveJurisdiction(jurisdiction)\n  // An unresolvable jurisdiction gets NO currency rather than Malaysia's.\n  // Defaulting it would be the same class of error as the hardcoded 'MYR'\n  // this replaces, just harder to see.\n  if (resolved === null) return undefined\n  return JURISDICTION_DISPLAY_CURRENCY[resolved]\n}\n","/*\n * Copyright 2025 Sisters Inspire Sdn Bhd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { Validator } from \"./survey-generator.js\";\nimport type { EditorValidator } from \"./form-field.js\";\n\nexport interface FormValidatorDefinitions {\n  options: EditorValidator[];\n  version: number;\n}\n\nexport class FormFieldValidator implements EditorValidator {\n  id: number;\n  displayName: string;\n  class: string;\n  description: string;\n  isRequired: boolean;\n  validators: Validator[];\n\n  constructor(validatorData: EditorValidator) {\n    this.id = validatorData.id;\n    this.displayName = validatorData.displayName;\n    this.class = validatorData.class;\n    this.description = validatorData.description;\n    this.isRequired = validatorData.isRequired;\n    this.validators = validatorData.validators;\n  }\n\n  validate(value: any): boolean {\n    for (const validator of this.validators) {\n      switch (validator.type) {\n        case 'numeric':\n          if (!this.validateNumeric(value, validator.minValue, validator.maxValue)) {\n            return false;\n          }\n          break;\n        case 'text':\n          if (!this.validateText(value, validator.minLength, validator.maxLength)) {\n            return false;\n          }\n          break;\n      }\n    }\n    return true;\n  }\n\n  private validateNumeric(value: number, min?: number, max?: number): boolean {\n    if (min !== undefined && value < min) return false;\n    if (max !== undefined && value > max) return false;\n    return true;\n  }\n\n  private validateText(value: string, minLength?: number, maxLength?: number): boolean {\n    if (minLength !== undefined && value.length < minLength) return false;\n    if (maxLength !== undefined && value.length > maxLength) return false;\n    return true;\n  }\n}\n","{\n  \"schemaVersion\": \"v2.0.0\",\n  \"categories\": [\n    {\n      \"id\": \"1\",\n      \"name\": \"Basic Information\"\n    },\n    {\n      \"id\": \"2\",\n      \"name\": \"Personal Information\"\n    },\n    {\n      \"id\": \"3\",\n      \"name\": \"Company Information\"\n    },\n    {\n      \"id\": \"4\",\n      \"name\": \"Financial Information\"\n    },\n    {\n      \"id\": \"5\",\n      \"name\": \"Employment Information\"\n    },\n    {\n      \"id\": \"6\",\n      \"name\": \"Consent and Legal Agreements\"\n    },\n    {\n      \"id\": \"7\",\n      \"name\": \"Address Information\"\n    },\n    {\n      \"id\": \"8\",\n      \"name\": \"Contact Information\"\n    },\n    {\n      \"id\": \"9\",\n      \"name\": \"Declarations\"\n    },\n    {\n      \"id\": \"10\",\n      \"name\": \"Account Information\"\n    },\n    {\n      \"id\": \"11\",\n      \"name\": \"Loan Information\"\n    },\n    {\n      \"id\": \"12\",\n      \"name\": \"Vehicle Information\"\n    },\n    {\n      \"id\": \"13\",\n      \"name\": \"Document Upload\"\n    }\n  ],\n  \"fields\": [\n    {\n      \"name\": \"fullName\",\n      \"displayName\": \"Full Name\",\n      \"placeholder\": \"E.g. John Doe\",\n      \"type\": \"text\",\n      \"maxLength\": 80,\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"text\": \"Please make sure the name doesn't include extra spaces, numbers, or invalid symbols\",\n          \"regex\": \"^[A-Za-z'-]+(?:\\\\s[A-Za-z'-]+)*\\\\s?[A-Za-z'-]+$\"\n        }\n      ],\n      \"category\": \"1\"\n    },\n    {\n      \"name\": \"email\",\n      \"displayName\": \"Email\",\n      \"placeholder\": \"E.g. johndoe@example.com\",\n      \"type\": \"text\",\n      \"inputType\": \"email\",\n      \"maxLength\": 65,\n      \"validators\": [\n        {\n          \"type\": \"email\",\n          \"text\": \"Value must be a valid email\"\n        }\n      ],\n      \"category\": \"1\"\n    },\n    {\n      \"name\": \"mobilePhoneNoAreaCode\",\n      \"displayName\": \"Mobile Phone Number Area Code\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"1\"\n    },\n    {\n      \"name\": \"mobilePhoneNo\",\n      \"displayName\": \"Mobile Phone Number\",\n      \"placeholder\": \"Mobile Phone Number\",\n      \"type\": \"text\",\n      \"inputType\": \"tel\",\n      \"maxLength\": 12,\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"text\": \"A valid Malaysia phone number is required.\",\n          \"regex\": \"^(011[0-9]{8}|01[2346789][0-9]{7}|[2-9][0-9]{0,8})$\"\n        }\n      ],\n      \"category\": \"1\"\n    },\n    {\n      \"type\": \"text\",\n      \"name\": \"idNumber\",\n      \"title\": \"ID Number\",\n      \"placeholder\": \"E.g. 700513065143\",\n      \"isRequired\": true,\n      \"displayName\": \"IC Number\",\n      \"maxLength\": 25,\n      \"inputType\": \"text\",\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"regex\": \"^\\\\d{12}$\",\n          \"text\": \"Please enter exactly 12 digits numbers\"\n        },\n        {\n          \"type\": \"regex\",\n          \"regex\": \"^(\\\\d{2})(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])\\\\d{6}$\",\n          \"text\": \"First 6 digits must be valid birth year (00-99), month (01-12), and day (01-31)\"\n        }\n      ],\n      \"category\": \"2\"\n    },\n    {\n      \"name\": \"dateOfBirth\",\n      \"displayName\": \"Date of Birth\",\n      \"type\": \"text\",\n      \"inputType\": \"date\",\n      \"visible\": false,\n      \"category\": \"2\"\n    },\n    {\n      \"name\": \"companyName\",\n      \"displayName\": \"Company Name\",\n      \"type\": \"text\",\n      \"category\": \"3\"\n    },\n    {\n      \"name\": \"companyRegNo\",\n      \"displayName\": \"Company Registration Number\",\n      \"type\": \"text\",\n      \"category\": \"3\"\n    },\n    {\n      \"name\": \"natureOfBusiness\",\n      \"displayName\": \"Nature of Business\",\n      \"placeholder\": \"Select your Nature of Business\",\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"Manufacturing\",\n          \"text\": \"Manufacturing\"\n        },\n        {\n          \"value\": \"Services\",\n          \"text\": \"Services\"\n        },\n        {\n          \"value\": \"Others\",\n          \"text\": \"Others\"\n        }\n      ],\n      \"maxLength\": 80,\n      \"category\": \"3\"\n    },\n    {\n      \"name\": \"officeFacilityType\",\n      \"displayName\": \"Office Facility Type\",\n      \"placeholder\": \"Select your facility type\",\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"Owned\",\n          \"text\": \"Owned\"\n        },\n        {\n          \"value\": \"Rented\",\n          \"text\": \"Rented\"\n        }\n      ],\n      \"maxLength\": 80,\n      \"category\": \"3\"\n    },\n    {\n      \"name\": \"companySize\",\n      \"displayName\": \"Company Size\",\n      \"placeholder\": \"Select your company size\",\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"selfEmplyed\",\n          \"text\": \"Self-employed\"\n        },\n        {\n          \"value\": \"1-10\",\n          \"text\": \"1-10\"\n        },\n        {\n          \"value\": \"11-20\",\n          \"text\": \"11-20\"\n        },\n        {\n          \"value\": \"21-30\",\n          \"text\": \"21-30\"\n        },\n        {\n          \"value\": \"31-50\",\n          \"text\": \"31-50\"\n        },\n        {\n          \"value\": \"51-100\",\n          \"text\": \"51-100\"\n        },\n        {\n          \"value\": \"101-500\",\n          \"text\": \"101-500\"\n        },\n        {\n          \"value\": \"500+\",\n          \"text\": \"500+\"\n        }\n      ],\n      \"category\": \"3\"\n    },\n    {\n      \"name\": \"facilityAddress\",\n      \"displayName\": \"Facility Address\",\n      \"type\": \"text\",\n      \"category\": \"3\"\n    },\n    {\n      \"name\": \"companyEntityType\",\n      \"displayName\": \"Company Entity Type\",\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"Branch office\",\n          \"text\": \"Branch office\"\n        },\n        {\n          \"value\": \"Company Limited by guarantee\",\n          \"text\": \"Company Limited by guarantee\"\n        },\n        {\n          \"value\": \"Enterprise or Sole Proprietorship\",\n          \"text\": \"Enterprise or Sole Proprietorship\"\n        },\n        {\n          \"value\": \"Foreign Companies\",\n          \"text\": \"Foreign Companies\"\n        },\n        {\n          \"value\": \"Limited Liability Partnership\",\n          \"text\": \"Limited Liability Partnership\"\n        },\n        {\n          \"value\": \"Partnership\",\n          \"text\": \"Partnership\"\n        },\n        {\n          \"value\": \"Private Limited Company (Sdn. Bhd.)\",\n          \"text\": \"Private Limited Company (Sdn. Bhd.)\"\n        },\n        {\n          \"value\": \"Public Limited Company (Bhd.)\",\n          \"text\": \"Public Limited Company (Bhd.)\"\n        },\n        {\n          \"value\": \"Proprietorship/ Partnership\",\n          \"text\": \"Proprietorship/ Partnership\"\n        }\n      ],\n      \"category\": \"3\"\n    },\n    {\n      \"name\": \"tnbTariff\",\n      \"displayName\": \"TNB Tariff\",\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"B\",\n          \"text\": \"B\"\n        },\n        {\n          \"value\": \"C1\",\n          \"text\": \"C1\"\n        },\n        {\n          \"value\": \"C2\",\n          \"text\": \"C2\"\n        },\n        {\n          \"value\": \"D\",\n          \"text\": \"D\"\n        },\n        {\n          \"value\": \"E1\",\n          \"text\": \"E1\"\n        },\n        {\n          \"value\": \"E2\",\n          \"text\": \"E2\"\n        },\n        {\n          \"value\": \"E3\",\n          \"text\": \"E3\"\n        },\n        {\n          \"value\": \"H\",\n          \"text\": \"H\"\n        },\n        {\n          \"value\": \"H1\",\n          \"text\": \"H1\"\n        },\n        {\n          \"value\": \"H2\",\n          \"text\": \"H2\"\n        }\n      ],\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"avgMaximumDemand\",\n      \"displayName\": \"Average Maximum Demand\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"ctRatio\",\n      \"displayName\": \"CT Ratio\",\n      \"type\": \"text\",\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"buildingType\",\n      \"displayName\": \"Building Type\",\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"Warehouse/Factory\",\n          \"text\": \"Warehouse/Factory\"\n        },\n        {\n          \"value\": \"Office building/Shoplot\",\n          \"text\": \"Office building/Shoplot\"\n        },\n        {\n          \"value\": \"Shopping Mall/Complex\",\n          \"text\": \"Shopping Mall/Complex\"\n        },\n        {\n          \"value\": \"School\",\n          \"text\": \"School\"\n        },\n        {\n          \"value\": \"Other\",\n          \"text\": \"Other\"\n        }\n      ],\n      \"category\": \"3\"\n    },\n    {\n      \"name\": \"tnbBills\",\n      \"displayName\": \"TNB Bills\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"2\"\n    },\n    {\n      \"name\": \"financingSelection\",\n      \"displayName\": \"Financing Selection\",\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"Loan\",\n          \"text\": \"Loan\"\n        },\n        {\n          \"value\": \"Leasing\",\n          \"text\": \"Leasing\"\n        },\n        {\n          \"value\": \"Extended Terms\",\n          \"text\": \"Extended Terms\"\n        }\n      ],\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"businessSector\",\n      \"displayName\": \"Business Sector\",\n      \"type\": \"text\",\n      \"category\": \"5\"\n    },\n    {\n      \"name\": \"companyBackground\",\n      \"displayName\": \"Company Background\",\n      \"type\": \"text\",\n      \"category\": \"3\"\n    },\n    {\n      \"name\": \"isApplication\",\n      \"displayName\": \"Is Application\",\n      \"type\": \"boolean\",\n      \"category\": \"6\"\n    },\n    {\n      \"name\": \"isReview\",\n      \"displayName\": \"Is Review\",\n      \"type\": \"boolean\",\n      \"category\": \"6\"\n    },\n    {\n      \"name\": \"addressLine1\",\n      \"displayName\": \"Address Line 1\",\n      \"type\": \"text\",\n      \"category\": \"7\"\n    },\n    {\n      \"name\": \"addressLine2\",\n      \"displayName\": \"Address Line 2\",\n      \"type\": \"text\",\n      \"category\": \"7\"\n    },\n    {\n      \"name\": \"addressLine3\",\n      \"displayName\": \"Address Line 3\",\n      \"type\": \"text\",\n      \"category\": \"7\"\n    },\n    {\n      \"name\": \"addressType\",\n      \"displayName\": \"Address Type\",\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"P\",\n          \"text\": \"Permanent\"\n        },\n        {\n          \"value\": \"O\",\n          \"text\": \"Office\"\n        },\n        {\n          \"value\": \"R\",\n          \"text\": \"Residence\"\n        }\n      ],\n      \"category\": \"7\"\n    },\n    {\n      \"name\": \"city\",\n      \"displayName\": \"City\",\n      \"type\": \"text\",\n      \"category\": \"7\"\n    },\n    {\n      \"name\": \"country\",\n      \"displayName\": \"Country\",\n      \"type\": \"dropdown\",\n      \"titleLocation\": \"hidden\",\n      \"placeholder\": \"Country\",\n      \"choices\": [\n        {\n          \"text\": \"Afghanistan\",\n          \"value\": \"AFG\"\n        },\n        {\n          \"text\": \"Angola\",\n          \"value\": \"ANG\"\n        },\n        {\n          \"text\": \"Albania\",\n          \"value\": \"ALB\"\n        },\n        {\n          \"text\": \"Andorra\",\n          \"value\": \"AND\"\n        },\n        {\n          \"text\": \"United Arab Emirates\",\n          \"value\": \"UAE\"\n        },\n        {\n          \"text\": \"Argentina\",\n          \"value\": \"ARG\"\n        },\n        {\n          \"text\": \"Armenia\",\n          \"value\": \"ARM\"\n        },\n        {\n          \"text\": \"Antigua and Barbuda\",\n          \"value\": \"ANT\"\n        },\n        {\n          \"text\": \"Australia\",\n          \"value\": \"AUS\"\n        },\n        {\n          \"text\": \"Austria\",\n          \"value\": \"AUT\"\n        },\n        {\n          \"text\": \"Azerbaijan\",\n          \"value\": \"AZE\"\n        },\n        {\n          \"text\": \"Burundi\",\n          \"value\": \"BDI\"\n        },\n        {\n          \"text\": \"Belgium\",\n          \"value\": \"BEL\"\n        },\n        {\n          \"text\": \"Benin\",\n          \"value\": \"BEN\"\n        },\n        {\n          \"text\": \"Burkina Faso\",\n          \"value\": \"BFA\"\n        },\n        {\n          \"text\": \"Bangladesh\",\n          \"value\": \"BGD\"\n        },\n        {\n          \"text\": \"Bulgaria\",\n          \"value\": \"BUL\"\n        },\n        {\n          \"text\": \"Bahrain\",\n          \"value\": \"BRN\"\n        },\n        {\n          \"text\": \"Bahamas\",\n          \"value\": \"BAH\"\n        },\n        {\n          \"text\": \"Bosnia and Herzegovina\",\n          \"value\": \"BIH\"\n        },\n        {\n          \"text\": \"Belarus\",\n          \"value\": \"BLR\"\n        },\n        {\n          \"text\": \"Belize\",\n          \"value\": \"BIZ\"\n        },\n        {\n          \"text\": \"Bolivia\",\n          \"value\": \"BOL\"\n        },\n        {\n          \"text\": \"Brazil\",\n          \"value\": \"BRA\"\n        },\n        {\n          \"text\": \"Barbados\",\n          \"value\": \"BAR\"\n        },\n        {\n          \"text\": \"Brunei\",\n          \"value\": \"BRU\"\n        },\n        {\n          \"text\": \"Bhutan\",\n          \"value\": \"BHU\"\n        },\n        {\n          \"text\": \"Botswana\",\n          \"value\": \"BOT\"\n        },\n        {\n          \"text\": \"Central African Republic\",\n          \"value\": \"CAF\"\n        },\n        {\n          \"text\": \"Canada\",\n          \"value\": \"CAN\"\n        },\n        {\n          \"text\": \"Switzerland\",\n          \"value\": \"CHE\"\n        },\n        {\n          \"text\": \"Chile\",\n          \"value\": \"CHI\"\n        },\n        {\n          \"text\": \"China\",\n          \"value\": \"CHN\"\n        },\n        {\n          \"text\": \"Ivory Coast\",\n          \"value\": \"CIV\"\n        },\n        {\n          \"text\": \"Cameroon\",\n          \"value\": \"CMR\"\n        },\n        {\n          \"text\": \"DR Congo\",\n          \"value\": \"COD\"\n        },\n        {\n          \"text\": \"Republic of the Congo\",\n          \"value\": \"CGO\"\n        },\n        {\n          \"text\": \"Colombia\",\n          \"value\": \"COL\"\n        },\n        {\n          \"text\": \"Comoros\",\n          \"value\": \"COM\"\n        },\n        {\n          \"text\": \"Cape Verde\",\n          \"value\": \"CPV\"\n        },\n        {\n          \"text\": \"Costa Rica\",\n          \"value\": \"CRC\"\n        },\n        {\n          \"text\": \"Cuba\",\n          \"value\": \"CUB\"\n        },\n        {\n          \"text\": \"Cyprus\",\n          \"value\": \"CYP\"\n        },\n        {\n          \"text\": \"Czechia\",\n          \"value\": \"CZE\"\n        },\n        {\n          \"text\": \"Germany\",\n          \"value\": \"DEU\"\n        },\n        {\n          \"text\": \"Djibouti\",\n          \"value\": \"DJI\"\n        },\n        {\n          \"text\": \"Dominica\",\n          \"value\": \"DMA\"\n        },\n        {\n          \"text\": \"Denmark\",\n          \"value\": \"DEN\"\n        },\n        {\n          \"text\": \"Dominican Republic\",\n          \"value\": \"DOM\"\n        },\n        {\n          \"text\": \"Algeria\",\n          \"value\": \"ALG\"\n        },\n        {\n          \"text\": \"Ecuador\",\n          \"value\": \"ECU\"\n        },\n        {\n          \"text\": \"Egypt\",\n          \"value\": \"EGY\"\n        },\n        {\n          \"text\": \"Eritrea\",\n          \"value\": \"ERI\"\n        },\n        {\n          \"text\": \"Spain\",\n          \"value\": \"ESP\"\n        },\n        {\n          \"text\": \"Estonia\",\n          \"value\": \"EST\"\n        },\n        {\n          \"text\": \"Ethiopia\",\n          \"value\": \"ETH\"\n        },\n        {\n          \"text\": \"Finland\",\n          \"value\": \"FIN\"\n        },\n        {\n          \"text\": \"Fiji\",\n          \"value\": \"FIJ\"\n        },\n        {\n          \"text\": \"France\",\n          \"value\": \"FRA\"\n        },\n        {\n          \"text\": \"Micronesia\",\n          \"value\": \"FSM\"\n        },\n        {\n          \"text\": \"Gabon\",\n          \"value\": \"GAB\"\n        },\n        {\n          \"text\": \"United Kingdom\",\n          \"value\": \"GBR\"\n        },\n        {\n          \"text\": \"Georgia\",\n          \"value\": \"GEO\"\n        },\n        {\n          \"text\": \"Ghana\",\n          \"value\": \"GHA\"\n        },\n        {\n          \"text\": \"Guinea\",\n          \"value\": \"GUI\"\n        },\n        {\n          \"text\": \"Gambia\",\n          \"value\": \"GAM\"\n        },\n        {\n          \"text\": \"Equatorial Guinea\",\n          \"value\": \"GEQ\"\n        },\n        {\n          \"text\": \"Greece\",\n          \"value\": \"GRE\"\n        },\n        {\n          \"text\": \"Grenada\",\n          \"value\": \"GRN\"\n        },\n        {\n          \"text\": \"Guatemala\",\n          \"value\": \"GUA\"\n        },\n        {\n          \"text\": \"Guyana\",\n          \"value\": \"GUY\"\n        },\n        {\n          \"text\": \"Honduras\",\n          \"value\": \"HON\"\n        },\n        {\n          \"text\": \"Croatia\",\n          \"value\": \"CRO\"\n        },\n        {\n          \"text\": \"Haiti\",\n          \"value\": \"HAI\"\n        },\n        {\n          \"text\": \"Hungary\",\n          \"value\": \"HUN\"\n        },\n        {\n          \"text\": \"Indonesia\",\n          \"value\": \"INA\"\n        },\n        {\n          \"text\": \"India\",\n          \"value\": \"IND\"\n        },\n        {\n          \"text\": \"Ireland\",\n          \"value\": \"IRL\"\n        },\n        {\n          \"text\": \"Iran\",\n          \"value\": \"IRI\"\n        },\n        {\n          \"text\": \"Iraq\",\n          \"value\": \"IRQ\"\n        },\n        {\n          \"text\": \"Iceland\",\n          \"value\": \"ISL\"\n        },\n        {\n          \"text\": \"Israel\",\n          \"value\": \"ISR\"\n        },\n        {\n          \"text\": \"Italy\",\n          \"value\": \"ITA\"\n        },\n        {\n          \"text\": \"Jamaica\",\n          \"value\": \"JAM\"\n        },\n        {\n          \"text\": \"Jordan\",\n          \"value\": \"JOR\"\n        },\n        {\n          \"text\": \"Japan\",\n          \"value\": \"JPN\"\n        },\n        {\n          \"text\": \"Kazakhstan\",\n          \"value\": \"KAZ\"\n        },\n        {\n          \"text\": \"Kenya\",\n          \"value\": \"KEN\"\n        },\n        {\n          \"text\": \"Kyrgyzstan\",\n          \"value\": \"KGZ\"\n        },\n        {\n          \"text\": \"Cambodia\",\n          \"value\": \"KHM\"\n        },\n        {\n          \"text\": \"Kiribati\",\n          \"value\": \"KIR\"\n        },\n        {\n          \"text\": \"Saint Kitts and Nevis\",\n          \"value\": \"SKN\"\n        },\n        {\n          \"text\": \"South Korea\",\n          \"value\": \"KOR\"\n        },\n        {\n          \"text\": \"Kuwait\",\n          \"value\": \"KUW\"\n        },\n        {\n          \"text\": \"Laos\",\n          \"value\": \"LAO\"\n        },\n        {\n          \"text\": \"Lebanon\",\n          \"value\": \"LIB\"\n        },\n        {\n          \"text\": \"Liberia\",\n          \"value\": \"LBR\"\n        },\n        {\n          \"text\": \"Libya\",\n          \"value\": \"LBA\"\n        },\n        {\n          \"text\": \"Saint Lucia\",\n          \"value\": \"LCA\"\n        },\n        {\n          \"text\": \"Liechtenstein\",\n          \"value\": \"LIE\"\n        },\n        {\n          \"text\": \"Sri Lanka\",\n          \"value\": \"SRI\"\n        },\n        {\n          \"text\": \"Lesotho\",\n          \"value\": \"LES\"\n        },\n        {\n          \"text\": \"Lithuania\",\n          \"value\": \"LTU\"\n        },\n        {\n          \"text\": \"Luxembourg\",\n          \"value\": \"LUX\"\n        },\n        {\n          \"text\": \"Latvia\",\n          \"value\": \"LAT\"\n        },\n        {\n          \"text\": \"Morocco\",\n          \"value\": \"MAR\"\n        },\n        {\n          \"text\": \"Monaco\",\n          \"value\": \"MON\"\n        },\n        {\n          \"text\": \"Moldova\",\n          \"value\": \"MDA\"\n        },\n        {\n          \"text\": \"Madagascar\",\n          \"value\": \"MAD\"\n        },\n        {\n          \"text\": \"Maldives\",\n          \"value\": \"MDV\"\n        },\n        {\n          \"text\": \"Mexico\",\n          \"value\": \"MEX\"\n        },\n        {\n          \"text\": \"Marshall Islands\",\n          \"value\": \"MHL\"\n        },\n        {\n          \"text\": \"North Macedonia\",\n          \"value\": \"MKD\"\n        },\n        {\n          \"text\": \"Mali\",\n          \"value\": \"MLI\"\n        },\n        {\n          \"text\": \"Malta\",\n          \"value\": \"MLT\"\n        },\n        {\n          \"text\": \"Myanmar\",\n          \"value\": \"MYA\"\n        },\n        {\n          \"text\": \"Montenegro\",\n          \"value\": \"MNE\"\n        },\n        {\n          \"text\": \"Mongolia\",\n          \"value\": \"MGL\"\n        },\n        {\n          \"text\": \"Mozambique\",\n          \"value\": \"MOZ\"\n        },\n        {\n          \"text\": \"Mauritania\",\n          \"value\": \"MTN\"\n        },\n        {\n          \"text\": \"Mauritius\",\n          \"value\": \"MRI\"\n        },\n        {\n          \"text\": \"Malawi\",\n          \"value\": \"MAW\"\n        },\n        {\n          \"text\": \"Malaysia\",\n          \"value\": \"MAS\"\n        },\n        {\n          \"text\": \"Namibia\",\n          \"value\": \"NAM\"\n        },\n        {\n          \"text\": \"Niger\",\n          \"value\": \"NIG\"\n        },\n        {\n          \"text\": \"Nigeria\",\n          \"value\": \"NGR\"\n        },\n        {\n          \"text\": \"Nicaragua\",\n          \"value\": \"NCA\"\n        },\n        {\n          \"text\": \"Netherlands\",\n          \"value\": \"NED\"\n        },\n        {\n          \"text\": \"Norway\",\n          \"value\": \"NOR\"\n        },\n        {\n          \"text\": \"Nepal\",\n          \"value\": \"NEP\"\n        },\n        {\n          \"text\": \"Nauru\",\n          \"value\": \"NRU\"\n        },\n        {\n          \"text\": \"New Zealand\",\n          \"value\": \"NZL\"\n        },\n        {\n          \"text\": \"Oman\",\n          \"value\": \"OMA\"\n        },\n        {\n          \"text\": \"Pakistan\",\n          \"value\": \"PAK\"\n        },\n        {\n          \"text\": \"Panama\",\n          \"value\": \"PAN\"\n        },\n        {\n          \"text\": \"Peru\",\n          \"value\": \"PER\"\n        },\n        {\n          \"text\": \"Philippines\",\n          \"value\": \"PHI\"\n        },\n        {\n          \"text\": \"Palau\",\n          \"value\": \"PLW\"\n        },\n        {\n          \"text\": \"Papua New Guinea\",\n          \"value\": \"PNG\"\n        },\n        {\n          \"text\": \"Poland\",\n          \"value\": \"POL\"\n        },\n        {\n          \"text\": \"North Korea\",\n          \"value\": \"PRK\"\n        },\n        {\n          \"text\": \"Portugal\",\n          \"value\": \"POR\"\n        },\n        {\n          \"text\": \"Paraguay\",\n          \"value\": \"PAR\"\n        },\n        {\n          \"text\": \"Qatar\",\n          \"value\": \"QAT\"\n        },\n        {\n          \"text\": \"Romania\",\n          \"value\": \"ROU\"\n        },\n        {\n          \"text\": \"Russia\",\n          \"value\": \"RUS\"\n        },\n        {\n          \"text\": \"Rwanda\",\n          \"value\": \"RWA\"\n        },\n        {\n          \"text\": \"Saudi Arabia\",\n          \"value\": \"KSA\"\n        },\n        {\n          \"text\": \"Sudan\",\n          \"value\": \"SUD\"\n        },\n        {\n          \"text\": \"Senegal\",\n          \"value\": \"SEN\"\n        },\n        {\n          \"text\": \"Singapore\",\n          \"value\": \"SIN\"\n        },\n        {\n          \"text\": \"Solomon Islands\",\n          \"value\": \"SOL\"\n        },\n        {\n          \"text\": \"Sierra Leone\",\n          \"value\": \"SLE\"\n        },\n        {\n          \"text\": \"El Salvador\",\n          \"value\": \"ESA\"\n        },\n        {\n          \"text\": \"San Marino\",\n          \"value\": \"SMR\"\n        },\n        {\n          \"text\": \"Somalia\",\n          \"value\": \"SOM\"\n        },\n        {\n          \"text\": \"Serbia\",\n          \"value\": \"SRB\"\n        },\n        {\n          \"text\": \"S\\u00e3o Tom\\u00e9 and Pr\\u00edncipe\",\n          \"value\": \"STP\"\n        },\n        {\n          \"text\": \"Suriname\",\n          \"value\": \"SUR\"\n        },\n        {\n          \"text\": \"Slovakia\",\n          \"value\": \"SVK\"\n        },\n        {\n          \"text\": \"Slovenia\",\n          \"value\": \"SLO\"\n        },\n        {\n          \"text\": \"Sweden\",\n          \"value\": \"SWE\"\n        },\n        {\n          \"text\": \"Eswatini\",\n          \"value\": \"SWZ\"\n        },\n        {\n          \"text\": \"Seychelles\",\n          \"value\": \"SEY\"\n        },\n        {\n          \"text\": \"Syria\",\n          \"value\": \"SYR\"\n        },\n        {\n          \"text\": \"Chad\",\n          \"value\": \"CHA\"\n        },\n        {\n          \"text\": \"Togo\",\n          \"value\": \"TOG\"\n        },\n        {\n          \"text\": \"Thailand\",\n          \"value\": \"THA\"\n        },\n        {\n          \"text\": \"Tajikistan\",\n          \"value\": \"TJK\"\n        },\n        {\n          \"text\": \"Turkmenistan\",\n          \"value\": \"TKM\"\n        },\n        {\n          \"text\": \"Timor-Leste\",\n          \"value\": \"TLS\"\n        },\n        {\n          \"text\": \"Tonga\",\n          \"value\": \"TGA\"\n        },\n        {\n          \"text\": \"Trinidad and Tobago\",\n          \"value\": \"TTO\"\n        },\n        {\n          \"text\": \"Tunisia\",\n          \"value\": \"TUN\"\n        },\n        {\n          \"text\": \"Turkey\",\n          \"value\": \"TUR\"\n        },\n        {\n          \"text\": \"Tuvalu\",\n          \"value\": \"TUV\"\n        },\n        {\n          \"text\": \"Tanzania\",\n          \"value\": \"TAN\"\n        },\n        {\n          \"text\": \"Uganda\",\n          \"value\": \"UGA\"\n        },\n        {\n          \"text\": \"Ukraine\",\n          \"value\": \"UKR\"\n        },\n        {\n          \"text\": \"Uruguay\",\n          \"value\": \"URU\"\n        },\n        {\n          \"text\": \"United States\",\n          \"value\": \"USA\"\n        },\n        {\n          \"text\": \"Uzbekistan\",\n          \"value\": \"UZB\"\n        },\n        {\n          \"text\": \"Saint Vincent and the Grenadines\",\n          \"value\": \"VIN\"\n        },\n        {\n          \"text\": \"Venezuela\",\n          \"value\": \"VEN\"\n        },\n        {\n          \"text\": \"Vietnam\",\n          \"value\": \"VIE\"\n        },\n        {\n          \"text\": \"Vanuatu\",\n          \"value\": \"VAN\"\n        },\n        {\n          \"text\": \"Samoa\",\n          \"value\": \"SAM\"\n        },\n        {\n          \"text\": \"Yemen\",\n          \"value\": \"YEM\"\n        },\n        {\n          \"text\": \"South Africa\",\n          \"value\": \"RSA\"\n        },\n        {\n          \"text\": \"Zambia\",\n          \"value\": \"ZAM\"\n        },\n        {\n          \"text\": \"Zimbabwe\",\n          \"value\": \"ZIM\"\n        }\n      ],\n      \"category\": \"7\"\n    },\n    {\n      \"name\": \"durationInCurrentResidenceMth\",\n      \"displayName\": \"Duration in Current Residence (Months)\",\n      \"placeholder\": \"Duration in Current Residence (Months)\",\n      \"startWithNewLine\": false,\n      \"type\": \"text\",\n      \"maxLength\": 2,\n      \"min\": 0,\n      \"max\": 11,\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"regex\": \"^([0-9]|10|11)$\",\n          \"text\": \"Value must be a number between 0-11.\"\n        }\n      ],\n      \"inputType\": \"number\",\n      \"category\": \"7\"\n    },\n    {\n      \"name\": \"durationInCurrentResidenceYr\",\n      \"displayName\": \"Duration in Current Residence (Years)\",\n      \"placeholder\": \"Duration in Current Residence (Years)\",\n      \"type\": \"text\",\n      \"maxLength\": 2,\n      \"min\": 0,\n      \"max\": 99,\n      \"inputType\": \"number\",\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"regex\": \"^([0-9]|[1-9][0-9])$\",\n          \"text\": \"Value must be a number between 0-99.\"\n        }\n      ],\n      \"category\": \"7\"\n    },\n    {\n      \"name\": \"officePhoneNo\",\n      \"displayName\": \"Employer Phone Number\",\n      \"placeholder\": \"Employer Phone Number\",\n      \"visibleIf\": \"{employmentType} anyof ['01', '02', '07', '08', '09', '10' ]\",\n      \"type\": \"text\",\n      \"maxLength\": 12,\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"text\": \"The phone number must be a valid Malaysian number\",\n          \"regex\": \"^(011[0-9]{8}|(60[4-7]|004|005|006|007|009|609|012|013|014|016|017|019)[0-9]{7})$\"\n        }\n      ],\n      \"inputType\": \"tel\",\n      \"category\": \"5\"\n    },\n    {\n      \"name\": \"officePhoneNoAreaCode\",\n      \"displayName\": \"Office Phone Number Area Code\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"8\"\n    },\n    {\n      \"name\": \"postcode\",\n      \"displayName\": \"Postcode\",\n      \"type\": \"text\",\n      \"category\": \"7\"\n    },\n    {\n      \"name\": \"state\",\n      \"displayName\": \"Permanent State\",\n      \"placeholder\": \"Select State Of The Permanenet Address\",\n      \"startWithNewLine\": false,\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"A\",\n          \"text\": \"PERAK\"\n        },\n        {\n          \"value\": \"B\",\n          \"text\": \"SELANGOR\"\n        },\n        {\n          \"value\": \"C\",\n          \"text\": \"PAHANG\"\n        },\n        {\n          \"value\": \"D\",\n          \"text\": \"KELANTAN\"\n        },\n        {\n          \"value\": \"J\",\n          \"text\": \"JOHOR\"\n        },\n        {\n          \"value\": \"K\",\n          \"text\": \"KEDAH\"\n        },\n        {\n          \"value\": \"L\",\n          \"text\": \"WP LABUAN\"\n        },\n        {\n          \"value\": \"M\",\n          \"text\": \"MELAKA\"\n        },\n        {\n          \"value\": \"N\",\n          \"text\": \"NEGERI SEMBILAN\"\n        },\n        {\n          \"value\": \"P\",\n          \"text\": \"PULAU PINANG\"\n        },\n        {\n          \"value\": \"Q\",\n          \"text\": \"SARAWAK\"\n        },\n        {\n          \"value\": \"R\",\n          \"text\": \"PERLIS\"\n        },\n        {\n          \"value\": \"S\",\n          \"text\": \"SABAH\"\n        },\n        {\n          \"value\": \"T\",\n          \"text\": \"TERENGGANU\"\n        },\n        {\n          \"value\": \"U\",\n          \"text\": \"WP PUTRAJAYA\"\n        },\n        {\n          \"value\": \"W\",\n          \"text\": \"WP KUALA LUMPUR\"\n        }\n      ],\n      \"category\": \"7\"\n    },\n    {\n      \"name\": \"residenceAddress\",\n      \"displayName\": \"Residence address same as permanent address?\",\n      \"type\": \"boolean\",\n      \"defaultValue\": false,\n      \"requiredForEvaluation\": false,\n      \"category\": \"7\"\n    },\n    {\n      \"name\": \"officestate\",\n      \"displayName\": \"Employer State\",\n      \"startWithNewLine\": false,\n      \"visibleIf\": \"{employmentType} anyof ['01', '02', '07', '08', '09', '10' ]\",\n      \"placeholder\": \"Select State Of The Employer Address\",\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"A\",\n          \"text\": \"PERAK\"\n        },\n        {\n          \"value\": \"B\",\n          \"text\": \"SELANGOR\"\n        },\n        {\n          \"value\": \"C\",\n          \"text\": \"PAHANG\"\n        },\n        {\n          \"value\": \"D\",\n          \"text\": \"KELANTAN\"\n        },\n        {\n          \"value\": \"J\",\n          \"text\": \"JOHOR\"\n        },\n        {\n          \"value\": \"K\",\n          \"text\": \"KEDAH\"\n        },\n        {\n          \"value\": \"L\",\n          \"text\": \"WP LABUAN\"\n        },\n        {\n          \"value\": \"M\",\n          \"text\": \"MELAKA\"\n        },\n        {\n          \"value\": \"N\",\n          \"text\": \"NEGERI SEMBILAN\"\n        },\n        {\n          \"value\": \"P\",\n          \"text\": \"PULAU PINANG\"\n        },\n        {\n          \"value\": \"Q\",\n          \"text\": \"SARAWAK\"\n        },\n        {\n          \"value\": \"R\",\n          \"text\": \"PERLIS\"\n        },\n        {\n          \"value\": \"S\",\n          \"text\": \"SABAH\"\n        },\n        {\n          \"value\": \"T\",\n          \"text\": \"TERENGGANU\"\n        },\n        {\n          \"value\": \"U\",\n          \"text\": \"WP PUTRAJAYA\"\n        },\n        {\n          \"value\": \"W\",\n          \"text\": \"WP KUALA LUMPUR\"\n        }\n      ],\n      \"category\": \"5\"\n    },\n    {\n      \"type\": \"text\",\n      \"name\": \"age\",\n      \"title\": \"Age\",\n      \"isRequired\": true,\n      \"displayName\": \"Age\",\n      \"visible\": false,\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"text\": \"Please enter a valid whole number age between 21 and 55.\",\n          \"regex\": \"^(2[1-9]|[3-4][0-9]|55)$\"\n        }\n      ],\n      \"defaultValue\": \"21\",\n      \"category\": \"2\"\n    },\n    {\n      \"name\": \"consentCrossSelling\",\n      \"displayName\": \"Consent Cross-Selling, Consent to Obtain Information from CTOS and Disclosure of Information\",\n      \"type\": \"boolean\",\n      \"validators\": [\n        {\n          \"type\": \"expression\",\n          \"expression\": \"{consentCrossSelling} = true\",\n          \"text\": \"You must provide consent to Consent Cross-Selling.\"\n        }\n      ],\n      \"defaultValue\": false,\n      \"showTitle\": true,\n      \"category\": \"9\"\n    },\n    {\n      \"type\": \"text\",\n      \"name\": \"consentObtainInfoFromCtos\",\n      \"displayName\": \"Consent to Obtain Information from CTOS\",\n      \"defaultValue\": \"yes\",\n      \"showTitle\": true,\n      \"visible\": false,\n      \"category\": \"9\"\n    },\n    {\n      \"name\": \"dateJoined\",\n      \"displayName\": \"Date Joined\",\n      \"placeholder\": \"Date Joined\",\n      \"startWithNewLine\": false,\n      \"type\": \"text\",\n      \"maxLength\": 10,\n      \"inputType\": \"date\",\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"regex\": \"^\\\\d{4}-\\\\d{2}-\\\\d{2}$\",\n          \"text\": \"Date must be in YYYY-MM-DD format\"\n        },\n        {\n          \"type\": \"custom\",\n          \"validator\": \"validateNotFutureDate\",\n          \"text\": \"Date of joining cannot be in the future\"\n        }\n      ],\n      \"category\": \"5\"\n    },\n    {\n      \"name\": \"disclosureOfInformation\",\n      \"displayName\": \"Disclosure of Information\",\n      \"type\": \"text\",\n      \"defaultValue\": \"yes\",\n      \"showTitle\": true,\n      \"visible\": false,\n      \"category\": \"9\"\n    },\n    {\n      \"name\": \"educationLevel\",\n      \"displayName\": \"Education Level\",\n      \"placeholder\": \"Highest Education Level\",\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"01\",\n          \"text\": \"Primary\"\n        },\n        {\n          \"value\": \"02\",\n          \"text\": \"Secondary/High school\"\n        },\n        {\n          \"value\": \"03\",\n          \"text\": \"College graduate-certificate/Diploma holder\"\n        },\n        {\n          \"value\": \"04\",\n          \"text\": \"University Degree/Associate Degree\"\n        },\n        {\n          \"value\": \"05\",\n          \"text\": \"Master Degree\"\n        },\n        {\n          \"value\": \"06\",\n          \"text\": \"Doctorate\"\n        }\n      ],\n      \"category\": \"2\"\n    },\n    {\n      \"name\": \"emerContactTelNo1\",\n      \"displayName\": \"Emergency Contact Telephone Number 1\",\n      \"startWithNewLine\": false,\n      \"placeholder\": \"Emergency Contact Telephone Number 1\",\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"text\": \"A valid Malaysia phone number is required.\",\n          \"regex\": \"^((60[4-79]|0[4-79])[0-9]{7}|011[0-9]{8}|01[2346789][0-9]{7})$\"\n        }\n      ],\n      \"type\": \"text\",\n      \"maxLength\": 18,\n      \"inputType\": \"tel\",\n      \"category\": \"8\"\n    },\n    {\n      \"name\": \"emerContactTelNo1AreaCode\",\n      \"displayName\": \"Emergency Contact Telephone Number 1 Area Code\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"8\"\n    },\n    {\n      \"name\": \"emergencyContactName\",\n      \"displayName\": \"Emergency Contact Name\",\n      \"placeholder\": \"Emergency Contact Name\",\n      \"type\": \"text\",\n      \"maxLength\": 40,\n      \"category\": \"8\"\n    },\n    {\n      \"name\": \"employerName\",\n      \"displayName\": \"Employer Name\",\n      \"placeholder\": \"Employer Name\",\n      \"visibleIf\": \"{employmentType} anyof ['01', '02', '07', '08', '09', '10' ]\",\n      \"type\": \"text\",\n      \"maxLength\": 40,\n      \"category\": \"5\"\n    },\n    {\n      \"name\": \"employmentSector\",\n      \"displayName\": \"Employment Sector\",\n      \"placeholder\": \"Select Employment Sector\",\n      \"visibleIf\": \"{employmentType} anyof ['01', '02', '07', '08', '09', '10' ]\",\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"0010\",\n          \"text\": \"Accounting\"\n        },\n        {\n          \"value\": \"0020\",\n          \"text\": \"Actuarial / Statistic\"\n        },\n        {\n          \"value\": \"0030\",\n          \"text\": \"Advertising / Marketing / PR\"\n        },\n        {\n          \"value\": \"0040\",\n          \"text\": \"Aerospace\"\n        },\n        {\n          \"value\": \"0050\",\n          \"text\": \"Agricultural / Chemicals / Forest Products\"\n        },\n        {\n          \"value\": \"0060\",\n          \"text\": \"Architecture\"\n        },\n        {\n          \"value\": \"0070\",\n          \"text\": \"Automotive / Manufacturing / Production\"\n        },\n        {\n          \"value\": \"0080\",\n          \"text\": \"Aviation\"\n        },\n        {\n          \"value\": \"0090\",\n          \"text\": \"Buying / Retail\"\n        },\n        {\n          \"value\": \"0100\",\n          \"text\": \"Computers / Electronics\"\n        },\n        {\n          \"value\": \"0110\",\n          \"text\": \"Construction\"\n        },\n        {\n          \"value\": \"0120\",\n          \"text\": \"Creative / Graphics\"\n        },\n        {\n          \"value\": \"0130\",\n          \"text\": \"Customer Service\"\n        },\n        {\n          \"value\": \"0140\",\n          \"text\": \"Education (includes students) / Training\"\n        },\n        {\n          \"value\": \"0150\",\n          \"text\": \"Energy / Mining\"\n        },\n        {\n          \"value\": \"0160\",\n          \"text\": \"Engineering\"\n        },\n        {\n          \"value\": \"0170\",\n          \"text\": \"Finance / Banking / Insurance\"\n        },\n        {\n          \"value\": \"0180\",\n          \"text\": \"Freight / Shipping\"\n        },\n        {\n          \"value\": \"0190\",\n          \"text\": \"Government / Military / Public Service\"\n        },\n        {\n          \"value\": \"0200\",\n          \"text\": \"Recreation / Hospitality / Sports\"\n        },\n        {\n          \"value\": \"0210\",\n          \"text\": \"Hotel / Food\"\n        },\n        {\n          \"value\": \"0220\",\n          \"text\": \"Human Resources\"\n        },\n        {\n          \"value\": \"0230\",\n          \"text\": \"Investment\"\n        },\n        {\n          \"value\": \"0240\",\n          \"text\": \"Journalist / Editor\"\n        },\n        {\n          \"value\": \"0250\",\n          \"text\": \"Media / Publishing\"\n        },\n        {\n          \"value\": \"0260\",\n          \"text\": \"Medical / Health Services\"\n        },\n        {\n          \"value\": \"0270\",\n          \"text\": \"Non-Profit Organization\"\n        },\n        {\n          \"value\": \"0280\",\n          \"text\": \"Geology\"\n        },\n        {\n          \"value\": \"0290\",\n          \"text\": \"Pharmaceuticals\"\n        },\n        {\n          \"value\": \"0300\",\n          \"text\": \"Real Estate\"\n        },\n        {\n          \"value\": \"0310\",\n          \"text\": \"Administrative and Support Service Activities\"\n        },\n        {\n          \"value\": \"0320\",\n          \"text\": \"Social Services\"\n        },\n        {\n          \"value\": \"0330\",\n          \"text\": \"Telecommunications / Networking\"\n        },\n        {\n          \"value\": \"0340\",\n          \"text\": \"Travel\"\n        },\n        {\n          \"value\": \"0350\",\n          \"text\": \"Transportation\"\n        },\n        {\n          \"value\": \"0360\",\n          \"text\": \"Entertainment / Arts\"\n        },\n        {\n          \"value\": \"0370\",\n          \"text\": \"Electricity, Gas, Steam and Air Conditioning Supply\"\n        },\n        {\n          \"value\": \"0380\",\n          \"text\": \"Water Supply; Sewerage, Waste Management and Remediation Activities\"\n        },\n        {\n          \"value\": \"0390\",\n          \"text\": \"Activities of Households as Employers; Undifferentiated Goods and Services Producing Activities of Households for Own Use\"\n        },\n        {\n          \"value\": \"0400\",\n          \"text\": \"Activities of Extraterritorial Organisations and Bodies\"\n        },\n        {\n          \"value\": \"0410\",\n          \"text\": \"Unemployed/ Outside Labour Force\"\n        },\n        {\n          \"value\": \"0420\",\n          \"text\": \"Other Service Activities\"\n        },\n        {\n          \"value\": \"0430\",\n          \"text\": \"Legal Services\"\n        },\n        {\n          \"value\": \"0440\",\n          \"text\": \"Research & Experimental Development Services\"\n        },\n        {\n          \"value\": \"0450\",\n          \"text\": \"Other Professional, Scientific and Technical Activities\"\n        }\n      ],\n      \"category\": \"5\"\n    },\n    {\n      \"name\": \"employmentStatus\",\n      \"displayName\": \"Employment Status\",\n      \"placeholder\": \"Select Employment Status\",\n      \"startWithNewLine\": false,\n      \"visibleIf\": \"{employmentType} anyof ['01', '08', '09']\",\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"CON\",\n          \"text\": \"Contract\"\n        },\n        {\n          \"value\": \"FRL\",\n          \"text\": \"Freelance\"\n        },\n        {\n          \"value\": \"OTH\",\n          \"text\": \"Others\"\n        },\n        {\n          \"value\": \"PER\",\n          \"text\": \"Permanent\"\n        },\n        {\n          \"value\": \"PRT\",\n          \"text\": \"Part Time\"\n        },\n        {\n          \"value\": \"TMP\",\n          \"text\": \"Temporary\"\n        },\n        {\n          \"value\": \"UPROB\",\n          \"text\": \"Under Probation\"\n        }\n      ],\n      \"category\": \"5\"\n    },\n    {\n      \"name\": \"employmentType\",\n      \"displayName\": \"Employment Type\",\n      \"placeholder\": \"Select Employment Type\",\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"01\",\n          \"text\": \"Private Employee\"\n        },\n        {\n          \"value\": \"02\",\n          \"text\": \"Employer\"\n        },\n        {\n          \"value\": \"03\",\n          \"text\": \"Housewife\"\n        },\n        {\n          \"value\": \"04\",\n          \"text\": \"Retired\"\n        },\n        {\n          \"value\": \"05\",\n          \"text\": \"Student\"\n        },\n        {\n          \"value\": \"06\",\n          \"text\": \"Unemployed\"\n        },\n        {\n          \"value\": \"07\",\n          \"text\": \"Self-employed/Own Account Worker\"\n        },\n        {\n          \"value\": \"08\",\n          \"text\": \"Government Employee\"\n        },\n        {\n          \"value\": \"09\",\n          \"text\": \"Reporting Entity Employee\"\n        },\n        {\n          \"value\": \"10\",\n          \"text\": \"Unpaid Family Worker\"\n        }\n      ],\n      \"category\": \"5\"\n    },\n    {\n      \"name\": \"gender\",\n      \"displayName\": \"Gender\",\n      \"placeholder\": \"Select Gender\",\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"M\",\n          \"text\": \"Male\"\n        },\n        {\n          \"value\": \"F\",\n          \"text\": \"Female\"\n        }\n      ],\n      \"category\": \"2\"\n    },\n    {\n      \"name\": \"idType\",\n      \"displayName\": \"ID Type\",\n      \"type\": \"dropdown\",\n      \"defaultValue\": \"MyKad\",\n      \"choices\": [\n        {\n          \"value\": \"MK\",\n          \"text\": \"MyKad\"\n        }\n      ],\n      \"category\": \"2\"\n    },\n    {\n      \"name\": \"lengthOfServiceMonth\",\n      \"displayName\": \"Length of Service (Months)\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"5\"\n    },\n    {\n      \"name\": \"lengthOfServiceYear\",\n      \"displayName\": \"Length of Service (Years)\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"5\"\n    },\n    {\n      \"name\": \"mailingBillingAddressInd\",\n      \"displayName\": \"Preferred Mailing Address\",\n      \"placeholder\": \"Select Preferred Mailing Address\",\n      \"startWithNewLine\": false,\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"O\",\n          \"text\": \"Office\"\n        },\n        {\n          \"value\": \"R\",\n          \"text\": \"Residence\"\n        }\n      ],\n      \"category\": \"7\"\n    },\n    {\n      \"name\": \"maritalStatus\",\n      \"displayName\": \"Marital Status\",\n      \"placeholder\": \"Select Marital Status\",\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"S\",\n          \"text\": \"Single\"\n        },\n        {\n          \"value\": \"M\",\n          \"text\": \"Married\"\n        },\n        {\n          \"value\": \"W\",\n          \"text\": \"Widowed\"\n        },\n        {\n          \"value\": \"D\",\n          \"text\": \"Divorced\"\n        },\n        {\n          \"value\": \"E\",\n          \"text\": \"Separated\"\n        }\n      ],\n      \"category\": \"2\"\n    },\n    {\n      \"name\": \"monthlyGrossIncome\",\n      \"displayName\": \"Monthly Gross Income\",\n      \"placeholder\": \"E.g. 6000\",\n      \"visibleIf\": \"{employmentType} anyof ['01', '07', '08', '09', '10']\",\n      \"type\": \"text\",\n      \"maxLength\": 15,\n      \"inputType\": \"number\",\n      \"min\": 2000,\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"regex\": \"^\\\\d+(\\\\.\\\\d+)?$\",\n          \"text\": \"Please enter a valid non-negative number.\"\n        },\n        {\n          \"type\": \"expression\",\n          \"expression\": \"{monthlyGrossIncome} >= 2000\",\n          \"text\": \"Income must be at least RM 2000.\"\n        }\n      ],\n      \"kind\": \"money\",\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"monthlyNetIncome\",\n      \"displayName\": \"Monthly Net Income\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"nationality\",\n      \"displayName\": \"Nationality\",\n      \"type\": \"text\",\n      \"category\": \"2\"\n    },\n    {\n      \"name\": \"noOfDependants\",\n      \"displayName\": \"Number of Dependants\",\n      \"placeholder\": \"Number Of Dependants\",\n      \"type\": \"text\",\n      \"startWithNewLine\": false,\n      \"maxLength\": 3,\n      \"inputType\": \"number\",\n      \"min\": 0,\n      \"max\": 99,\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"text\": \"Please enter a valid whole number between 0 and 99.\",\n          \"regex\": \"^[0-9][0-9]?$\"\n        }\n      ],\n      \"category\": \"2\"\n    },\n    {\n      \"name\": \"occupation\",\n      \"displayName\": \"Occupation\",\n      \"placeholder\": \"Select Occupation\",\n      \"startWithNewLine\": false,\n      \"visibleIf\": \"{employmentType} anyof ['01', '02', '07', '08', '09', '10' ]\",\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"001\",\n          \"text\": \"Accountant\"\n        },\n        {\n          \"value\": \"005\",\n          \"text\": \"Army Officer\"\n        },\n        {\n          \"value\": \"007\",\n          \"text\": \"Assistant Director\"\n        },\n        {\n          \"value\": \"008\",\n          \"text\": \"Assistant Manager\"\n        },\n        {\n          \"value\": \"009\",\n          \"text\": \"Auditor\"\n        },\n        {\n          \"value\": \"010\",\n          \"text\": \"Baker\"\n        },\n        {\n          \"value\": \"011\",\n          \"text\": \"Beautician\"\n        },\n        {\n          \"value\": \"012\",\n          \"text\": \"Broker\"\n        },\n        {\n          \"value\": \"013\",\n          \"text\": \"Business Partner\"\n        },\n        {\n          \"value\": \"014\",\n          \"text\": \"Businessman/Businesswoman\"\n        },\n        {\n          \"value\": \"015\",\n          \"text\": \"Carpenter\"\n        },\n        {\n          \"value\": \"016\",\n          \"text\": \"Cashier\"\n        },\n        {\n          \"value\": \"017\",\n          \"text\": \"CEO\"\n        },\n        {\n          \"value\": \"018\",\n          \"text\": \"Chairman\"\n        },\n        {\n          \"value\": \"019\",\n          \"text\": \"Chief Accountant\"\n        },\n        {\n          \"value\": \"020\",\n          \"text\": \"Chief Auditor\"\n        },\n        {\n          \"value\": \"022\",\n          \"text\": \"Co-Director\"\n        },\n        {\n          \"value\": \"023\",\n          \"text\": \"Consultant\"\n        },\n        {\n          \"value\": \"024\",\n          \"text\": \"Contractor\"\n        },\n        {\n          \"value\": \"025\",\n          \"text\": \"Financial Controller\"\n        },\n        {\n          \"value\": \"026\",\n          \"text\": \"Coordinator\"\n        },\n        {\n          \"value\": \"027\",\n          \"text\": \"Copywriter\"\n        },\n        {\n          \"value\": \"028\",\n          \"text\": \"Dealer/Distributor\"\n        },\n        {\n          \"value\": \"029\",\n          \"text\": \"Dentist\"\n        },\n        {\n          \"value\": \"031\",\n          \"text\": \"Despatch\"\n        },\n        {\n          \"value\": \"032\",\n          \"text\": \"Detective\"\n        },\n        {\n          \"value\": \"034\",\n          \"text\": \"Diplomat\"\n        },\n        {\n          \"value\": \"035\",\n          \"text\": \"Director\"\n        },\n        {\n          \"value\": \"036\",\n          \"text\": \"Doctor\"\n        },\n        {\n          \"value\": \"038\",\n          \"text\": \"Electrician\"\n        },\n        {\n          \"value\": \"040\",\n          \"text\": \"Executive\"\n        },\n        {\n          \"value\": \"041\",\n          \"text\": \"Executive Director\"\n        },\n        {\n          \"value\": \"042\",\n          \"text\": \"Exporter\"\n        },\n        {\n          \"value\": \"043\",\n          \"text\": \"Farmer\"\n        },\n        {\n          \"value\": \"044\",\n          \"text\": \"Foreman\"\n        },\n        {\n          \"value\": \"045\",\n          \"text\": \"Gardener\"\n        },\n        {\n          \"value\": \"046\",\n          \"text\": \"General Manager\"\n        },\n        {\n          \"value\": \"047\",\n          \"text\": \"Goldsmith\"\n        },\n        {\n          \"value\": \"048\",\n          \"text\": \"Hairdresser\"\n        },\n        {\n          \"value\": \"049\",\n          \"text\": \"Hawker\"\n        },\n        {\n          \"value\": \"050\",\n          \"text\": \"Housewife\"\n        },\n        {\n          \"value\": \"051\",\n          \"text\": \"Homemaker\"\n        },\n        {\n          \"value\": \"053\",\n          \"text\": \"Investor\"\n        },\n        {\n          \"value\": \"054\",\n          \"text\": \"Jeweller\"\n        },\n        {\n          \"value\": \"055\",\n          \"text\": \"Judge\"\n        },\n        {\n          \"value\": \"057\",\n          \"text\": \"Lawyer/Barrister/Solicitor\"\n        },\n        {\n          \"value\": \"058\",\n          \"text\": \"Lender\"\n        },\n        {\n          \"value\": \"060\",\n          \"text\": \"Managing Director\"\n        },\n        {\n          \"value\": \"061\",\n          \"text\": \"Manufacturer\"\n        },\n        {\n          \"value\": \"063\",\n          \"text\": \"Money Lender\"\n        },\n        {\n          \"value\": \"064\",\n          \"text\": \"Money-Changer\"\n        },\n        {\n          \"value\": \"068\",\n          \"text\": \"Owner/Co-Owner\"\n        },\n        {\n          \"value\": \"070\",\n          \"text\": \"Partner\"\n        },\n        {\n          \"value\": \"071\",\n          \"text\": \"Pastor\"\n        },\n        {\n          \"value\": \"072\",\n          \"text\": \"Physician\"\n        },\n        {\n          \"value\": \"073\",\n          \"text\": \"Plumber\"\n        },\n        {\n          \"value\": \"075\",\n          \"text\": \"Principal\"\n        },\n        {\n          \"value\": \"076\",\n          \"text\": \"Programmer\"\n        },\n        {\n          \"value\": \"077\",\n          \"text\": \"Quantity Surveyor\"\n        },\n        {\n          \"value\": \"078\",\n          \"text\": \"Remiser\"\n        },\n        {\n          \"value\": \"079\",\n          \"text\": \"Retailer\"\n        },\n        {\n          \"value\": \"080\",\n          \"text\": \"Retiree\"\n        },\n        {\n          \"value\": \"082\",\n          \"text\": \"Secretary\"\n        },\n        {\n          \"value\": \"083\",\n          \"text\": \"Self-Employed\"\n        },\n        {\n          \"value\": \"084\",\n          \"text\": \"Smallholder\"\n        },\n        {\n          \"value\": \"085\",\n          \"text\": \"Stockbroker\"\n        },\n        {\n          \"value\": \"086\",\n          \"text\": \"Store-Keeper\"\n        },\n        {\n          \"value\": \"087\",\n          \"text\": \"Student\"\n        },\n        {\n          \"value\": \"088\",\n          \"text\": \"Sub-contractor\"\n        },\n        {\n          \"value\": \"090\",\n          \"text\": \"Supplier\"\n        },\n        {\n          \"value\": \"091\",\n          \"text\": \"Tailor/Dressmaker\"\n        },\n        {\n          \"value\": \"094\",\n          \"text\": \"Tourist Guide\"\n        },\n        {\n          \"value\": \"095\",\n          \"text\": \"Trader\"\n        },\n        {\n          \"value\": \"096\",\n          \"text\": \"Valuer\"\n        },\n        {\n          \"value\": \"097\",\n          \"text\": \"Vice President\"\n        },\n        {\n          \"value\": \"098\",\n          \"text\": \"Waiter/Waitress\"\n        },\n        {\n          \"value\": \"099\",\n          \"text\": \"Welder\"\n        },\n        {\n          \"value\": \"100\",\n          \"text\": \"Wholesaler\"\n        },\n        {\n          \"value\": \"101\",\n          \"text\": \"Fisherman\"\n        },\n        {\n          \"value\": \"102\",\n          \"text\": \"Grocer\"\n        },\n        {\n          \"value\": \"104\",\n          \"text\": \"Unemployed\"\n        },\n        {\n          \"value\": \"105\",\n          \"text\": \"Babysitter\"\n        },\n        {\n          \"value\": \"107\",\n          \"text\": \"Sole Proprietor\"\n        },\n        {\n          \"value\": \"108\",\n          \"text\": \"Politician\"\n        },\n        {\n          \"value\": \"109\",\n          \"text\": \"Actor\"\n        },\n        {\n          \"value\": \"110\",\n          \"text\": \"Adjusters\"\n        },\n        {\n          \"value\": \"111\",\n          \"text\": \"Air Hostess\"\n        },\n        {\n          \"value\": \"112\",\n          \"text\": \"Aquaculture\"\n        },\n        {\n          \"value\": \"115\",\n          \"text\": \"Athlete\"\n        },\n        {\n          \"value\": \"116\",\n          \"text\": \"Auctioneer\"\n        },\n        {\n          \"value\": \"117\",\n          \"text\": \"Author\"\n        },\n        {\n          \"value\": \"118\",\n          \"text\": \"Bell Boy\"\n        },\n        {\n          \"value\": \"119\",\n          \"text\": \"Biographer\"\n        },\n        {\n          \"value\": \"120\",\n          \"text\": \"Butcher\"\n        },\n        {\n          \"value\": \"121\",\n          \"text\": \"Catering\"\n        },\n        {\n          \"value\": \"122\",\n          \"text\": \"Chargeman\"\n        },\n        {\n          \"value\": \"123\",\n          \"text\": \"Chemist, Physicist\"\n        },\n        {\n          \"value\": \"124\",\n          \"text\": \"Choreographer/Dancer\"\n        },\n        {\n          \"value\": \"125\",\n          \"text\": \"Circus Performer\"\n        },\n        {\n          \"value\": \"126\",\n          \"text\": \"Civil Servant\"\n        },\n        {\n          \"value\": \"127\",\n          \"text\": \"Clergy\"\n        },\n        {\n          \"value\": \"128\",\n          \"text\": \"Coach\"\n        },\n        {\n          \"value\": \"129\",\n          \"text\": \"Composer\"\n        },\n        {\n          \"value\": \"130\",\n          \"text\": \"Decorator\"\n        },\n        {\n          \"value\": \"131\",\n          \"text\": \"Direct Sales\"\n        },\n        {\n          \"value\": \"132\",\n          \"text\": \"Economist\"\n        },\n        {\n          \"value\": \"133\",\n          \"text\": \"Editor\"\n        },\n        {\n          \"value\": \"135\",\n          \"text\": \"Fireman\"\n        },\n        {\n          \"value\": \"136\",\n          \"text\": \"Fishmonger\"\n        },\n        {\n          \"value\": \"137\",\n          \"text\": \"Florist\"\n        },\n        {\n          \"value\": \"138\",\n          \"text\": \"Forestry\"\n        },\n        {\n          \"value\": \"139\",\n          \"text\": \"Freight Forwarding Services\"\n        },\n        {\n          \"value\": \"140\",\n          \"text\": \"General Worker\"\n        },\n        {\n          \"value\": \"142\",\n          \"text\": \"Hunter\"\n        },\n        {\n          \"value\": \"143\",\n          \"text\": \"Journalist\"\n        },\n        {\n          \"value\": \"144\",\n          \"text\": \"Launderer/Dry Cleaner\"\n        },\n        {\n          \"value\": \"145\",\n          \"text\": \"Librarian/Curator\"\n        },\n        {\n          \"value\": \"146\",\n          \"text\": \"Locksmith\"\n        },\n        {\n          \"value\": \"147\",\n          \"text\": \"Magician\"\n        },\n        {\n          \"value\": \"149\",\n          \"text\": \"Model\"\n        },\n        {\n          \"value\": \"150\",\n          \"text\": \"Newscaster\"\n        },\n        {\n          \"value\": \"151\",\n          \"text\": \"NGO Staff/Volunteer\"\n        },\n        {\n          \"value\": \"152\",\n          \"text\": \"Nursery Worker & Gardener\"\n        },\n        {\n          \"value\": \"154\",\n          \"text\": \"Pharmacist\"\n        },\n        {\n          \"value\": \"155\",\n          \"text\": \"Photographer\"\n        },\n        {\n          \"value\": \"156\",\n          \"text\": \"Postman\"\n        },\n        {\n          \"value\": \"157\",\n          \"text\": \"Priest/Nun\"\n        },\n        {\n          \"value\": \"158\",\n          \"text\": \"Promoter\"\n        },\n        {\n          \"value\": \"159\",\n          \"text\": \"Proof Reader\"\n        },\n        {\n          \"value\": \"160\",\n          \"text\": \"Psychiatrist\"\n        },\n        {\n          \"value\": \"161\",\n          \"text\": \"Psychologist\"\n        },\n        {\n          \"value\": \"162\",\n          \"text\": \"Sailor\"\n        },\n        {\n          \"value\": \"163\",\n          \"text\": \"Security/Bodyguard\"\n        },\n        {\n          \"value\": \"164\",\n          \"text\": \"Shop Assistant\"\n        },\n        {\n          \"value\": \"165\",\n          \"text\": \"Singer\"\n        },\n        {\n          \"value\": \"166\",\n          \"text\": \"Social Worker\"\n        },\n        {\n          \"value\": \"168\",\n          \"text\": \"Town Planner\"\n        },\n        {\n          \"value\": \"169\",\n          \"text\": \"Translator/Interpreter\"\n        },\n        {\n          \"value\": \"170\",\n          \"text\": \"Upholsterer\"\n        },\n        {\n          \"value\": \"171\",\n          \"text\": \"Warden\"\n        },\n        {\n          \"value\": \"172\",\n          \"text\": \"Bank Officer\"\n        },\n        {\n          \"value\": \"175\",\n          \"text\": \"Astronaut/Astronomer/Astrologer\"\n        },\n        {\n          \"value\": \"176\",\n          \"text\": \"President\"\n        },\n        {\n          \"value\": \"200\",\n          \"text\": \"Production and Manufacturing Managers\"\n        },\n        {\n          \"value\": \"201\",\n          \"text\": \"Hospitality, Retail and Other Services Managers\"\n        },\n        {\n          \"value\": \"202\",\n          \"text\": \"Information and Communications Technology Managers\"\n        },\n        {\n          \"value\": \"203\",\n          \"text\": \"Services Managers\"\n        },\n        {\n          \"value\": \"204\",\n          \"text\": \"Meteorologists and Seismologists\"\n        },\n        {\n          \"value\": \"205\",\n          \"text\": \"Geologists and Geophysicists\"\n        },\n        {\n          \"value\": \"206\",\n          \"text\": \"Farming, Forestry and Fisheries Advisers\"\n        },\n        {\n          \"value\": \"207\",\n          \"text\": \"Other Life Science Professionals\"\n        },\n        {\n          \"value\": \"208\",\n          \"text\": \"Landscape Architects\"\n        },\n        {\n          \"value\": \"209\",\n          \"text\": \"Product and Garment Designers\"\n        },\n        {\n          \"value\": \"210\",\n          \"text\": \"Graphic and Multimedia Designers\"\n        },\n        {\n          \"value\": \"211\",\n          \"text\": \"Ships Engineers\"\n        },\n        {\n          \"value\": \"212\",\n          \"text\": \"Aircraft Pilots and Related Professionals\"\n        },\n        {\n          \"value\": \"213\",\n          \"text\": \"Other Ship, Aircraft and Train/Locomotive Controllers\"\n        },\n        {\n          \"value\": \"214\",\n          \"text\": \"University and Higher Education Teachers\"\n        },\n        {\n          \"value\": \"215\",\n          \"text\": \"Vocational Education Teachers\"\n        },\n        {\n          \"value\": \"216\",\n          \"text\": \"Secondary Education Teachers\"\n        },\n        {\n          \"value\": \"217\",\n          \"text\": \"Primary School and Early Childhood Teachers\"\n        },\n        {\n          \"value\": \"218\",\n          \"text\": \"Music, Arts and Performing Arts Teachers\"\n        },\n        {\n          \"value\": \"219\",\n          \"text\": \"Language Teachers\"\n        },\n        {\n          \"value\": \"220\",\n          \"text\": \"Technology Skill and Technical Trainers\"\n        },\n        {\n          \"value\": \"221\",\n          \"text\": \"System Analysts\"\n        },\n        {\n          \"value\": \"222\",\n          \"text\": \"Web and Multimedia Developers\"\n        },\n        {\n          \"value\": \"223\",\n          \"text\": \"Software and Applications Developers and Analysts n.e.c.\"\n        },\n        {\n          \"value\": \"224\",\n          \"text\": \"Database Designers and Administrators\"\n        },\n        {\n          \"value\": \"225\",\n          \"text\": \"Information Technology System Administrators\"\n        },\n        {\n          \"value\": \"226\",\n          \"text\": \"Other Database and Network Professionals\"\n        },\n        {\n          \"value\": \"227\",\n          \"text\": \"Legal Professionals n.e.c.\"\n        },\n        {\n          \"value\": \"228\",\n          \"text\": \"Sociologists, Anthropologists and Related Professionals\"\n        },\n        {\n          \"value\": \"229\",\n          \"text\": \"Philosophers, Historians and Political Scientists\"\n        },\n        {\n          \"value\": \"230\",\n          \"text\": \"Film, Stage and Related Directors and Producers\"\n        },\n        {\n          \"value\": \"231\",\n          \"text\": \"Animals Keepers and Trainers\"\n        },\n        {\n          \"value\": \"232\",\n          \"text\": \"Professional Customs and Border Inspectors\"\n        },\n        {\n          \"value\": \"233\",\n          \"text\": \"Professional Taxation and Excise Officials\"\n        },\n        {\n          \"value\": \"234\",\n          \"text\": \"Professional Government Social Benefits Officials\"\n        },\n        {\n          \"value\": \"235\",\n          \"text\": \"Professional Government Licensing Officials\"\n        },\n        {\n          \"value\": \"236\",\n          \"text\": \"Professional Civil Defence Officials\"\n        },\n        {\n          \"value\": \"237\",\n          \"text\": \"Physical and Engineering Science Technicians\"\n        },\n        {\n          \"value\": \"238\",\n          \"text\": \"Mining, Manufacturing and Construction Supervisors\"\n        },\n        {\n          \"value\": \"239\",\n          \"text\": \"Process Control Technicians\"\n        },\n        {\n          \"value\": \"240\",\n          \"text\": \"Life Science Technicians and Related Associate Professionals\"\n        },\n        {\n          \"value\": \"241\",\n          \"text\": \"Ship, Aircraft and Train Technicians\"\n        },\n        {\n          \"value\": \"242\",\n          \"text\": \"Nuclear Science Associate Professionals\"\n        },\n        {\n          \"value\": \"243\",\n          \"text\": \"Medical and Pharmaceutical Technicians\"\n        },\n        {\n          \"value\": \"244\",\n          \"text\": \"Traditional and Complementary Medicine Associate Professionals\"\n        },\n        {\n          \"value\": \"245\",\n          \"text\": \"Veterinary Technicians and Assistants\"\n        },\n        {\n          \"value\": \"246\",\n          \"text\": \"Dental Assistants and Therapists\"\n        },\n        {\n          \"value\": \"247\",\n          \"text\": \"Medical Records and Health Information Technicians\"\n        },\n        {\n          \"value\": \"248\",\n          \"text\": \"Dispensing Opticians\"\n        },\n        {\n          \"value\": \"249\",\n          \"text\": \"Physiotherapy Technicians and Assistants\"\n        },\n        {\n          \"value\": \"250\",\n          \"text\": \"Medical Assistants\"\n        },\n        {\n          \"value\": \"251\",\n          \"text\": \"Health Associate Professionals Not Elsewhere Classified\"\n        },\n        {\n          \"value\": \"252\",\n          \"text\": \"Statistical, Mathematical and Actuarial Associate Professionals\"\n        },\n        {\n          \"value\": \"253\",\n          \"text\": \"Insurance Agent\"\n        },\n        {\n          \"value\": \"254\",\n          \"text\": \"Commercial Sales Agent\"\n        },\n        {\n          \"value\": \"255\",\n          \"text\": \"Buyers\"\n        },\n        {\n          \"value\": \"256\",\n          \"text\": \"Administrative Associate Professionals\"\n        },\n        {\n          \"value\": \"257\",\n          \"text\": \"Administrative and Executive Secretaries\"\n        },\n        {\n          \"value\": \"258\",\n          \"text\": \"Other Administrative and Specialized Associate Professionals\"\n        },\n        {\n          \"value\": \"259\",\n          \"text\": \"Legal Associate Professionals\"\n        },\n        {\n          \"value\": \"260\",\n          \"text\": \"Social and Religious Associate Professionals\"\n        },\n        {\n          \"value\": \"261\",\n          \"text\": \"Fitness and Recreation Instructors and Program Leaders\"\n        },\n        {\n          \"value\": \"262\",\n          \"text\": \"Gallery, Museum and Library Technicians\"\n        },\n        {\n          \"value\": \"263\",\n          \"text\": \"Cultural Associate Professionals\"\n        },\n        {\n          \"value\": \"264\",\n          \"text\": \"Artistic and Cultural Associate Professionals Not Elsewhere Classified\"\n        },\n        {\n          \"value\": \"265\",\n          \"text\": \"Customs and Border Inspector Associate Professionals\"\n        },\n        {\n          \"value\": \"266\",\n          \"text\": \"Taxation and Excise Official Associate Professionals\"\n        },\n        {\n          \"value\": \"267\",\n          \"text\": \"Government Social Benefit Official Associate Professionals\"\n        },\n        {\n          \"value\": \"268\",\n          \"text\": \"Government Licensing Official Associate Professionals\"\n        },\n        {\n          \"value\": \"269\",\n          \"text\": \"Civil Defence Associate Professionals\"\n        },\n        {\n          \"value\": \"270\",\n          \"text\": \"General Office Clerks\"\n        },\n        {\n          \"value\": \"271\",\n          \"text\": \"Data Entry Clerks\"\n        },\n        {\n          \"value\": \"272\",\n          \"text\": \"Bank Tellers and Related Clerks\"\n        },\n        {\n          \"value\": \"273\",\n          \"text\": \"Travel Consultants and Related Clerks\"\n        },\n        {\n          \"value\": \"274\",\n          \"text\": \"Contact/Call Centre Information Clerks\"\n        },\n        {\n          \"value\": \"275\",\n          \"text\": \"Telephone Switchboard Operators\"\n        },\n        {\n          \"value\": \"276\",\n          \"text\": \"Receptionists\"\n        },\n        {\n          \"value\": \"277\",\n          \"text\": \"Enquiry Clerks\"\n        },\n        {\n          \"value\": \"278\",\n          \"text\": \"Numerical and Material Recording Clerks\"\n        },\n        {\n          \"value\": \"279\",\n          \"text\": \"Transport Conductors\"\n        },\n        {\n          \"value\": \"280\",\n          \"text\": \"Cooks\"\n        },\n        {\n          \"value\": \"281\",\n          \"text\": \"Building and Housekeeping Supervisors\"\n        },\n        {\n          \"value\": \"282\",\n          \"text\": \"Street Food Salespersons\"\n        },\n        {\n          \"value\": \"283\",\n          \"text\": \"Sales Demonstrators\"\n        },\n        {\n          \"value\": \"284\",\n          \"text\": \"Teachers Aide\"\n        },\n        {\n          \"value\": \"285\",\n          \"text\": \"Personal Care Workers in Health Services Not Elsewhere Classified\"\n        },\n        {\n          \"value\": \"286\",\n          \"text\": \"Immigration/Custom Officers and Assistants\"\n        },\n        {\n          \"value\": \"287\",\n          \"text\": \"Protective Services Workers n.e.c.\"\n        },\n        {\n          \"value\": \"288\",\n          \"text\": \"Livestock and Dairy Producers\"\n        },\n        {\n          \"value\": \"289\",\n          \"text\": \"Animal Producers and Related Workers Not Elsewhere Classified\"\n        },\n        {\n          \"value\": \"290\",\n          \"text\": \"Mixed Crop and Animal Producers\"\n        },\n        {\n          \"value\": \"291\",\n          \"text\": \"Subsistence Farmers, Fishermen, Hunters and Gatherers\"\n        },\n        {\n          \"value\": \"292\",\n          \"text\": \"House Builders\"\n        },\n        {\n          \"value\": \"293\",\n          \"text\": \"Air Conditioning and Refrigeration Mechanics\"\n        },\n        {\n          \"value\": \"294\",\n          \"text\": \"Other Building Finishers and Related Trades Workers\"\n        },\n        {\n          \"value\": \"295\",\n          \"text\": \"Spray Painters and Varnishers\"\n        },\n        {\n          \"value\": \"296\",\n          \"text\": \"Building Structure Cleaners\"\n        },\n        {\n          \"value\": \"297\",\n          \"text\": \"Metal Moulders and Coremakers\"\n        },\n        {\n          \"value\": \"298\",\n          \"text\": \"Other Sheet and Structural Metal Workers, Moulders, Welders and Related Workers\"\n        },\n        {\n          \"value\": \"299\",\n          \"text\": \"Metal Working Machine Tool Setters and Operators\"\n        },\n        {\n          \"value\": \"300\",\n          \"text\": \"Aircraft Engine Mechanics and Repairers\"\n        },\n        {\n          \"value\": \"301\",\n          \"text\": \"Agricultural and Industrial Machinery Mechanics and Repairers\"\n        },\n        {\n          \"value\": \"302\",\n          \"text\": \"Bicycle and Related Repairers\"\n        },\n        {\n          \"value\": \"303\",\n          \"text\": \"Machinery Mechanics and Repairers Not Elsewhere Classified\"\n        },\n        {\n          \"value\": \"304\",\n          \"text\": \"Sign Writers, Decorative Painters, Engravers and Etchers\"\n        },\n        {\n          \"value\": \"305\",\n          \"text\": \"Pre-press Workers\"\n        },\n        {\n          \"value\": \"306\",\n          \"text\": \"Other Printing Trades Workers\"\n        },\n        {\n          \"value\": \"307\",\n          \"text\": \"Electrical Mechanics and Fitters\"\n        },\n        {\n          \"value\": \"308\",\n          \"text\": \"Electronics Mechanics and Servicers\"\n        },\n        {\n          \"value\": \"309\",\n          \"text\": \"Information and Communications Technology Installers and Services\"\n        },\n        {\n          \"value\": \"310\",\n          \"text\": \"Other Food Processing and Related Trades Workers\"\n        },\n        {\n          \"value\": \"311\",\n          \"text\": \"Woodworking-Machine Tool Setters and Operators\"\n        },\n        {\n          \"value\": \"312\",\n          \"text\": \"Other Wood Treaters, Cabinet-Makers and Related Trades Workers\"\n        },\n        {\n          \"value\": \"313\",\n          \"text\": \"Other Garment and Related Trades Workers\"\n        },\n        {\n          \"value\": \"314\",\n          \"text\": \"Other Craft and Related Workers\"\n        },\n        {\n          \"value\": \"315\",\n          \"text\": \"Stationary Plant and Machine Operators\"\n        },\n        {\n          \"value\": \"316\",\n          \"text\": \"Mechanical Machinery Assemblers\"\n        },\n        {\n          \"value\": \"317\",\n          \"text\": \"Assemblers Not Elsewhere Classified\"\n        },\n        {\n          \"value\": \"318\",\n          \"text\": \"Machine-Tool Setter-Operators\"\n        },\n        {\n          \"value\": \"319\",\n          \"text\": \"Locomotive Engine Drivers\"\n        },\n        {\n          \"value\": \"320\",\n          \"text\": \"Railway Brake, Signal and Switch Operators\"\n        },\n        {\n          \"value\": \"321\",\n          \"text\": \"Heavy Truck and Bus Drivers\"\n        },\n        {\n          \"value\": \"322\",\n          \"text\": \"Mobile Plant Operators\"\n        },\n        {\n          \"value\": \"323\",\n          \"text\": \"Mining and Construction Labourers\"\n        },\n        {\n          \"value\": \"324\",\n          \"text\": \"Hand and Pedal Vehicle Drivers\"\n        },\n        {\n          \"value\": \"325\",\n          \"text\": \"Animal-Drawn Machinery and Vehicle Drivers\"\n        },\n        {\n          \"value\": \"326\",\n          \"text\": \"Transport and Storage Labourers\"\n        },\n        {\n          \"value\": \"327\",\n          \"text\": \"Shelf Fillers\"\n        },\n        {\n          \"value\": \"328\",\n          \"text\": \"Food Preparation Assistant\"\n        },\n        {\n          \"value\": \"329\",\n          \"text\": \"Street and Related Sales and Services Workers\"\n        },\n        {\n          \"value\": \"330\",\n          \"text\": \"Refuse Workers and Other Elementary Workers\"\n        },\n        {\n          \"value\": \"331\",\n          \"text\": \"Nursing and Midwifery Associate Professionals\"\n        },\n        {\n          \"value\": \"332\",\n          \"text\": \"Police Officers - Protective Service Workers\"\n        },\n        {\n          \"value\": \"333\",\n          \"text\": \"Other Outside Labour Force\"\n        },\n        {\n          \"value\": \"334\",\n          \"text\": \"Financial and Investment Advisers\"\n        },\n        {\n          \"value\": \"335\",\n          \"text\": \"Business Services Agent\"\n        },\n        {\n          \"value\": \"336\",\n          \"text\": \"Health Care Assistants\"\n        },\n        {\n          \"value\": \"337\",\n          \"text\": \"Other Clerical Support Workers\"\n        },\n        {\n          \"value\": \"338\",\n          \"text\": \"Interior Designers and Decorators\"\n        },\n        {\n          \"value\": \"339\",\n          \"text\": \"Software Developers\"\n        },\n        {\n          \"value\": \"340\",\n          \"text\": \"Car, Van and Motorcycle Drivers\"\n        },\n        {\n          \"value\": \"341\",\n          \"text\": \"Engineering Professionals (including Electrotechnology)\"\n        },\n        {\n          \"value\": \"342\",\n          \"text\": \"Driving Instructors\"\n        },\n        {\n          \"value\": \"343\",\n          \"text\": \"Manufacturing Labourers\"\n        },\n        {\n          \"value\": \"344\",\n          \"text\": \"Administrative and Commercial Managers\"\n        },\n        {\n          \"value\": \"345\",\n          \"text\": \"Motor Vehicle Mechanics and Repairers\"\n        },\n        {\n          \"value\": \"346\",\n          \"text\": \"Nursing and Midwifery Professionals\"\n        },\n        {\n          \"value\": \"347\",\n          \"text\": \"Typist and Word Processor Operators\"\n        },\n        {\n          \"value\": \"348\",\n          \"text\": \"Painters and Related Workers\"\n        },\n        {\n          \"value\": \"349\",\n          \"text\": \"Police Officers\"\n        },\n        {\n          \"value\": \"350\",\n          \"text\": \"Stall and Market Salespersons\"\n        },\n        {\n          \"value\": \"351\",\n          \"text\": \"Shop Supervisors\"\n        },\n        {\n          \"value\": \"352\",\n          \"text\": \"Other Teaching Professionals\"\n        },\n        {\n          \"value\": \"353\",\n          \"text\": \"Information and Communications Technicians\"\n        },\n        {\n          \"value\": \"354\",\n          \"text\": \"Ships Deck Officers and Pilots\"\n        },\n        {\n          \"value\": \"355\",\n          \"text\": \"Chefs\"\n        },\n        {\n          \"value\": \"356\",\n          \"text\": \"Building Architects\"\n        },\n        {\n          \"value\": \"357\",\n          \"text\": \"Visual Artists\"\n        },\n        {\n          \"value\": \"358\",\n          \"text\": \"Creative and Performing Artists n.e.c.\"\n        },\n        {\n          \"value\": \"359\",\n          \"text\": \"Regulatory Government Professionals Not Elsewhere Classified\"\n        },\n        {\n          \"value\": \"360\",\n          \"text\": \"Cleaners and Helpers\"\n        },\n        {\n          \"value\": \"361\",\n          \"text\": \"Optometrists and Ophthalmic Opticians\"\n        },\n        {\n          \"value\": \"362\",\n          \"text\": \"Mathematicians, Actuaries and Statisticians\"\n        },\n        {\n          \"value\": \"363\",\n          \"text\": \"Financial Analysts\"\n        },\n        {\n          \"value\": \"364\",\n          \"text\": \"Administrative Professional\"\n        },\n        {\n          \"value\": \"365\",\n          \"text\": \"Other Legislators and Senior Officials\"\n        },\n        {\n          \"value\": \"366\",\n          \"text\": \"Personal Assistant\"\n        }\n      ],\n      \"category\": \"5\"\n    },\n    {\n      \"name\": \"preferredLanguage\",\n      \"displayName\": \"Preferred Language\",\n      \"placeholder\": \"Select Preferred Language\",\n      \"startWithNewLine\": false,\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"01\",\n          \"text\": \"English\"\n        },\n        {\n          \"value\": \" 02\",\n          \"text\": \"Bahasa\"\n        }\n      ],\n      \"category\": \"2\"\n    },\n    {\n      \"name\": \"race\",\n      \"displayName\": \"Race\",\n      \"placeholder\": \"Select Race\",\n      \"type\": \"dropdown\",\n      \"startWithNewLine\": false,\n      \"choices\": [\n        {\n          \"value\": \"01\",\n          \"text\": \"Malaysian - Chinese\"\n        },\n        {\n          \"value\": \"02\",\n          \"text\": \"Malaysian - Bumiputra - Malay\"\n        },\n        {\n          \"value\": \"03\",\n          \"text\": \"Malaysian - Bumiputra - Non Malay\"\n        },\n        {\n          \"value\": \"04\",\n          \"text\": \"Malaysian - Indian\"\n        },\n        {\n          \"value\": \"05\",\n          \"text\": \"Malaysian - Other Race\"\n        }\n      ],\n      \"category\": \"2\"\n    },\n    {\n      \"name\": \"relationshiptoContactName\",\n      \"displayName\": \"Relationship to Contact Name\",\n      \"type\": \"dropdown\",\n      \"placeholder\": \"Relationship to contact Name\",\n      \"choices\": [\n        {\n          \"value\": \"07\",\n          \"text\": \"Father\"\n        },\n        {\n          \"value\": \"08\",\n          \"text\": \"Mother\"\n        },\n        {\n          \"value\": \"09\",\n          \"text\": \"Brother\"\n        },\n        {\n          \"value\": \"10\",\n          \"text\": \"Sister\"\n        },\n        {\n          \"value\": \"11\",\n          \"text\": \"Spouse\"\n        },\n        {\n          \"value\": \"12\",\n          \"text\": \"Son\"\n        },\n        {\n          \"value\": \"13\",\n          \"text\": \"Daughter\"\n        },\n        {\n          \"value\": \"14\",\n          \"text\": \"Uncle\"\n        },\n        {\n          \"value\": \"15\",\n          \"text\": \"Aunt\"\n        },\n        {\n          \"value\": \"40\",\n          \"text\": \"Relative\"\n        }\n      ],\n      \"category\": \"8\"\n    },\n    {\n      \"name\": \"residenceType\",\n      \"displayName\": \"Residence Type\",\n      \"placeholder\": \"Residence Type\",\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"PL0001\",\n          \"text\": \"Own Property\"\n        },\n        {\n          \"value\": \"PL0002\",\n          \"text\": \"Mortgaged\"\n        },\n        {\n          \"value\": \"PL0003\",\n          \"text\": \"Employers\"\n        },\n        {\n          \"value\": \"PL0004\",\n          \"text\": \"Rented\"\n        },\n        {\n          \"value\": \"PL0005\",\n          \"text\": \"Parents\"\n        }\n      ],\n      \"category\": \"2\"\n    },\n    {\n      \"name\": \"salutation\",\n      \"displayName\": \"Salutation\",\n      \"placeholder\": \"Select Salutation\",\n      \"startWithNewLine\": false,\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"002\",\n          \"text\": \"CIK\"\n        },\n        {\n          \"value\": \"004\",\n          \"text\": \"DATIN\"\n        },\n        {\n          \"value\": \"009\",\n          \"text\": \"Datin Seri\"\n        },\n        {\n          \"value\": \"011\",\n          \"text\": \"DATO`\"\n        },\n        {\n          \"value\": \"018\",\n          \"text\": \"DATO SERI\"\n        },\n        {\n          \"value\": \"023\",\n          \"text\": \"DATUK\"\n        },\n        {\n          \"value\": \"028\",\n          \"text\": \"DOCTOR\"\n        },\n        {\n          \"value\": \"033\",\n          \"text\": \"ENCIK\"\n        },\n        {\n          \"value\": \"043\",\n          \"text\": \"DYTM\"\n        },\n        {\n          \"value\": \"053\",\n          \"text\": \"MADAM\"\n        },\n        {\n          \"value\": \"061\",\n          \"text\": \"MISS\"\n        },\n        {\n          \"value\": \"062\",\n          \"text\": \"MR\"\n        },\n        {\n          \"value\": \"072\",\n          \"text\": \"PUAN\"\n        },\n        {\n          \"value\": \"075\",\n          \"text\": \"PUAN SRI\"\n        },\n        {\n          \"value\": \"079\",\n          \"text\": \"TAN SRI\"\n        },\n        {\n          \"value\": \"090\",\n          \"text\": \"Toh Puan\"\n        },\n        {\n          \"value\": \"102\",\n          \"text\": \"YAM\"\n        },\n        {\n          \"value\": \"151\",\n          \"text\": \"DATO SRI\"\n        },\n        {\n          \"value\": \"157\",\n          \"text\": \"TYT TUN DATUK SERI PANGLIMA\"\n        },\n        {\n          \"value\": \"158\",\n          \"text\": \"Ms\"\n        },\n        {\n          \"value\": \"159\",\n          \"text\": \"KDYTM\"\n        }\n      ],\n      \"category\": \"2\"\n    },\n    {\n      \"name\": \"sourceOfWealth\",\n      \"displayName\": \"Source of Wealth\",\n      \"placeholder\": \"Source of Wealth\",\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"01\",\n          \"text\": \"Accumulated Saving\"\n        },\n        {\n          \"value\": \"02\",\n          \"text\": \"Employment income\"\n        },\n        {\n          \"value\": \"03\",\n          \"text\": \"Inheritance\"\n        },\n        {\n          \"value\": \"04\",\n          \"text\": \"Trust Fund\"\n        },\n        {\n          \"value\": \"05\",\n          \"text\": \"Retirement Income\"\n        },\n        {\n          \"value\": \"06\",\n          \"text\": \"EPF\"\n        },\n        {\n          \"value\": \"07\",\n          \"text\": \"Disposal of Assets/Shares\"\n        },\n        {\n          \"value\": \"08\",\n          \"text\": \"Insurance Maturity/Surrender\"\n        },\n        {\n          \"value\": \"09\",\n          \"text\": \"Return on investment\"\n        },\n        {\n          \"value\": \"10\",\n          \"text\": \"Legal Settlement\"\n        },\n        {\n          \"value\": \"11\",\n          \"text\": \"Income from own business\"\n        }\n      ],\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"statementType\",\n      \"displayName\": \"Statement Type\",\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"E\",\n          \"text\": \"Email\"\n        },\n        {\n          \"value\": \"R\",\n          \"text\": \"RHB Now\"\n        }\n      ],\n      \"category\": \"10\"\n    },\n    {\n      \"name\": \"subEmploymentSector\",\n      \"displayName\": \"Sub Employment Sector\",\n      \"placeholder\": \"Select Sub Employment Sector\",\n      \"startWithNewLine\": false,\n      \"visibleIf\": \"{employmentType} anyof ['01', '02', '07', '08', '09', '10' ]\",\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"0011\",\n          \"text\": \"Accounting\"\n        },\n        {\n          \"value\": \"0021\",\n          \"text\": \"Actuarial / Statistic\"\n        },\n        {\n          \"value\": \"0031\",\n          \"text\": \"Advertising\"\n        },\n        {\n          \"value\": \"0032\",\n          \"text\": \"Public Relations\"\n        },\n        {\n          \"value\": \"0041\",\n          \"text\": \"Aerospace\"\n        },\n        {\n          \"value\": \"0051\",\n          \"text\": \"Agricultural / Chemicals / Forest Products\"\n        },\n        {\n          \"value\": \"0052\",\n          \"text\": \"Support activities to agriculture and post-harvest crops activities\"\n        },\n        {\n          \"value\": \"0053\",\n          \"text\": \"Growing paddy, sugar cane, vegetables and melons, roots, tubers, perennial crops\"\n        },\n        {\n          \"value\": \"0054\",\n          \"text\": \"Raising of animals\"\n        },\n        {\n          \"value\": \"0055\",\n          \"text\": \"Mixed farming\"\n        },\n        {\n          \"value\": \"0056\",\n          \"text\": \"Fishing / aquaculture\"\n        },\n        {\n          \"value\": \"0057\",\n          \"text\": \"Plantation (e.g. oil palm, rubber tree, cocoa, coconut etc.)\"\n        },\n        {\n          \"value\": \"0058\",\n          \"text\": \"Silviculture and forestry activities\"\n        },\n        {\n          \"value\": \"0059\",\n          \"text\": \"Veterinary activities\"\n        },\n        {\n          \"value\": \"0061\",\n          \"text\": \"Architecture\"\n        },\n        {\n          \"value\": \"0062\",\n          \"text\": \"Engineering Services\"\n        },\n        {\n          \"value\": \"0063\",\n          \"text\": \"Engineering technical services\"\n        },\n        {\n          \"value\": \"0064\",\n          \"text\": \"Surveying Services\"\n        },\n        {\n          \"value\": \"0071\",\n          \"text\": \"Manufacture of Switchgear and Switchboard Apparatus\"\n        },\n        {\n          \"value\": \"0072\",\n          \"text\": \"Manufacture of Insulated wire and cable\"\n        },\n        {\n          \"value\": \"0073\",\n          \"text\": \"Manufacture of TV radio communication equipment\"\n        },\n        {\n          \"value\": \"0074\",\n          \"text\": \"Manufacture of Typesetting; Platemaking and Related Services\"\n        },\n        {\n          \"value\": \"0075\",\n          \"text\": \"Manufacture of Aircraft and related machinery\"\n        },\n        {\n          \"value\": \"0076\",\n          \"text\": \"Manufacture of Consumer goods & Pharmaceuticals\"\n        },\n        {\n          \"value\": \"0077\",\n          \"text\": \"Manufacture of jewellery, bijouterie & related articles\"\n        },\n        {\n          \"value\": \"0078\",\n          \"text\": \"Manufacture of machinery/ motor vehicles/ other transport equipment\"\n        },\n        {\n          \"value\": \"0079\",\n          \"text\": \"Manufacture of other fabricated metal product\"\n        },\n        {\n          \"value\": \"0081\",\n          \"text\": \"Aviation\"\n        },\n        {\n          \"value\": \"0091\",\n          \"text\": \"Radio, Television, and Consumer Electronics Stores\"\n        },\n        {\n          \"value\": \"0092\",\n          \"text\": \"Retail garments / apparels\"\n        },\n        {\n          \"value\": \"0093\",\n          \"text\": \"Household goods\"\n        },\n        {\n          \"value\": \"0094\",\n          \"text\": \"Furniture stores\"\n        },\n        {\n          \"value\": \"0095\",\n          \"text\": \"Retail sale of Chinaware Glassware\"\n        },\n        {\n          \"value\": \"0096\",\n          \"text\": \"Other retail trade (except for motor vehicle, f&b, health care and grocery)\"\n        },\n        {\n          \"value\": \"0097\",\n          \"text\": \"Other retail sale in non-specialized stores\"\n        },\n        {\n          \"value\": \"0098\",\n          \"text\": \"Retail sale of beer, wine and spirits\"\n        },\n        {\n          \"value\": \"0099\",\n          \"text\": \"Retail sale of tobacco products in specialized store\"\n        },\n        {\n          \"value\": \"0101\",\n          \"text\": \"Radio and Television Repair Shops\"\n        },\n        {\n          \"value\": \"0102\",\n          \"text\": \"Repair Shops and Related Services, N.E.C.;\"\n        },\n        {\n          \"value\": \"0103\",\n          \"text\": \"Refrigeration and Air-Conditioning Service and Repair Shops;\"\n        },\n        {\n          \"value\": \"0104\",\n          \"text\": \"Computer related activities;\"\n        },\n        {\n          \"value\": \"0105\",\n          \"text\": \"Electrical and Electronic Repair Shops, N.E.C\"\n        },\n        {\n          \"value\": \"00110\",\n          \"text\": \"Construction of other civil engineering projects (specialised)\"\n        },\n        {\n          \"value\": \"0111\",\n          \"text\": \"Building Construction\"\n        },\n        {\n          \"value\": \"00111\",\n          \"text\": \"Construction of other civil engineering projects (not specialised)\"\n        },\n        {\n          \"value\": \"00112\",\n          \"text\": \"Electrical, Installation and plumbing\"\n        },\n        {\n          \"value\": \"00113\",\n          \"text\": \"Demolition and site preparation\"\n        },\n        {\n          \"value\": \"00114\",\n          \"text\": \"Construction of utility projects\"\n        },\n        {\n          \"value\": \"0114\",\n          \"text\": \"Construction of Residential house (landed property)\"\n        },\n        {\n          \"value\": \"00115\",\n          \"text\": \"Other specialized construction activities\"\n        },\n        {\n          \"value\": \"0115\",\n          \"text\": \"Construction of other residentials\"\n        },\n        {\n          \"value\": \"00116\",\n          \"text\": \"Roofing, Siding, and Sheet Metal Work\"\n        },\n        {\n          \"value\": \"0116\",\n          \"text\": \"Construction of industrial building & factories\"\n        },\n        {\n          \"value\": \"00117\",\n          \"text\": \"Water, Sewer, Pipeline, and Communications and Power Line Construction\"\n        },\n        {\n          \"value\": \"0117\",\n          \"text\": \"Construction of office buildings\"\n        },\n        {\n          \"value\": \"00118\",\n          \"text\": \"Assembly and erection of prefabricated constructions on the site\"\n        },\n        {\n          \"value\": \"0118\",\n          \"text\": \"Construction of commercial complex\"\n        },\n        {\n          \"value\": \"0119\",\n          \"text\": \"Construction of infrastructure\"\n        },\n        {\n          \"value\": \"00119\",\n          \"text\": \"Construction of hotels\"\n        },\n        {\n          \"value\": \"00120\",\n          \"text\": \"Construction of condominiums/apartments\"\n        },\n        {\n          \"value\": \"0121\",\n          \"text\": \"Creative / Graphics\"\n        },\n        {\n          \"value\": \"0131\",\n          \"text\": \"Customer Service\"\n        },\n        {\n          \"value\": \"0141\",\n          \"text\": \"Higher Education with significant reliance on foreign/international students\"\n        },\n        {\n          \"value\": \"0142\",\n          \"text\": \"Higher Education with no significant reliance on foreign students\"\n        },\n        {\n          \"value\": \"0143\",\n          \"text\": \"Administration of the State and the economic and social policy of the community\"\n        },\n        {\n          \"value\": \"0144\",\n          \"text\": \"Public - Pre school, primary and secondary level education\"\n        },\n        {\n          \"value\": \"0145\",\n          \"text\": \"Private - Pre school, primary and secondary level education\"\n        },\n        {\n          \"value\": \"0151\",\n          \"text\": \"O&G - Upstream i.e. drilling, extraction, exploration and field services\"\n        },\n        {\n          \"value\": \"0152\",\n          \"text\": \"O&G - Other than Upstream\"\n        },\n        {\n          \"value\": \"0153\",\n          \"text\": \"Mining of iron ores and other non-ferrous metal ores\"\n        },\n        {\n          \"value\": \"0154\",\n          \"text\": \"Stonequarrying, clay & sand pits\"\n        },\n        {\n          \"value\": \"155\",\n          \"text\": \"Chemical & fertilizer mining\"\n        },\n        {\n          \"value\": \"0155\",\n          \"text\": \"Chemical & fertiliser mining\"\n        },\n        {\n          \"value\": \"156\",\n          \"text\": \"Other than oil and gas\"\n        },\n        {\n          \"value\": \"0156\",\n          \"text\": \"Other than oil and gas\"\n        },\n        {\n          \"value\": \"161\",\n          \"text\": \"Engineering Services & Engineering Technical Services\"\n        },\n        {\n          \"value\": \"0161\",\n          \"text\": \"Engineering Services & Engineering Technical Services\"\n        },\n        {\n          \"value\": \"171\",\n          \"text\": \"Banking services\"\n        },\n        {\n          \"value\": \"0171\",\n          \"text\": \"Banking services\"\n        },\n        {\n          \"value\": \"172\",\n          \"text\": \"Finance services\"\n        },\n        {\n          \"value\": \"0172\",\n          \"text\": \"Finance services\"\n        },\n        {\n          \"value\": \"0173\",\n          \"text\": \"Insurance services\"\n        },\n        {\n          \"value\": \"173\",\n          \"text\": \"Insurance services\"\n        },\n        {\n          \"value\": \"0174\",\n          \"text\": \"Money lenders / Money Changers/ Remittance Services/ Money Transmitter/ Check Cashing Business/ Currency Exchange\"\n        },\n        {\n          \"value\": \"0175\",\n          \"text\": \"Pawnshop\"\n        },\n        {\n          \"value\": \"0176\",\n          \"text\": \"Activity of holding companies\"\n        },\n        {\n          \"value\": \"0177\",\n          \"text\": \"Financial leasing activities\"\n        },\n        {\n          \"value\": \"0178\",\n          \"text\": \"Finance - credit card services\"\n        },\n        {\n          \"value\": \"0179\",\n          \"text\": \"Consultancy services\"\n        },\n        {\n          \"value\": \"0181\",\n          \"text\": \"Freight Forwarding Services\"\n        },\n        {\n          \"value\": \"0191\",\n          \"text\": \"Government\"\n        },\n        {\n          \"value\": \"0192\",\n          \"text\": \"Public Service\"\n        },\n        {\n          \"value\": \"0193\",\n          \"text\": \"Military\"\n        },\n        {\n          \"value\": \"0201\",\n          \"text\": \"Tourism & Hospitality\"\n        },\n        {\n          \"value\": \"0202\",\n          \"text\": \"Recreational related services / activities\"\n        },\n        {\n          \"value\": \"0211\",\n          \"text\": \"Food Service Activities\"\n        },\n        {\n          \"value\": \"0212\",\n          \"text\": \"Organization Hotel, Lodging Houses, chalet, rest house, homestay, Inn, motels, rooming sporting, and recreational camp\"\n        },\n        {\n          \"value\": \"0213\",\n          \"text\": \"Other short term accommodation not mentioned above\"\n        },\n        {\n          \"value\": \"0214\",\n          \"text\": \"Restaurants, bars and canteens\"\n        },\n        {\n          \"value\": \"0215\",\n          \"text\": \"Restaurant, bar (other discretionary items and significant reliance on dine-in)\"\n        },\n        {\n          \"value\": \"0216\",\n          \"text\": \"Event catering and other food service activities\"\n        },\n        {\n          \"value\": \"0217\",\n          \"text\": \"Eating Places, Except Food Service, Institutional\"\n        },\n        {\n          \"value\": \"0221\",\n          \"text\": \"Human Resources\"\n        },\n        {\n          \"value\": \"0231\",\n          \"text\": \"Investment advisory services\"\n        },\n        {\n          \"value\": \"0241\",\n          \"text\": \"Journalist / Editor\"\n        },\n        {\n          \"value\": \"0251\",\n          \"text\": \"Motion picture, video and television programme production, sound recording and music publishing activities\"\n        },\n        {\n          \"value\": \"0252\",\n          \"text\": \"Programming and broadcasting activities\"\n        },\n        {\n          \"value\": \"0253\",\n          \"text\": \"News agency activities\"\n        },\n        {\n          \"value\": \"0254\",\n          \"text\": \"Media, culture and recreational activities\"\n        },\n        {\n          \"value\": \"0261\",\n          \"text\": \"Medical / Health Services\"\n        },\n        {\n          \"value\": \"0262\",\n          \"text\": \"Kidney Dialysis Centers\"\n        },\n        {\n          \"value\": \"0263\",\n          \"text\": \"Intermediate Care Facilities\"\n        },\n        {\n          \"value\": \"0264\",\n          \"text\": \"Home Health Care Services Facilities\"\n        },\n        {\n          \"value\": \"0271\",\n          \"text\": \"Non-Profit Organization\"\n        },\n        {\n          \"value\": \"0281\",\n          \"text\": \"Geology\"\n        },\n        {\n          \"value\": \"0291\",\n          \"text\": \"Pharmaceuticals products\"\n        },\n        {\n          \"value\": \"0301\",\n          \"text\": \"Real estate operations - shopping complex\"\n        },\n        {\n          \"value\": \"0302\",\n          \"text\": \"Appraisal services for real estate\"\n        },\n        {\n          \"value\": \"0303\",\n          \"text\": \"Real estate activities on a fee or contract basis\"\n        },\n        {\n          \"value\": \"0304\",\n          \"text\": \"Buying, selling, renting and operating of residential buildings or land\"\n        },\n        {\n          \"value\": \"0305\",\n          \"text\": \"Real estate operations - shophouse\"\n        },\n        {\n          \"value\": \"0306\",\n          \"text\": \"Real estate Operation - Industrial building & factories\"\n        },\n        {\n          \"value\": \"0307\",\n          \"text\": \"Real estate Operation - office building\"\n        },\n        {\n          \"value\": \"0308\",\n          \"text\": \"Real estate Operation - other commercial building\"\n        },\n        {\n          \"value\": \"0309\",\n          \"text\": \"Real estate operation not related above\"\n        },\n        {\n          \"value\": \"0311\",\n          \"text\": \"Administrative and Support Service Activities\"\n        },\n        {\n          \"value\": \"0321\",\n          \"text\": \"Social Work Activites\"\n        },\n        {\n          \"value\": \"0331\",\n          \"text\": \"Wired / Wireless telecommunications activities\"\n        },\n        {\n          \"value\": \"0341\",\n          \"text\": \"Tour operators\"\n        },\n        {\n          \"value\": \"0342\",\n          \"text\": \"Travel Agencies\"\n        },\n        {\n          \"value\": \"0351\",\n          \"text\": \"Rail transport\"\n        },\n        {\n          \"value\": \"0352\",\n          \"text\": \"Transportation Services, N.E.C.\"\n        },\n        {\n          \"value\": \"0353\",\n          \"text\": \"Service activities incidental to land / road transportation\"\n        },\n        {\n          \"value\": \"0354\",\n          \"text\": \"Scheduled and Non-Scheduled Air Transport (Transport of passengers by air over regular routes and on regular schedules)\"\n        },\n        {\n          \"value\": \"0355\",\n          \"text\": \"Aircrafts, Aircraft engine / parts, space vehicles\"\n        },\n        {\n          \"value\": \"0356\",\n          \"text\": \"Tanks and Tank components\"\n        },\n        {\n          \"value\": \"0357\",\n          \"text\": \"Warehousing and storage\"\n        },\n        {\n          \"value\": \"0358\",\n          \"text\": \"Water transport\"\n        },\n        {\n          \"value\": \"0359\",\n          \"text\": \"Other transportation support activities n.e.c. (e.g. arranging transportation services, terminal maintenance services, etc)\"\n        },\n        {\n          \"value\": \"0361\",\n          \"text\": \"Casinos including Junket Operators\"\n        },\n        {\n          \"value\": \"0362\",\n          \"text\": \"Karaoke lounges, internet cafe or video arcade\"\n        },\n        {\n          \"value\": \"0363\",\n          \"text\": \"Amusement and Recreation Services\"\n        },\n        {\n          \"value\": \"0364\",\n          \"text\": \"Membership Sports and Recreation Clubs\"\n        },\n        {\n          \"value\": \"0365\",\n          \"text\": \"Entertainment services\"\n        },\n        {\n          \"value\": \"0366\",\n          \"text\": \"Arts & Theatrical\"\n        },\n        {\n          \"value\": \"0371\",\n          \"text\": \"Electricty power generation\"\n        },\n        {\n          \"value\": \"0372\",\n          \"text\": \"Steam and air conditioning supply\"\n        },\n        {\n          \"value\": \"0373\",\n          \"text\": \"Water collection, treatment and supply\"\n        },\n        {\n          \"value\": \"0381\",\n          \"text\": \"Water Supply\"\n        },\n        {\n          \"value\": \"0382\",\n          \"text\": \"Sewerage\"\n        },\n        {\n          \"value\": \"0383\",\n          \"text\": \"Waste Management and Remediation Activities\"\n        },\n        {\n          \"value\": \"0384\",\n          \"text\": \"Recycling of non-metal (including rubber & textile fibre)\"\n        },\n        {\n          \"value\": \"0385\",\n          \"text\": \"Recycling of tin and other metal waste and scrap\"\n        },\n        {\n          \"value\": \"0391\",\n          \"text\": \"Activities of Households as Employers; Undifferentiated Goods and Services Producing Activities of Households for Own Use\"\n        },\n        {\n          \"value\": \"0401\",\n          \"text\": \"Activities of Extraterritorial Organisations and Bodies\"\n        },\n        {\n          \"value\": \"0411\",\n          \"text\": \"Unemployed/ Outside Labour Force\"\n        },\n        {\n          \"value\": \"0421\",\n          \"text\": \"Activities of membership organisations (Political/Religious/Trade Union)\"\n        },\n        {\n          \"value\": \"0422\",\n          \"text\": \"International Business Corporations and other similar entities\"\n        },\n        {\n          \"value\": \"0423\",\n          \"text\": \"Business Activities - Intermediary activities - trustee/ nominee/ agent  OR Shell Companies\"\n        },\n        {\n          \"value\": \"0424\",\n          \"text\": \"Other Services\"\n        },\n        {\n          \"value\": \"0425\",\n          \"text\": \"Offshore Corporations (or their subsidiaries) and bank set up in tax and/or secrecy havens\"\n        },\n        {\n          \"value\": \"0426\",\n          \"text\": \"Building Cleaning and Maintenance Services, N.E.C.\"\n        },\n        {\n          \"value\": \"0427\",\n          \"text\": \"Detective, Guard, and Armored Car Services\"\n        },\n        {\n          \"value\": \"0428\",\n          \"text\": \"Rental, Leasing and Packaging ( tour operator, reservation services and related activities, Organisation of conventions and trade shows)\"\n        },\n        {\n          \"value\": \"0429\",\n          \"text\": \"Funeral Service and Crematories\"\n        },\n        {\n          \"value\": \"0431\",\n          \"text\": \"Legal Services\"\n        },\n        {\n          \"value\": \"0441\",\n          \"text\": \"Research & Experiemental Development Services\"\n        },\n        {\n          \"value\": \"0451\",\n          \"text\": \"Other Professional, scientific and Technical activities\"\n        },\n        {\n          \"value\": \"00510\",\n          \"text\": \"Hunting, trapping and related service activities\"\n        },\n        {\n          \"value\": \"00511\",\n          \"text\": \"Logging\"\n        },\n        {\n          \"value\": \"00710\",\n          \"text\": \"Manufacture of watches and clocks\"\n        },\n        {\n          \"value\": \"0711\",\n          \"text\": \"Manufacture of others\"\n        },\n        {\n          \"value\": \"00711\",\n          \"text\": \"Manufacture of others\"\n        },\n        {\n          \"value\": \"0712\",\n          \"text\": \"Maintenance and repair of motor vehicles\"\n        },\n        {\n          \"value\": \"00712\",\n          \"text\": \"Maintenance and repair of motor vehicles\"\n        },\n        {\n          \"value\": \"0713\",\n          \"text\": \"Manufacture of furniture\"\n        },\n        {\n          \"value\": \"00713\",\n          \"text\": \"Manufacture of furniture\"\n        },\n        {\n          \"value\": \"0714\",\n          \"text\": \"Manufacture of packaging and stretch film\"\n        },\n        {\n          \"value\": \"00714\",\n          \"text\": \"Manufacture of packaging and stretch film\"\n        },\n        {\n          \"value\": \"0715\",\n          \"text\": \"Manufacture of plastic product\"\n        },\n        {\n          \"value\": \"00715\",\n          \"text\": \"Manufacture of plastic product\"\n        },\n        {\n          \"value\": \"0716\",\n          \"text\": \"Manufacture of rubber product\"\n        },\n        {\n          \"value\": \"00716\",\n          \"text\": \"Manufacture of rubber product\"\n        },\n        {\n          \"value\": \"00717\",\n          \"text\": \"Manufacture of processed food or beverages products\"\n        },\n        {\n          \"value\": \"0717\",\n          \"text\": \"Manufacture of processed food or beverages products\"\n        },\n        {\n          \"value\": \"00718\",\n          \"text\": \"Manufacture of wood product except furniture\"\n        },\n        {\n          \"value\": \"0718\",\n          \"text\": \"Manufacture of wood product except furniture\"\n        },\n        {\n          \"value\": \"00719\",\n          \"text\": \"Manufacture of refined petroleum products\"\n        },\n        {\n          \"value\": \"0719\",\n          \"text\": \"Manufacture of refined petroleum products\"\n        },\n        {\n          \"value\": \"00720\",\n          \"text\": \"Manufacture of chemicals and chemical products (except for refined petroleum products)\"\n        },\n        {\n          \"value\": \"0720\",\n          \"text\": \"Manufacture of chemicals and chemical products (except for refined petroleum products)\"\n        },\n        {\n          \"value\": \"00721\",\n          \"text\": \"Manufacture of electrical equipment or components\"\n        },\n        {\n          \"value\": \"00722\",\n          \"text\": \"Manufacture of dairy food\"\n        },\n        {\n          \"value\": \"00723\",\n          \"text\": \"Manufacture of grain mills\"\n        },\n        {\n          \"value\": \"00724\",\n          \"text\": \"Manufacture of other food product (except dairy food and grain mills, starches and starch products)\"\n        },\n        {\n          \"value\": \"00725\",\n          \"text\": \"Manufacture of vegetable and animal oils and fats\"\n        },\n        {\n          \"value\": \"00726\",\n          \"text\": \"Manufacture of textiles\"\n        },\n        {\n          \"value\": \"00727\",\n          \"text\": \"Manufacture of footwear\"\n        },\n        {\n          \"value\": \"00728\",\n          \"text\": \"Manufacture of building materials\"\n        },\n        {\n          \"value\": \"00729\",\n          \"text\": \"Manufacture of glass and glass products\"\n        },\n        {\n          \"value\": \"00730\",\n          \"text\": \"Manufacture of mineral products\"\n        },\n        {\n          \"value\": \"00731\",\n          \"text\": \"Manufacture of medical and dental instruments and supplies\"\n        },\n        {\n          \"value\": \"00732\",\n          \"text\": \"Manufacturing of automobile or autopart\"\n        },\n        {\n          \"value\": \"00733\",\n          \"text\": \"Manufacture of paper and paper products\"\n        },\n        {\n          \"value\": \"00734\",\n          \"text\": \"Manufacture of gas and distribution of gaseous fuels through mains\"\n        },\n        {\n          \"value\": \"00735\",\n          \"text\": \"Manufacture of fertiliser pesticides\"\n        },\n        {\n          \"value\": \"00736\",\n          \"text\": \"Production of natural mineral water and other bottled water\"\n        },\n        {\n          \"value\": \"00901\",\n          \"text\": \"Retail trade not in stores, stalls or markets\"\n        },\n        {\n          \"value\": \"00902\",\n          \"text\": \"Retail sale via stalls and markets\"\n        },\n        {\n          \"value\": \"00903\",\n          \"text\": \"Wholesale of beer, wine and spirits\"\n        },\n        {\n          \"value\": \"00904\",\n          \"text\": \"Wholesale of tobacco, cigar, cigarettes\"\n        },\n        {\n          \"value\": \"00905\",\n          \"text\": \"Wholesale of construction and civil engineering machinery and equipment\"\n        },\n        {\n          \"value\": \"00906\",\n          \"text\": \"Wholesale of other machinery for use in industry, trade and navigation and other services n.e.c.\"\n        },\n        {\n          \"value\": \"00907\",\n          \"text\": \"Motor Vehicle dealer (Used)\"\n        },\n        {\n          \"value\": \"00908\",\n          \"text\": \"Jewel / Gem / Precious Metal\"\n        },\n        {\n          \"value\": \"00909\",\n          \"text\": \"Automobile and autoparts\"\n        },\n        {\n          \"value\": \"00910\",\n          \"text\": \"Hardware / construction material\"\n        },\n        {\n          \"value\": \"00911\",\n          \"text\": \"Electrical products\"\n        },\n        {\n          \"value\": \"00912\",\n          \"text\": \"Chemical / Petrochemical\"\n        },\n        {\n          \"value\": \"00913\",\n          \"text\": \"Cosmetics\"\n        },\n        {\n          \"value\": \"00914\",\n          \"text\": \"Import / Export\"\n        },\n        {\n          \"value\": \"00915\",\n          \"text\": \"Medical related products\"\n        },\n        {\n          \"value\": \"00916\",\n          \"text\": \"Automatic Merchandising Machine Operators\"\n        },\n        {\n          \"value\": \"00917\",\n          \"text\": \"Direct Selling Establishments\"\n        },\n        {\n          \"value\": \"00918\",\n          \"text\": \"Liquefied Petroleum Gas (Bottled Gas) Dealers\"\n        },\n        {\n          \"value\": \"00919\",\n          \"text\": \"Motor Vehicle Dealers (New )\"\n        },\n        {\n          \"value\": \"00920\",\n          \"text\": \"Office equipment\"\n        },\n        {\n          \"value\": \"00921\",\n          \"text\": \"Stationery, books, periodical and newspapers\"\n        },\n        {\n          \"value\": \"00922\",\n          \"text\": \"Retail - Petrol Station\"\n        },\n        {\n          \"value\": \"00923\",\n          \"text\": \"Retail / wholesaler other than above\"\n        },\n        {\n          \"value\": \"01700\",\n          \"text\": \"Other monetary intermediation\"\n        },\n        {\n          \"value\": \"1700\",\n          \"text\": \"Other monetary intermediation\"\n        },\n        {\n          \"value\": \"01701\",\n          \"text\": \"Research & Experiemental Development Services\"\n        },\n        {\n          \"value\": \"1701\",\n          \"text\": \"Research & Experimental Development Services\"\n        },\n        {\n          \"value\": \"01702\",\n          \"text\": \"licensed money lending activities, co-operative with credit functions and factoring companies\"\n        },\n        {\n          \"value\": \"1702\",\n          \"text\": \"licensed money lending activities, co-operative with credit functions and factoring companies\"\n        },\n        {\n          \"value\": \"03510\",\n          \"text\": \"Postal and courier activities\"\n        },\n        {\n          \"value\": \"04201\",\n          \"text\": \"Beauty Shops\"\n        },\n        {\n          \"value\": \"04202\",\n          \"text\": \"Barber Shops\"\n        },\n        {\n          \"value\": \"04203\",\n          \"text\": \"Libraries, archives, museums and other cultural activities\"\n        },\n        {\n          \"value\": \"04204\",\n          \"text\": \"Reupholstery and Furniture Repair\"\n        },\n        {\n          \"value\": \"04205\",\n          \"text\": \"Armature Rewinding Shops\"\n        },\n        {\n          \"value\": \"04206\",\n          \"text\": \"Welding Repair\"\n        },\n        {\n          \"value\": \"04207\",\n          \"text\": \"Maintenance and repair of motor vehicles\"\n        },\n        {\n          \"value\": \"04208\",\n          \"text\": \"Renting and leasing of motor vehicle, household good, machinery, equipment and tangible goods\"\n        },\n        {\n          \"value\": \"04209\",\n          \"text\": \"Business management consultancy services\"\n        },\n        {\n          \"value\": \"04210\",\n          \"text\": \"Activties of  collection agencies / credit bureaus\"\n        },\n        {\n          \"value\": \"04211\",\n          \"text\": \"Repair of bicycles\"\n        },\n        {\n          \"value\": \"04212\",\n          \"text\": \"Repair of footwear and other leather goods\"\n        }\n      ],\n      \"category\": \"5\"\n    },\n    {\n      \"name\": \"dateApplied\",\n      \"displayName\": \"Date Applied\",\n      \"type\": \"text\",\n      \"inputType\": \"date\",\n      \"category\": \"11\"\n    },\n    {\n      \"name\": \"entity\",\n      \"displayName\": \"Entity\",\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"C\",\n          \"text\": \"Conventional\"\n        },\n        {\n          \"value\": \"I\",\n          \"text\": \"Islamic\"\n        }\n      ],\n      \"category\": \"10\"\n    },\n    {\n      \"name\": \"facilityPackage\",\n      \"displayName\": \"Facility Package\",\n      \"type\": \"text\",\n      \"category\": \"11\"\n    },\n    {\n      \"name\": \"purposeOfAcquisition\",\n      \"displayName\": \"Purpose of Acquisition\",\n      \"placeholder\": \"Select your Purpose of Acquisition\",\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"Internal Use\",\n          \"text\": \"Internal Use\"\n        },\n        {\n          \"value\": \"Tender\",\n          \"text\": \"Tender\"\n        },\n        {\n          \"value\": \"Service\",\n          \"text\": \"Service\"\n        }\n      ],\n      \"category\": \"11\"\n    },\n    {\n      \"name\": \"facilityPurpose\",\n      \"displayName\": \"Facility Purpose\",\n      \"type\": \"dropdown\",\n      \"defaultValue\": \"Refinancing of property\",\n      \"choices\": [\n        {\n          \"value\": \"01\",\n          \"text\": \"Staff ASB - Untuk Kegunaan Sendiri dalam Pelaburan ASB\"\n        },\n        {\n          \"value\": \"02\",\n          \"text\": \"ASB - Untuk Kegunaan Sendiri dalam pelaburan ASB\"\n        },\n        {\n          \"value\": \"002\",\n          \"text\": \"Finance purchase of property/land for INVESTMENT.\"\n        },\n        {\n          \"value\": \"03\",\n          \"text\": \"ASB2 - Untuk Kegunaan Sendiri dalam Pelaburan ASB2\"\n        },\n        {\n          \"value\": \"003\",\n          \"text\": \"Finance purchase of prop/land for own occupation\"\n        },\n        {\n          \"value\": \"04\",\n          \"text\": \"Personal Consumption Against ASB/ASM2W Certificate\"\n        },\n        {\n          \"value\": \"05\",\n          \"text\": \"ASB/ASM2W for Sole-prop Business\"\n        },\n        {\n          \"value\": \"005\",\n          \"text\": \"Personal consumption\"\n        },\n        {\n          \"value\": \"008\",\n          \"text\": \"Construction of property\"\n        },\n        {\n          \"value\": \"010\",\n          \"text\": \"Purchase of property for INVESTMENT & consumption.\"\n        },\n        {\n          \"value\": \"013\",\n          \"text\": \"Purchase of car park\"\n        },\n        {\n          \"value\": \"015\",\n          \"text\": \"To finance renovation/upgrading cost\"\n        },\n        {\n          \"value\": \"016\",\n          \"text\": \"To part finance Car Park and Renovation Cost\"\n        },\n        {\n          \"value\": \"018\",\n          \"text\": \"Staff - Renovation of property under staff rate\"\n        },\n        {\n          \"value\": \"023\",\n          \"text\": \"Refinancing of property\"\n        },\n        {\n          \"value\": \"026\",\n          \"text\": \"Staff Sundry Loan - Calamities\"\n        },\n        {\n          \"value\": \"027\",\n          \"text\": \"Staff-To part finance Medical Expenses\"\n        },\n        {\n          \"value\": \"028\",\n          \"text\": \"Staff-To part finance the purchase of a personal computer\"\n        },\n        {\n          \"value\": \"029\",\n          \"text\": \"Staff-Purchase of new car\"\n        },\n        {\n          \"value\": \"030\",\n          \"text\": \"Staff- study loan\"\n        },\n        {\n          \"value\": \"031\",\n          \"text\": \"Staff-Purchase of motorcycle\"\n        },\n        {\n          \"value\": \"036\",\n          \"text\": \"Staff-Staff Sundry loan\"\n        },\n        {\n          \"value\": \"037\",\n          \"text\": \"Booking Fee - Car\"\n        },\n        {\n          \"value\": \"038\",\n          \"text\": \"Debt Consolidation\"\n        },\n        {\n          \"value\": \"039\",\n          \"text\": \"Education\"\n        },\n        {\n          \"value\": \"040\",\n          \"text\": \"Electrical Goods\"\n        },\n        {\n          \"value\": \"041\",\n          \"text\": \"Home Furnishing/Equipment\"\n        },\n        {\n          \"value\": \"042\",\n          \"text\": \"Medical Expenses\"\n        },\n        {\n          \"value\": \"043\",\n          \"text\": \"Online Financing\"\n        },\n        {\n          \"value\": \"044\",\n          \"text\": \"Personal Refinancing\"\n        },\n        {\n          \"value\": \"045\",\n          \"text\": \"Property/House Downpayment\"\n        },\n        {\n          \"value\": \"046\",\n          \"text\": \"Renovation\"\n        },\n        {\n          \"value\": \"047\",\n          \"text\": \"Travel\"\n        },\n        {\n          \"value\": \"048\",\n          \"text\": \"Additional Financing for Revival of Abandoned Project\"\n        },\n        {\n          \"value\": \"100\",\n          \"text\": \"Purchase of Resident / Non Resident Property for personal purpose\"\n        },\n        {\n          \"value\": \"101\",\n          \"text\": \"Purchase of securities quoted on the Bursa Malaysia and/or financing of IPO shares\"\n        },\n        {\n          \"value\": \"102\",\n          \"text\": \"Purchase of securities quoted on the Bursa Malaysia and/or financing of IPO shares\"\n        },\n        {\n          \"value\": \"COM01AF\",\n          \"text\": \"PURCHASE OF COMMERCIAL VEHICLES\"\n        },\n        {\n          \"value\": \"PRI01AF\",\n          \"text\": \"PURCHASE OF PRIVATE VEHICLES\"\n        }\n      ],\n      \"category\": \"11\"\n    },\n    {\n      \"name\": \"facilityType\",\n      \"displayName\": \"Facility Type (Personal)\",\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"PLFT001\",\n          \"text\": \"Conventional\"\n        },\n        {\n          \"value\": \"PLFT002\",\n          \"text\": \"Private Sector\"\n        }\n      ],\n      \"category\": \"11\"\n    },\n    {\n      \"name\": \"facilityType\",\n      \"displayName\": \"Facility Type (Auto)\",\n      \"placeholder\": \"Facility Type\",\n      \"startWithNewLine\": false,\n      \"visible\": false,\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"HPFAC04\",\n          \"text\": \" Islamic - Variable rate\"\n        }\n      ],\n      \"category\": \"11\"\n    },\n    {\n      \"name\": \"financingTenure\",\n      \"displayName\": \"Financing Tenure (Years)\",\n      \"placeholder\": \"Financing Tenure (Years)\",\n      \"startWithNewLine\": false,\n      \"type\": \"text\",\n      \"maxLength\": 3,\n      \"min\": 1,\n      \"max\": 7,\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"text\": \"Please enter a valid financing tenure from 1 to 7 years.\",\n          \"regex\": \"^[1-7]$\"\n        }\n      ],\n      \"inputType\": \"number\",\n      \"category\": \"11\"\n    },\n    {\n      \"name\": \"product\",\n      \"displayName\": \"Product (Auto)\",\n      \"placeholder\": \"Product\",\n      \"startWithNewLine\": false,\n      \"visible\": false,\n      \"isRequired\": true,\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"AFI04\",\n          \"text\": \"Vehicle Financing-i (Variable Rate SBR)\"\n        }\n      ],\n      \"maxLength\": 40,\n      \"category\": \"11\"\n    },\n    {\n      \"name\": \"purposeOfAcctOpen\",\n      \"displayName\": \"Purpose of Account Opening\",\n      \"type\": \"dropdown\",\n      \"defaultValue\": \"Personal Loan/Financing\",\n      \"choices\": [\n        {\n          \"value\": \"01\",\n          \"text\": \"Payroll/Salary\"\n        },\n        {\n          \"value\": \"03\",\n          \"text\": \"Savings/Fixed/Term Deposits\"\n        },\n        {\n          \"value\": \"04\",\n          \"text\": \"Remittance (Local/Foreign)\"\n        },\n        {\n          \"value\": \"05\",\n          \"text\": \"Household/Family Expenses\"\n        },\n        {\n          \"value\": \"06\",\n          \"text\": \"Investment\"\n        },\n        {\n          \"value\": \"08\",\n          \"text\": \"Standing Instruction\"\n        },\n        {\n          \"value\": \"11\",\n          \"text\": \"EPF Withdrawals\"\n        },\n        {\n          \"value\": \"12\",\n          \"text\": \"Personal Loan/Financing\"\n        },\n        {\n          \"value\": \"14\",\n          \"text\": \"Equipment & Machinery Expenses\"\n        },\n        {\n          \"value\": \"15\",\n          \"text\": \"Business Operating Account\"\n        },\n        {\n          \"value\": \"16\",\n          \"text\": \"Client's Account\"\n        },\n        {\n          \"value\": \"17\",\n          \"text\": \"Sales Proceed\"\n        },\n        {\n          \"value\": \"18\",\n          \"text\": \"Capital Injection\"\n        },\n        {\n          \"value\": \"19\",\n          \"text\": \"Administration of Estate Account\"\n        },\n        {\n          \"value\": \"20\",\n          \"text\": \"Liquidation/Disposal of Asset\"\n        },\n        {\n          \"value\": \"21\",\n          \"text\": \"Financing Payment/Drawdown\"\n        }\n      ],\n      \"category\": \"11\"\n    },\n    {\n      \"name\": \"sourceOfFund\",\n      \"displayName\": \"Source of Fund\",\n      \"placeholder\": \"Source of Fund\",\n      \"startWithNewLine\": false,\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"01\",\n          \"text\": \"Income/Salary\"\n        },\n        {\n          \"value\": \"02\",\n          \"text\": \"Own Bank Transfer (within RHB)\"\n        },\n        {\n          \"value\": \"04\",\n          \"text\": \"EPF/SOCSO/Pension/Gratuity\"\n        },\n        {\n          \"value\": \"05\",\n          \"text\": \"Savings/Investment\"\n        },\n        {\n          \"value\": \"08\",\n          \"text\": \"Scholarship/Allowance/Edu Loan\"\n        },\n        {\n          \"value\": \"13\",\n          \"text\": \"Trust Funds\"\n        },\n        {\n          \"value\": \"15\",\n          \"text\": \"Divorce Sett/Compensation\"\n        },\n        {\n          \"value\": \"17\",\n          \"text\": \"Sale of Inves/Shares/Prop/Land\"\n        },\n        {\n          \"value\": \"18\",\n          \"text\": \"Dividends/Profits\"\n        },\n        {\n          \"value\": \"20\",\n          \"text\": \"Rental Proceeds\"\n        },\n        {\n          \"value\": \"21\",\n          \"text\": \"Commission\"\n        },\n        {\n          \"value\": \"22\",\n          \"text\": \"Directors Fee/Salary\"\n        },\n        {\n          \"value\": \"23\",\n          \"text\": \"Welfare Allowance\"\n        },\n        {\n          \"value\": \"24\",\n          \"text\": \"Return on Investment\"\n        },\n        {\n          \"value\": \"25\",\n          \"text\": \"FD Placement Roll Over/Renewal\"\n        },\n        {\n          \"value\": \"26\",\n          \"text\": \"Insurance Maturity/Surrender\"\n        },\n        {\n          \"value\": \"27\",\n          \"text\": \"Legal Settlement\"\n        },\n        {\n          \"value\": \"28\",\n          \"text\": \"Credit Facility Approve by FI\"\n        },\n        {\n          \"value\": \"29\",\n          \"text\": \"Trf frm Parent/Holding/Subs\"\n        },\n        {\n          \"value\": \"30\",\n          \"text\": \"Trf frm Own Acct with Oth FI\"\n        },\n        {\n          \"value\": \"31\",\n          \"text\": \"Spouse/Parents/Children\"\n        },\n        {\n          \"value\": \"32\",\n          \"text\": \"Financial Aid/Subsidies\"\n        },\n        {\n          \"value\": \"33\",\n          \"text\": \"Part-time Income\"\n        },\n        {\n          \"value\": \"34\",\n          \"text\": \"Inheritance\"\n        },\n        {\n          \"value\": \"35\",\n          \"text\": \"Gift/Donation\"\n        },\n        {\n          \"value\": \"36\",\n          \"text\": \"Winning-legal Gambling/Contest\"\n        },\n        {\n          \"value\": \"37\",\n          \"text\": \"Business/Sales Proceeds\"\n        },\n        {\n          \"value\": \"38\",\n          \"text\": \"Crypto Currency/Digital Asset Investment Proceeds\"\n        }\n      ],\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"preferredBranch\",\n      \"displayName\": \"Preferred Branch\",\n      \"placeholder\": \"Select Preferred Branch\",\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"000\",\n          \"text\": \"Head Office (KL)\"\n        },\n        {\n          \"value\": \"002\",\n          \"text\": \"JALAN SILANG (WITH KUP)\"\n        },\n        {\n          \"value\": \"003\",\n          \"text\": \"Jalan Bukit Bintang (WITH BBI)\"\n        },\n        {\n          \"value\": \"004\",\n          \"text\": \"Jln Tun Sambanthan, Ipoh\"\n        },\n        {\n          \"value\": \"005\",\n          \"text\": \"Kampar\"\n        },\n        {\n          \"value\": \"006\",\n          \"text\": \"Johor Bahru City Square\"\n        },\n        {\n          \"value\": \"007\",\n          \"text\": \"Wisma Khoo, Sandakan\"\n        },\n        {\n          \"value\": \"008\",\n          \"text\": \"Putra Square, Kuantan\"\n        },\n        {\n          \"value\": \"009\",\n          \"text\": \"New Town, Petaling Jaya\"\n        },\n        {\n          \"value\": \"010\",\n          \"text\": \"Seri Kembangan\"\n        },\n        {\n          \"value\": \"011\",\n          \"text\": \"Kajang\"\n        },\n        {\n          \"value\": \"012\",\n          \"text\": \"Lebuh Pantai\"\n        },\n        {\n          \"value\": \"013\",\n          \"text\": \"Bentung\"\n        },\n        {\n          \"value\": \"014\",\n          \"text\": \"Batu Pahat\"\n        },\n        {\n          \"value\": \"015\",\n          \"text\": \"Kepong\"\n        },\n        {\n          \"value\": \"016\",\n          \"text\": \"Tanjung Sepat\"\n        },\n        {\n          \"value\": \"017\",\n          \"text\": \"Jln Tunku Ibrahim, Alor Setar\"\n        },\n        {\n          \"value\": \"018\",\n          \"text\": \"Jln Tok Hakim, Kota Bharu\"\n        },\n        {\n          \"value\": \"019\",\n          \"text\": \"Kuala Terengganu\"\n        },\n        {\n          \"value\": \"020\",\n          \"text\": \"Air Tawar\"\n        },\n        {\n          \"value\": \"021\",\n          \"text\": \"Kulai\"\n        },\n        {\n          \"value\": \"022\",\n          \"text\": \"Jln Gaya, Kota Kinabalu\"\n        },\n        {\n          \"value\": \"024\",\n          \"text\": \"Setapak\"\n        },\n        {\n          \"value\": \"025\",\n          \"text\": \"Jelapang\"\n        },\n        {\n          \"value\": \"026\",\n          \"text\": \"Jln Niaga, Shah Alam\"\n        },\n        {\n          \"value\": \"027\",\n          \"text\": \"Bukit Baru\"\n        },\n        {\n          \"value\": \"028\",\n          \"text\": \"Jln Chain Ferry, Prai\"\n        },\n        {\n          \"value\": \"029\",\n          \"text\": \"Yung Kong\"\n        },\n        {\n          \"value\": \"030\",\n          \"text\": \"Kenanga Wholesale City\"\n        },\n        {\n          \"value\": \"031\",\n          \"text\": \"Tmn Sg. Besi\"\n        },\n        {\n          \"value\": \"032\",\n          \"text\": \"Damansara Jaya\"\n        },\n        {\n          \"value\": \"033\",\n          \"text\": \"Kluang\"\n        },\n        {\n          \"value\": \"034\",\n          \"text\": \"Jerantut\"\n        },\n        {\n          \"value\": \"035\",\n          \"text\": \"Kuala Kurau\"\n        },\n        {\n          \"value\": \"036\",\n          \"text\": \"Raub\"\n        },\n        {\n          \"value\": \"037\",\n          \"text\": \"Port Klang\"\n        },\n        {\n          \"value\": \"038\",\n          \"text\": \"Jln Bakar Arang, Sg. Petani\"\n        },\n        {\n          \"value\": \"039\",\n          \"text\": \"Kemaman\"\n        },\n        {\n          \"value\": \"040\",\n          \"text\": \"Pasir Gudang\"\n        },\n        {\n          \"value\": \"041\",\n          \"text\": \"Bandar Baru Sg. Buloh\"\n        },\n        {\n          \"value\": \"042\",\n          \"text\": \"Jelutong\"\n        },\n        {\n          \"value\": \"043\",\n          \"text\": \"Tmn Suntex\"\n        },\n        {\n          \"value\": \"044\",\n          \"text\": \"Tmn Johor Jaya, Johor Bahru\"\n        },\n        {\n          \"value\": \"045\",\n          \"text\": \"JALAN TUN RAZAK (WITH PAS)\"\n        },\n        {\n          \"value\": \"046\",\n          \"text\": \"Jln Nakhoda Gampar, Miri\"\n        },\n        {\n          \"value\": \"047\",\n          \"text\": \"Tawau\"\n        },\n        {\n          \"value\": \"048\",\n          \"text\": \"Inanam\"\n        },\n        {\n          \"value\": \"049\",\n          \"text\": \"Tmn Pelangi, Johor Bahru\"\n        },\n        {\n          \"value\": \"050\",\n          \"text\": \"Tmn Ungku Tun Aminah\"\n        },\n        {\n          \"value\": \"051\",\n          \"text\": \"Jln Tunku Osman, Sibu\"\n        },\n        {\n          \"value\": \"052\",\n          \"text\": \"BUKIT MERTAJAM 1(WITH BMT)\"\n        },\n        {\n          \"value\": \"053\",\n          \"text\": \"Bandar Baru Uda, Tampoi\"\n        },\n        {\n          \"value\": \"054\",\n          \"text\": \"Rawang\"\n        },\n        {\n          \"value\": \"055\",\n          \"text\": \"Jln SS15 Subang Jaya\"\n        },\n        {\n          \"value\": \"056\",\n          \"text\": \"Mid Valley\"\n        },\n        {\n          \"value\": \"057\",\n          \"text\": \"Pandan Indah\"\n        },\n        {\n          \"value\": \"058\",\n          \"text\": \"Bayan Baru\"\n        },\n        {\n          \"value\": \"059\",\n          \"text\": \"Pasar Borong, Selayang\"\n        },\n        {\n          \"value\": \"060\",\n          \"text\": \"IOI Boulevard Puchong\"\n        },\n        {\n          \"value\": \"061\",\n          \"text\": \"KLCC\"\n        },\n        {\n          \"value\": \"062\",\n          \"text\": \"Bandar Baru Ampang\"\n        },\n        {\n          \"value\": \"063\",\n          \"text\": \"Tangkak\"\n        },\n        {\n          \"value\": \"064\",\n          \"text\": \"Mentakab\"\n        },\n        {\n          \"value\": \"065\",\n          \"text\": \"Bandar Baru Klang\"\n        },\n        {\n          \"value\": \"066\",\n          \"text\": \"Wisma Mahmud, Kuching\"\n        },\n        {\n          \"value\": \"067\",\n          \"text\": \"First Avenue\"\n        },\n        {\n          \"value\": \"068\",\n          \"text\": \"Kuala Lumpur Main\"\n        },\n        {\n          \"value\": \"069\",\n          \"text\": \"Kuala Kedah\"\n        },\n        {\n          \"value\": \"070\",\n          \"text\": \"Kulim\"\n        },\n        {\n          \"value\": \"073\",\n          \"text\": \"Lahad Datu\"\n        },\n        {\n          \"value\": \"074\",\n          \"text\": \"The Trillium, Lakefields\"\n        },\n        {\n          \"value\": \"075\",\n          \"text\": \"Mergong, Alor Setar\"\n        },\n        {\n          \"value\": \"076\",\n          \"text\": \"Ampang Point\"\n        },\n        {\n          \"value\": \"077\",\n          \"text\": \"Ayer Itam\"\n        },\n        {\n          \"value\": \"078\",\n          \"text\": \"Bangsar Shopping Centre\"\n        },\n        {\n          \"value\": \"079\",\n          \"text\": \"Bekok\"\n        },\n        {\n          \"value\": \"080\",\n          \"text\": \"Butterworth\"\n        },\n        {\n          \"value\": \"081\",\n          \"text\": \"Gopeng\"\n        },\n        {\n          \"value\": \"082\",\n          \"text\": \"Gunung Rapat, Ipoh\"\n        },\n        {\n          \"value\": \"083\",\n          \"text\": \"Ipoh Garden South\"\n        },\n        {\n          \"value\": \"084\",\n          \"text\": \"Jln Bukit Bintang\"\n        },\n        {\n          \"value\": \"086\",\n          \"text\": \"Jln Ipoh\"\n        },\n        {\n          \"value\": \"087\",\n          \"text\": \"Jln Pasar\"\n        },\n        {\n          \"value\": \"088\",\n          \"text\": \"JALAN RAJA LAUT(WITH JIP)\"\n        },\n        {\n          \"value\": \"089\",\n          \"text\": \"Jln Raja Uda, Butterworth\"\n        },\n        {\n          \"value\": \"091\",\n          \"text\": \"Jementah\"\n        },\n        {\n          \"value\": \"092\",\n          \"text\": \"Tmn Sentosa, Johor Bahru\"\n        },\n        {\n          \"value\": \"093\",\n          \"text\": \"Kangar\"\n        },\n        {\n          \"value\": \"094\",\n          \"text\": \"Ketereh\"\n        },\n        {\n          \"value\": \"095\",\n          \"text\": \"Persiaran Sultan Ibrahim, Kelang\"\n        },\n        {\n          \"value\": \"096\",\n          \"text\": \"Kluang 2 (WITH KLU)\"\n        },\n        {\n          \"value\": \"098\",\n          \"text\": \"Jln Tun HS Lee\"\n        },\n        {\n          \"value\": \"101\",\n          \"text\": \"Jln Burma\"\n        },\n        {\n          \"value\": \"102\",\n          \"text\": \"Jln Hang Tuah\"\n        },\n        {\n          \"value\": \"103\",\n          \"text\": \"Plaza OSK, Jln Ampang\"\n        },\n        {\n          \"value\": \"104\",\n          \"text\": \"Meru\"\n        },\n        {\n          \"value\": \"106\",\n          \"text\": \"Permas Jaya, Johor Bahru\"\n        },\n        {\n          \"value\": \"107\",\n          \"text\": \"RHB SOHO IPOH\"\n        },\n        {\n          \"value\": \"110\",\n          \"text\": \"Rantau\"\n        },\n        {\n          \"value\": \"111\",\n          \"text\": \"Bandar Sri Permaisuri\"\n        },\n        {\n          \"value\": \"112\",\n          \"text\": \"Section 14, Petaling Jaya\"\n        },\n        {\n          \"value\": \"113\",\n          \"text\": \"Segamat\"\n        },\n        {\n          \"value\": \"115\",\n          \"text\": \"Senai\"\n        },\n        {\n          \"value\": \"116\",\n          \"text\": \"Seremban\"\n        },\n        {\n          \"value\": \"118\",\n          \"text\": \"Jln Tengku Ampuan Zabedah, Shah Alam\"\n        },\n        {\n          \"value\": \"121\",\n          \"text\": \"Bandar Sri Damansara\"\n        },\n        {\n          \"value\": \"123\",\n          \"text\": \"Sg. Bakap\"\n        },\n        {\n          \"value\": \"124\",\n          \"text\": \"Kg. Baru Sg. Buloh\"\n        },\n        {\n          \"value\": \"125\",\n          \"text\": \"Sg. Pelek\"\n        },\n        {\n          \"value\": \"126\",\n          \"text\": \"Tmn Pekan Baru, Sg. Petani\"\n        },\n        {\n          \"value\": \"128\",\n          \"text\": \"Sungkai\"\n        },\n        {\n          \"value\": \"130\",\n          \"text\": \"Tmn Indah\"\n        },\n        {\n          \"value\": \"131\",\n          \"text\": \"Tmn Megah\"\n        },\n        {\n          \"value\": \"132\",\n          \"text\": \"Tmn Molek, Johor Bahru\"\n        },\n        {\n          \"value\": \"133\",\n          \"text\": \"Dataran Wangsa\"\n        },\n        {\n          \"value\": \"134\",\n          \"text\": \"Tmn Shamelin\"\n        },\n        {\n          \"value\": \"136\",\n          \"text\": \"Tmn Taming Jaya\"\n        },\n        {\n          \"value\": \"139\",\n          \"text\": \"UEP Subang Jaya\"\n        },\n        {\n          \"value\": \"140\",\n          \"text\": \"Ulu Tiram\"\n        },\n        {\n          \"value\": \"142\",\n          \"text\": \"Bandar Baru Nilai\"\n        },\n        {\n          \"value\": \"144\",\n          \"text\": \"Menglembu\"\n        },\n        {\n          \"value\": \"145\",\n          \"text\": \"Bayan Point\"\n        },\n        {\n          \"value\": \"150\",\n          \"text\": \"Jln Masjid, Bintulu\"\n        },\n        {\n          \"value\": \"153\",\n          \"text\": \"Damansara Utama\"\n        },\n        {\n          \"value\": \"158\",\n          \"text\": \"Plentong, Johor Bahru\"\n        },\n        {\n          \"value\": \"161\",\n          \"text\": \"Bagan Serai\"\n        },\n        {\n          \"value\": \"163\",\n          \"text\": \"Bahau\"\n        },\n        {\n          \"value\": \"165\",\n          \"text\": \"Bukit Mertajam\"\n        },\n        {\n          \"value\": \"169\",\n          \"text\": \"Simpang Empat, Hutan Melintang\"\n        },\n        {\n          \"value\": \"176\",\n          \"text\": \"Jenjarom\"\n        },\n        {\n          \"value\": \"177\",\n          \"text\": \"Jinjang Utara\"\n        },\n        {\n          \"value\": \"182\",\n          \"text\": \"Kerteh\"\n        },\n        {\n          \"value\": \"183\",\n          \"text\": \"Jln Stesen, Kelang\"\n        },\n        {\n          \"value\": \"187\",\n          \"text\": \"Kuala Dungun\"\n        },\n        {\n          \"value\": \"188\",\n          \"text\": \"Kuala Kangsar\"\n        },\n        {\n          \"value\": \"190\",\n          \"text\": \"Kuala Pilah\"\n        },\n        {\n          \"value\": \"195\",\n          \"text\": \"Jln Tun Mustapha\"\n        },\n        {\n          \"value\": \"196\",\n          \"text\": \"Pulau Langkawi\"\n        },\n        {\n          \"value\": \"198\",\n          \"text\": \"LEBUH PANTAI 3 (WITH PNG)\"\n        },\n        {\n          \"value\": \"202\",\n          \"text\": \"Jln Abdullah, Muar\"\n        },\n        {\n          \"value\": \"203\",\n          \"text\": \"Overseas Union Garden\"\n        },\n        {\n          \"value\": \"204\",\n          \"text\": \"Padang Serai\"\n        },\n        {\n          \"value\": \"205\",\n          \"text\": \"Parit Buntar\"\n        },\n        {\n          \"value\": \"207\",\n          \"text\": \"Pasir Mas\"\n        },\n        {\n          \"value\": \"208\",\n          \"text\": \"Pontian Kecil\"\n        },\n        {\n          \"value\": \"213\",\n          \"text\": \"Segambut\"\n        },\n        {\n          \"value\": \"216\",\n          \"text\": \"SETAPAK 3 (WITH STP)\"\n        },\n        {\n          \"value\": \"218\",\n          \"text\": \"Simpang Renggam\"\n        },\n        {\n          \"value\": \"219\",\n          \"text\": \"Sitiawan\"\n        },\n        {\n          \"value\": \"223\",\n          \"text\": \"Sg. Siput\"\n        },\n        {\n          \"value\": \"224\",\n          \"text\": \"SS2 Petaling Jaya\"\n        },\n        {\n          \"value\": \"225\",\n          \"text\": \"Taiping\"\n        },\n        {\n          \"value\": \"228\",\n          \"text\": \"Tmn Midah\"\n        },\n        {\n          \"value\": \"231\",\n          \"text\": \"Tmn Tun Dr Ismail\"\n        },\n        {\n          \"value\": \"232\",\n          \"text\": \"Tanjong Karang\"\n        },\n        {\n          \"value\": \"233\",\n          \"text\": \"Tasek, Ipoh\"\n        },\n        {\n          \"value\": \"235\",\n          \"text\": \"Teluk Intan\"\n        },\n        {\n          \"value\": \"237\",\n          \"text\": \"Yong Peng\"\n        },\n        {\n          \"value\": \"239\",\n          \"text\": \"Plaza Damas 3\"\n        },\n        {\n          \"value\": \"240\",\n          \"text\": \"Putrajaya\"\n        },\n        {\n          \"value\": \"242\",\n          \"text\": \"Lawas\"\n        },\n        {\n          \"value\": \"252\",\n          \"text\": \"Melaka Raya\"\n        },\n        {\n          \"value\": \"260\",\n          \"text\": \"Prima Square, Sandakan\"\n        },\n        {\n          \"value\": \"261\",\n          \"text\": \"Jln Kulas, Kuching\"\n        },\n        {\n          \"value\": \"264\",\n          \"text\": \"Simpang Tiga, Kuching\"\n        },\n        {\n          \"value\": \"266\",\n          \"text\": \"Boulevard Centre, Miri\"\n        },\n        {\n          \"value\": \"268\",\n          \"text\": \"Lundu\"\n        },\n        {\n          \"value\": \"269\",\n          \"text\": \"Kanowit\"\n        },\n        {\n          \"value\": \"271\",\n          \"text\": \"Dalat\"\n        },\n        {\n          \"value\": \"272\",\n          \"text\": \"Kota Samarahan, Kuching\"\n        },\n        {\n          \"value\": \"273\",\n          \"text\": \"Sarikei\"\n        },\n        {\n          \"value\": \"275\",\n          \"text\": \"Tabuan Jaya, Kuching\"\n        },\n        {\n          \"value\": \"276\",\n          \"text\": \"Siburan\"\n        },\n        {\n          \"value\": \"278\",\n          \"text\": \"Matang Jaya, Kuching\"\n        },\n        {\n          \"value\": \"280\",\n          \"text\": \"Batu Kawah, Kuching\"\n        },\n        {\n          \"value\": \"281\",\n          \"text\": \"Lintas Station Complex, Kota Kinabalu\"\n        },\n        {\n          \"value\": \"282\",\n          \"text\": \"Limbang\"\n        },\n        {\n          \"value\": \"286\",\n          \"text\": \"Taipan Senawang\"\n        },\n        {\n          \"value\": \"288\",\n          \"text\": \"Kota Damansara\"\n        },\n        {\n          \"value\": \"289\",\n          \"text\": \"The Vertical, Bangsar South\"\n        },\n        {\n          \"value\": \"290\",\n          \"text\": \"Tmn Mount Austin, Johor Bahru\"\n        },\n        {\n          \"value\": \"291\",\n          \"text\": \"Menara Shell\"\n        },\n        {\n          \"value\": \"293\",\n          \"text\": \"Paradigm Mall, Kelana Jaya\"\n        },\n        {\n          \"value\": \"294\",\n          \"text\": \"Utropolis Mall, Glenmarie\"\n        },\n        {\n          \"value\": \"295\",\n          \"text\": \"Bandar Bukit Tinggi\"\n        },\n        {\n          \"value\": \"296\",\n          \"text\": \"Jitra\"\n        },\n        {\n          \"value\": \"297\",\n          \"text\": \"Air Putih, Kuantan\"\n        },\n        {\n          \"value\": \"298\",\n          \"text\": \"Sg. Merah, Sibu\"\n        },\n        {\n          \"value\": \"299\",\n          \"text\": \"Tmn Nusa Bestari, Johor Bahru\"\n        },\n        {\n          \"value\": \"300\",\n          \"text\": \"Keningau\"\n        },\n        {\n          \"value\": \"301\",\n          \"text\": \"1 Lagenda\"\n        },\n        {\n          \"value\": \"302\",\n          \"text\": \"Triang\"\n        },\n        {\n          \"value\": \"303\",\n          \"text\": \"Tmn Connaught\"\n        },\n        {\n          \"value\": \"304\",\n          \"text\": \"MetroTown, Kota Kinabalu\"\n        },\n        {\n          \"value\": \"305\",\n          \"text\": \"Kota Kemuning\"\n        },\n        {\n          \"value\": \"306\",\n          \"text\": \"Kota Tinggi\"\n        },\n        {\n          \"value\": \"307\",\n          \"text\": \"Setia Alam\"\n        },\n        {\n          \"value\": \"308\",\n          \"text\": \"Alam Avenue\"\n        },\n        {\n          \"value\": \"309\",\n          \"text\": \"Malim\"\n        },\n        {\n          \"value\": \"310\",\n          \"text\": \"Mukah\"\n        },\n        {\n          \"value\": \"312\",\n          \"text\": \"Bandar Mahkota Cheras\"\n        },\n        {\n          \"value\": \"313\",\n          \"text\": \"Seremban 2\"\n        },\n        {\n          \"value\": \"314\",\n          \"text\": \"Banting\"\n        },\n        {\n          \"value\": \"315\",\n          \"text\": \"IOI Resort City\"\n        },\n        {\n          \"value\": \"316\",\n          \"text\": \"Bandar Sri Petaling\"\n        },\n        {\n          \"value\": \"317\",\n          \"text\": \"Tanjung Tokong\"\n        },\n        {\n          \"value\": \"319\",\n          \"text\": \"Bandar Penawar\"\n        },\n        {\n          \"value\": \"320\",\n          \"text\": \"Kelana Jaya\"\n        },\n        {\n          \"value\": \"321\",\n          \"text\": \"RHB Bank Jalan Raja Laut, Kuala Lumpur\"\n        },\n        {\n          \"value\": \"322\",\n          \"text\": \"Auto City, Juru\"\n        },\n        {\n          \"value\": \"323\",\n          \"text\": \"Tmn Setia Tropika, Johor Bahru\"\n        },\n        {\n          \"value\": \"389\",\n          \"text\": \"Tmn Flora Utama, Batu Pahat\"\n        },\n        {\n          \"value\": \"399\",\n          \"text\": \"Caw. Utama\"\n        },\n        {\n          \"value\": \"400\",\n          \"text\": \"Caw. Jln Satok, Kuching\"\n        },\n        {\n          \"value\": \"401\",\n          \"text\": \"Caw. Kelana Jaya\"\n        },\n        {\n          \"value\": \"402\",\n          \"text\": \"Caw. Tmn Flora Utama, Batu Pahat\"\n        },\n        {\n          \"value\": \"403\",\n          \"text\": \"Caw. Kubang Kerian, Kota Bharu\"\n        },\n        {\n          \"value\": \"404\",\n          \"text\": \"Caw. Tmn Setia Tropika, Johor Bahru\"\n        },\n        {\n          \"value\": \"405\",\n          \"text\": \"Caw. Bandar Baru Bangi\"\n        },\n        {\n          \"value\": \"407\",\n          \"text\": \"Caw. Kuala Terengganu\"\n        },\n        {\n          \"value\": \"408\",\n          \"text\": \"Caw. Jln Raja Laut\"\n        },\n        {\n          \"value\": \"409\",\n          \"text\": \"Caw. Auto City\"\n        },\n        {\n          \"value\": \"411\",\n          \"text\": \"Caw. Lagenda Heights, Sg. Petani\"\n        },\n        {\n          \"value\": \"412\",\n          \"text\": \"Caw. Laman Seri, Shah Alam\"\n        },\n        {\n          \"value\": \"457\",\n          \"text\": \"RHB Bank Sales Centre AEON Taman Equine\"\n        },\n        {\n          \"value\": \"473\",\n          \"text\": \"RHB EASY - Kompleks Teruntum\"\n        },\n        {\n          \"value\": \"479\",\n          \"text\": \"RHB EASY - Giant Plentong\"\n        },\n        {\n          \"value\": \"491\",\n          \"text\": \"RHB EASY - Mydin Mall MITC Melaka\"\n        },\n        {\n          \"value\": \"630\",\n          \"text\": \"RHB EASY - Mydin Kubang Kerian\"\n        },\n        {\n          \"value\": \"637\",\n          \"text\": \"RHB EASY - Mydin Meru Raya\"\n        },\n        {\n          \"value\": \"710\",\n          \"text\": \"RHB EASY - E-Mart Commercial Centre\"\n        },\n        {\n          \"value\": \"712\",\n          \"text\": \"RHB EASY - Giant Hypermarket Bayan Baru\"\n        },\n        {\n          \"value\": \"861\",\n          \"text\": \"RHB EASY Warisan Square\"\n        },\n        {\n          \"value\": \"931\",\n          \"text\": \"CC EMBOSSING\"\n        },\n        {\n          \"value\": \"RD08\",\n          \"text\": \"PERAK REGION\"\n        }\n      ],\n      \"category\": \"11\"\n    },\n    {\n      \"name\": \"bdmMoreThan2500kg\",\n      \"displayName\": \"BDM More Than 2500kg\",\n      \"type\": \"text\",\n      \"category\": \"12\"\n    },\n    {\n      \"name\": \"chassisNo\",\n      \"displayName\": \"Chassis Number\",\n      \"type\": \"text\",\n      \"category\": \"12\"\n    },\n    {\n      \"name\": \"engineNo\",\n      \"displayName\": \"Engine Number\",\n      \"type\": \"text\",\n      \"category\": \"12\"\n    },\n    {\n      \"name\": \"marketValue\",\n      \"displayName\": \"Market Value\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"12\"\n    },\n    {\n      \"name\": \"modelOfVehicle\",\n      \"displayName\": \"Model of Vehicle\",\n      \"type\": \"text\",\n      \"category\": \"12\"\n    },\n    {\n      \"type\": \"text\",\n      \"name\": \"purchasePriceOTR\",\n      \"title\": \"carPrice\",\n      \"placeholder\": \"Car Price\",\n      \"isRequired\": true,\n      \"displayName\": \"Car Price\",\n      \"maxLength\": 23,\n      \"min\": 2000,\n      \"max\": 150000,\n      \"inputType\": \"number\",\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"text\": \"Please enter a financing amount between 2,000 and 150,000.\",\n          \"regex\": \"^(2000|[1-9][0-9]{3}|[1-9][0-9]{4}|150000)$\"\n        },\n        {\n          \"type\": \"regex\",\n          \"text\": \"Please enter an amount in increments of 1,000.\",\n          \"regex\": \"^([1-9][0-9]*000|150000)$\"\n        }\n      ],\n      \"kind\": \"money\",\n      \"category\": \"12\"\n    },\n    {\n      \"name\": \"registrationDate\",\n      \"displayName\": \"Registration Date\",\n      \"type\": \"text\",\n      \"inputType\": \"date\",\n      \"category\": \"12\"\n    },\n    {\n      \"name\": \"registrationNo\",\n      \"displayName\": \"Registration Number\",\n      \"type\": \"text\",\n      \"category\": \"12\"\n    },\n    {\n      \"name\": \"vehicleCondition\",\n      \"displayName\": \"Condition\",\n      \"placeholder\": \"Vehicle Condition\",\n      \"startWithNewLine\": false,\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"N\",\n          \"text\": \"New\"\n        },\n        {\n          \"value\": \"U\",\n          \"text\": \"Used\"\n        },\n        {\n          \"value\": \"UN\",\n          \"text\": \"UnRegistered Recon\"\n        },\n        {\n          \"value\": \"UR\",\n          \"text\": \"Used Recon\"\n        },\n        {\n          \"value\": \"PR\",\n          \"text\": \"Pre-registered\"\n        }\n      ],\n      \"category\": \"12\"\n    },\n    {\n      \"name\": \"yearMake\",\n      \"displayName\": \"Year Make\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"startWithNewLine\": false,\n      \"placeholder\": \"Year\",\n      \"min\": 2014,\n      \"max\": 2100,\n      \"category\": \"12\"\n    },\n    {\n      \"name\": \"makeOfVehicle\",\n      \"displayName\": \"Make of Vehicle\",\n      \"type\": \"text\",\n      \"category\": \"12\"\n    },\n    {\n      \"name\": \"permanentaddressLine1\",\n      \"displayName\": \"Permanent Address Line 1\",\n      \"placeholder\": \"Permanent Address Line 1\",\n      \"maxLength\": 40,\n      \"type\": \"text\",\n      \"category\": \"7\"\n    },\n    {\n      \"name\": \"permanentaddressLine2\",\n      \"displayName\": \"Permanent Address Line 2\",\n      \"placeholder\": \"Permanent Address Line 2 (optional)\",\n      \"isRequired\": false,\n      \"type\": \"text\",\n      \"maxLength\": 40,\n      \"category\": \"7\"\n    },\n    {\n      \"name\": \"permanentaddressLine3\",\n      \"displayName\": \"Permanent Address Line 3\",\n      \"maxLength\": 40,\n      \"placeholder\": \"Permanent Address Line 3 (optional)\",\n      \"isRequired\": false,\n      \"startWithNewLine\": false,\n      \"type\": \"text\",\n      \"category\": \"7\"\n    },\n    {\n      \"name\": \"permanentaddressType\",\n      \"displayName\": \"Permanent Address Type\",\n      \"type\": \"text\",\n      \"category\": \"7\"\n    },\n    {\n      \"name\": \"permanentcity\",\n      \"displayName\": \"Permanent City\",\n      \"placeholder\": \"City of the Permanent Address\",\n      \"type\": \"text\",\n      \"maxLength\": 20,\n      \"startWithNewLine\": false,\n      \"category\": \"7\"\n    },\n    {\n      \"name\": \"permanentpostcode\",\n      \"displayName\": \"Permanent Postcode\",\n      \"placeholder\": \"Postcode of the Permanent Address\",\n      \"type\": \"text\",\n      \"maxLength\": 10,\n      \"category\": \"7\"\n    },\n    {\n      \"name\": \"residentialaddressLine1\",\n      \"displayName\": \"Residential Address Line 1\",\n      \"placeholder\": \"Residential Address Line 1\",\n      \"visibleIf\": \"{residenceAddress} == false\",\n      \"type\": \"text\",\n      \"maxLength\": 40,\n      \"category\": \"7\"\n    },\n    {\n      \"name\": \"residentialaddressLine2\",\n      \"displayName\": \"Residential Address Line 2\",\n      \"placeholder\": \"Residential Address Line 2 (optional)\",\n      \"isRequired\": false,\n      \"visibleIf\": \"{residenceAddress} == false\",\n      \"type\": \"text\",\n      \"maxLength\": 40,\n      \"category\": \"7\"\n    },\n    {\n      \"name\": \"residentialaddressLine3\",\n      \"displayName\": \"Residential Address Line 3\",\n      \"placeholder\": \"Residential Address Line 3 (optional)\",\n      \"isRequired\": false,\n      \"startWithNewLine\": false,\n      \"visibleIf\": \"{residenceAddress} == false\",\n      \"type\": \"text\",\n      \"maxLength\": 40,\n      \"category\": \"7\"\n    },\n    {\n      \"name\": \"residentialaddressType\",\n      \"displayName\": \"Residential Address Type\",\n      \"type\": \"text\",\n      \"category\": \"7\"\n    },\n    {\n      \"name\": \"residentialcity\",\n      \"displayName\": \"Residential City\",\n      \"placeholder\": \"City of the Residential Address\",\n      \"visibleIf\": \"{residenceAddress} == false\",\n      \"startWithNewLine\": false,\n      \"type\": \"text\",\n      \"maxLength\": 20,\n      \"category\": \"7\"\n    },\n    {\n      \"name\": \"residentialpostcode\",\n      \"displayName\": \"Residential Postcode\",\n      \"placeholder\": \"Postcode of the Residential Address\",\n      \"visibleIf\": \"{residenceAddress} == false\",\n      \"type\": \"text\",\n      \"maxLength\": 10,\n      \"category\": \"7\"\n    },\n    {\n      \"name\": \"residentialstate\",\n      \"displayName\": \"Residential State\",\n      \"placeholder\": \"Select State Of The Residential Address\",\n      \"startWithNewLine\": false,\n      \"visibleIf\": \"{residenceAddress} == false\",\n      \"type\": \"dropdown\",\n      \"choices\": [\n        {\n          \"value\": \"A\",\n          \"text\": \"PERAK\"\n        },\n        {\n          \"value\": \"B\",\n          \"text\": \"SELANGOR\"\n        },\n        {\n          \"value\": \"C\",\n          \"text\": \"PAHANG\"\n        },\n        {\n          \"value\": \"D\",\n          \"text\": \"KELANTAN\"\n        },\n        {\n          \"value\": \"J\",\n          \"text\": \"JOHOR\"\n        },\n        {\n          \"value\": \"K\",\n          \"text\": \"KEDAH\"\n        },\n        {\n          \"value\": \"L\",\n          \"text\": \"WP LABUAN\"\n        },\n        {\n          \"value\": \"M\",\n          \"text\": \"MELAKA\"\n        },\n        {\n          \"value\": \"N\",\n          \"text\": \"NEGERI SEMBILAN\"\n        },\n        {\n          \"value\": \"P\",\n          \"text\": \"PULAU PINANG\"\n        },\n        {\n          \"value\": \"Q\",\n          \"text\": \"SARAWAK\"\n        },\n        {\n          \"value\": \"R\",\n          \"text\": \"PERLIS\"\n        },\n        {\n          \"value\": \"S\",\n          \"text\": \"SABAH\"\n        },\n        {\n          \"value\": \"T\",\n          \"text\": \"TERENGGANU\"\n        },\n        {\n          \"value\": \"U\",\n          \"text\": \"WP PUTRAJAYA\"\n        },\n        {\n          \"value\": \"W\",\n          \"text\": \"WP KUALA LUMPUR\"\n        }\n      ],\n      \"category\": \"7\"\n    },\n    {\n      \"name\": \"officeaddressLine1\",\n      \"displayName\": \"Employer Address Line 1\",\n      \"placeholder\": \"Employer Address Line 1\",\n      \"type\": \"text\",\n      \"maxLength\": 40,\n      \"visibleIf\": \"{employmentType} anyof ['01', '02', '07', '08', '09', '10' ]\",\n      \"category\": \"5\"\n    },\n    {\n      \"name\": \"officeaddressLine2\",\n      \"displayName\": \"Employer Address Line 2\",\n      \"placeholder\": \"Employer Address Line 2 (optional)\",\n      \"isRequired\": false,\n      \"visibleIf\": \"{employmentType} anyof ['01', '02', '07', '08', '09', '10' ]\",\n      \"type\": \"text\",\n      \"maxLength\": 40,\n      \"category\": \"5\"\n    },\n    {\n      \"name\": \"officeaddressLine3\",\n      \"displayName\": \"Employer Address Line 3\",\n      \"placeholder\": \"Employer Address Line 3 (optional)\",\n      \"startWithNewLine\": false,\n      \"isRequired\": false,\n      \"visibleIf\": \"{employmentType} anyof ['01', '02', '07', '08', '09', '10' ]\",\n      \"type\": \"text\",\n      \"maxLength\": 40,\n      \"category\": \"5\"\n    },\n    {\n      \"name\": \"officeaddressType\",\n      \"displayName\": \"Office Address Type\",\n      \"type\": \"text\",\n      \"category\": \"7\"\n    },\n    {\n      \"name\": \"officecity\",\n      \"displayName\": \"Employer City\",\n      \"placeholder\": \"Employer City\",\n      \"visibleIf\": \"{employmentType} anyof ['01', '02', '07', '08', '09', '10' ]\",\n      \"startWithNewLine\": false,\n      \"type\": \"text\",\n      \"maxLength\": 20,\n      \"category\": \"5\"\n    },\n    {\n      \"name\": \"officepostcode\",\n      \"displayName\": \"Employer Postcode\",\n      \"placeholder\": \"Employer Postcode\",\n      \"visibleIf\": \"{employmentType} anyof ['01', '02', '07', '08', '09', '10' ]\",\n      \"type\": \"text\",\n      \"maxLength\": 10,\n      \"inputType\": \"number\",\n      \"category\": \"5\"\n    },\n    {\n      \"name\": \"computationMode\",\n      \"displayName\": \"Computation Mode\",\n      \"type\": \"text\",\n      \"category\": \"10\"\n    },\n    {\n      \"name\": \"countryOfPermanentResident\",\n      \"displayName\": \"Country of Permanent Resident\",\n      \"type\": \"text\",\n      \"category\": \"2\"\n    },\n    {\n      \"name\": \"foreignPR\",\n      \"displayName\": \"Foreign PR\",\n      \"type\": \"text\",\n      \"category\": \"2\"\n    },\n    {\n      \"name\": \"internationalExtensionPhoneNo\",\n      \"displayName\": \"International Extension Phone No\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"8\"\n    },\n    {\n      \"name\": \"internationalPhoneNo\",\n      \"displayName\": \"International Phone No\",\n      \"type\": \"text\",\n      \"inputType\": \"tel\",\n      \"category\": \"8\"\n    },\n    {\n      \"name\": \"internationalPhoneNoAreaCode\",\n      \"displayName\": \"International Phone No Area Code\",\n      \"type\": \"text\",\n      \"inputType\": \"tel\",\n      \"category\": \"8\"\n    },\n    {\n      \"name\": \"pRIDNo\",\n      \"displayName\": \"PR ID No\",\n      \"type\": \"text\",\n      \"category\": \"2\"\n    },\n    {\n      \"name\": \"dealerName\",\n      \"displayName\": \"Dealer Name\",\n      \"type\": \"text\",\n      \"category\": \"3\"\n    },\n    {\n      \"name\": \"cashDownpayment\",\n      \"displayName\": \"Cash Downpayment\",\n      \"placeholder\": \"Cash Downpayment\",\n      \"startWithNewLine\": false,\n      \"type\": \"text\",\n      \"maxLength\": 20,\n      \"category\": \"11\"\n    },\n    {\n      \"name\": \"downpayment\",\n      \"displayName\": \"Down Payment (%)\",\n      \"placeholder\": \"Down Payment (%)\",\n      \"type\": \"text\",\n      \"category\": \"11\"\n    },\n    {\n      \"name\": \"bankName\",\n      \"displayName\": \"Bank Name\",\n      \"placeholder\": \"Bank Name\",\n      \"visible\": false,\n      \"type\": \"text\",\n      \"startWithNewLine\": false,\n      \"category\": \"11\"\n    },\n    {\n      \"name\": \"bankRates\",\n      \"displayName\": \"Bank Rate\",\n      \"placeholder\": \"Bank Rate\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"startWithNewLine\": false,\n      \"category\": \"11\"\n    },\n    {\n      \"name\": \"monthlyRepayment\",\n      \"displayName\": \"Monthly Repayment\",\n      \"placeholder\": \"Monthly Repayment\",\n      \"startWithNewLine\": false,\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"11\"\n    },\n    {\n      \"name\": \"facilityTenureYears\",\n      \"displayName\": \"Repayment Term (Years)\",\n      \"placeholder\": \"Payment Term\",\n      \"startWithNewLine\": false,\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"text\": \"Please enter a valid financing tenure from 1 to 7 years.\",\n          \"regex\": \"^[1-7]$\"\n        }\n      ],\n      \"category\": \"11\"\n    },\n    {\n      \"name\": \"totalFinancing\",\n      \"displayName\": \"Financing Amount\",\n      \"placeholder\": \"How much do you want to borrow?\",\n      \"type\": \"text\",\n      \"maxLength\": 15,\n      \"min\": 2000,\n      \"max\": 150000,\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"text\": \"Please enter a financing amount between 2,000 and 150,000.\",\n          \"regex\": \"^(2000|[1-9][0-9]{3}|[1-9][0-9]{4}|150000)$\"\n        },\n        {\n          \"type\": \"regex\",\n          \"text\": \"Please enter an amount in increments of 1,000.\",\n          \"regex\": \"^([1-9][0-9]*000|150000)$\"\n        }\n      ],\n      \"inputType\": \"number\",\n      \"kind\": \"money\",\n      \"category\": \"11\"\n    },\n    {\n      \"name\": \"myKadOrPassport\",\n      \"displayName\": \"MyKad or Passport\",\n      \"type\": \"text\",\n      \"category\": \"2\"\n    },\n    {\n      \"name\": \"incomeEPF_iakaun\",\n      \"displayName\": \"Income EPF i-Akaun\",\n      \"type\": \"text\",\n      \"category\": \"11\"\n    },\n    {\n      \"name\": \"phoneNumber\",\n      \"displayName\": \"Phone Number\",\n      \"type\": \"text\",\n      \"inputType\": \"tel\",\n      \"category\": \"1\"\n    },\n    {\n      \"name\": \"incorporatedDate\",\n      \"displayName\": \"Incorporated Date\",\n      \"type\": \"text\",\n      \"inputType\": \"date\",\n      \"category\": \"3\"\n    },\n    {\n      \"name\": \"shareCapital\",\n      \"displayName\": \"Share Capital\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"tangibleAssets\",\n      \"displayName\": \"Tangible Assets\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"totalCurrentLiabilities\",\n      \"displayName\": \"Total Current Liabilities\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"totalCurrentAssets\",\n      \"displayName\": \"Total Current Assets\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"endOfYearCash\",\n      \"displayName\": \"Cash and Cash Equivalent at end of the Financial Year or Period\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"shortTermLiabilities\",\n      \"displayName\": \"Short Term Liabilities\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"ebitda\",\n      \"displayName\": \"Earning Before Interest, Tax, Depreciation and Amortization (EBITDA)\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"totalAssets\",\n      \"displayName\": \"Total Assets\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"netOperatingCashFlow\",\n      \"displayName\": \"Net Operating Cash Flow\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"netProfitT1\",\n      \"displayName\": \"Net Profit/ Loss and Total Comprehensive Income (year T-1)\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"totalEquityT1\",\n      \"displayName\": \"Total Equity/Owner equity/Total Net (year T-1)\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"netProfitT2\",\n      \"displayName\": \"Net Profit/ Loss and Total Comprehensive Income (year T-2)\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"totalEquityT2\",\n      \"displayName\": \"Total Equity/Owner equity/Total Net (year T-2)\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"facilityInterestRate\",\n      \"displayName\": \"Interest Rate\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"eppProduct\",\n      \"displayName\": \"EPP Product Name\",\n      \"type\": \"text\",\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"eppPrice\",\n      \"displayName\": \"EPP Price\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"eppNoOfPax\",\n      \"displayName\": \"EPP No. of Pax\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"housingLoanMonthlyInstallment\",\n      \"displayName\": \"Housing Loan Monthly Installment\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"hirePurchaseMonthlyInstallment\",\n      \"displayName\": \"Hire Purchase Monthly Installment\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"personalLoanMonthlyInstallment\",\n      \"displayName\": \"Personal Loan Monthly Installment\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"creditCardMonthlyInstallment\",\n      \"displayName\": \"Credit Card Monthly Installment\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"otherFinancingMonthlyInstallment\",\n      \"displayName\": \"Other Financing Monthly Installment\",\n      \"type\": \"text\",\n      \"inputType\": \"number\",\n      \"category\": \"4\"\n    },\n    {\n      \"name\": \"bank_statement_t1\",\n      \"displayName\": \"Bank Statement (Month T-1)\",\n      \"type\": \"file\",\n      \"ihs_column_names\": [\n        \"accountHolderNameT1\",\n        \"statementDateT1\",\n        \"bankNameT1\",\n        \"accountNumberT1\",\n        \"totalCreditsT1\",\n        \"totalDebitsT1\",\n        \"openingBalanceT1\",\n        \"bankBalanceT1\"\n      ],\n      \"category\": \"13\",\n      \"document_type\": \"bankStatements\",\n      \"document_group\": \"bank_statements\",\n      \"document_group_label\": \"Bank Statements\",\n      \"wire_format\": \"path_array\",\n      \"document_slot\": 1,\n      \"time_period_unit\": \"month\"\n    },\n    {\n      \"name\": \"bank_statement_t2\",\n      \"displayName\": \"Bank Statement (Month T-2)\",\n      \"type\": \"file\",\n      \"ihs_column_names\": [\n        \"accountHolderNameT2\",\n        \"statementDateT2\",\n        \"bankNameT2\",\n        \"accountNumberT2\",\n        \"totalCreditsT2\",\n        \"totalDebitsT2\",\n        \"openingBalanceT2\",\n        \"bankBalanceT2\"\n      ],\n      \"category\": \"13\",\n      \"document_type\": \"bankStatements\",\n      \"document_group\": \"bank_statements\",\n      \"document_group_label\": \"Bank Statements\",\n      \"wire_format\": \"path_array\",\n      \"document_slot\": 2,\n      \"time_period_unit\": \"month\"\n    },\n    {\n      \"name\": \"bank_statement_t3\",\n      \"displayName\": \"Bank Statement (Month T-3)\",\n      \"type\": \"file\",\n      \"ihs_column_names\": [\n        \"accountHolderNameT3\",\n        \"statementDateT3\",\n        \"bankNameT3\",\n        \"accountNumberT3\",\n        \"totalCreditsT3\",\n        \"totalDebitsT3\",\n        \"openingBalanceT3\",\n        \"bankBalanceT3\"\n      ],\n      \"category\": \"13\",\n      \"document_type\": \"bankStatements\",\n      \"document_group\": \"bank_statements\",\n      \"document_group_label\": \"Bank Statements\",\n      \"wire_format\": \"path_array\",\n      \"document_slot\": 3,\n      \"time_period_unit\": \"month\"\n    },\n    {\n      \"name\": \"bank_statement_t4\",\n      \"displayName\": \"Bank Statement (Month T-4)\",\n      \"type\": \"file\",\n      \"ihs_column_names\": [\n        \"accountHolderNameT4\",\n        \"statementDateT4\",\n        \"bankNameT4\",\n        \"accountNumberT4\",\n        \"totalCreditsT4\",\n        \"totalDebitsT4\",\n        \"openingBalanceT4\",\n        \"bankBalanceT4\"\n      ],\n      \"category\": \"13\",\n      \"document_type\": \"bankStatements\",\n      \"document_group\": \"bank_statements\",\n      \"document_group_label\": \"Bank Statements\",\n      \"wire_format\": \"path_array\",\n      \"document_slot\": 4,\n      \"time_period_unit\": \"month\"\n    },\n    {\n      \"name\": \"bank_statement_t5\",\n      \"displayName\": \"Bank Statement (Month T-5)\",\n      \"type\": \"file\",\n      \"ihs_column_names\": [\n        \"accountHolderNameT5\",\n        \"statementDateT5\",\n        \"bankNameT5\",\n        \"accountNumberT5\",\n        \"totalCreditsT5\",\n        \"totalDebitsT5\",\n        \"openingBalanceT5\",\n        \"bankBalanceT5\"\n      ],\n      \"category\": \"13\",\n      \"document_type\": \"bankStatements\",\n      \"document_group\": \"bank_statements\",\n      \"document_group_label\": \"Bank Statements\",\n      \"wire_format\": \"path_array\",\n      \"document_slot\": 5,\n      \"time_period_unit\": \"month\"\n    },\n    {\n      \"name\": \"bank_statement_t6\",\n      \"displayName\": \"Bank Statement (Month T-6)\",\n      \"type\": \"file\",\n      \"ihs_column_names\": [\n        \"accountHolderNameT6\",\n        \"statementDateT6\",\n        \"bankNameT6\",\n        \"accountNumberT6\",\n        \"totalCreditsT6\",\n        \"totalDebitsT6\",\n        \"openingBalanceT6\",\n        \"bankBalanceT6\"\n      ],\n      \"category\": \"13\",\n      \"document_type\": \"bankStatements\",\n      \"document_group\": \"bank_statements\",\n      \"document_group_label\": \"Bank Statements\",\n      \"wire_format\": \"path_array\",\n      \"document_slot\": 6,\n      \"time_period_unit\": \"month\"\n    },\n    {\n      \"name\": \"financials\",\n      \"displayName\": \"Audited Financial Statement\",\n      \"type\": \"file\",\n      \"ihs_column_names\": [\n        \"shareCapital\",\n        \"totalEquityT1\",\n        \"totalEquityT2\",\n        \"totalCurrentLiabilities\",\n        \"shortTermLiabilities\",\n        \"totalAssets\",\n        \"totalCurrentAssets\",\n        \"tangibleAssets\",\n        \"netProfitT1\",\n        \"netProfitT2\",\n        \"endOfYearCash\",\n        \"netOperatingCashFlow\",\n        \"ebitda\"\n      ],\n      \"category\": \"13\",\n      \"document_type\": \"financialStatements\",\n      \"document_group\": \"financials\",\n      \"document_group_label\": \"Audited Financial Statements\",\n      \"wire_format\": \"path_array\",\n      \"document_slot\": 1,\n      \"time_period_unit\": \"year\"\n    },\n    {\n      \"name\": \"financials_vn\",\n      \"displayName\": \"Audited Financial Statement (Vietnam)\",\n      \"type\": \"file\",\n      \"ihs_column_names\": [],\n      \"category\": \"13\",\n      \"document_type\": \"financialStatements\",\n      \"document_group\": \"financials\",\n      \"document_group_label\": \"Audited Financial Statements\",\n      \"wire_format\": \"path_array\",\n      \"document_slot\": 1,\n      \"time_period_unit\": \"year\",\n      \"document_language_options\": [\"vi\", \"en\"]\n    },\n    {\n      \"name\": \"financials_fincap_t1\",\n      \"displayName\": \"Audited Financial Statement (T-1) (FinCap)\",\n      \"type\": \"file\",\n      \"ihs_column_names\": [\n        \"nonCurrentAssetsSubsidiaryCompaniesT1\",\n        \"nonCurrentAssetsAssociatedCompaniesT1\",\n        \"nonCurrentAssetsDevelopmentPropertiesOrExpenditureT1\",\n        \"nonCurrentAssetInvestmentPropertiesT1\",\n        \"nonCurrentAssetsInvestmentsT1\",\n        \"nonCurrentAssetInvestmentSecuritiesT1\",\n        \"nonCurrentAssetDeferredAssetsT1\",\n        \"nonCurrentAssetDepositsT1\",\n        \"nonCurrentAssetOwnGoodwillT1\",\n        \"nonCurrentAssetGoodwillOnConsolidationT1\",\n        \"nonCurrentAssetSinkingFundT1\",\n        \"nonCurrentAssetPropertyPlantEquipmentT1\",\n        \"nonCurrentAssetInventoriesT1\",\n        \"nonCurrentAssetRightOfUseAssetsT1\",\n        \"nonCurrentAssetIntangibleAssetsT1\",\n        \"nonCurrentAssetPrepaidLeasePaymentsT1\",\n        \"nonCurrentAssetFinancialAssetAtFairValueT1\",\n        \"nonCurrentAssetLandUseRightT1\",\n        \"nonCurrentAssetTradeReceivablesT1\",\n        \"nonCurrentAssetOtherReceivablesT1\",\n        \"nonCurrentAssetTradeAndOtherReceivablesT1\",\n        \"nonCurrentAssetOtherReceivablesDepositsAndPrepaymentsT1\",\n        \"totalNonCurrentAssetsT1\",\n        \"currentAssetDevelopmentPropertiesOrExpenditureT1\",\n        \"currentAssetShortTermInvestmentsT1\",\n        \"currentAssetTradeDebtorsT1\",\n        \"currentAssetShortTermDepositsT1\",\n        \"currentAssetAmountDueFromHoldingCompanyT1\",\n        \"currentAssetAmountDueFromSubsidiaryCompaniesT1\",\n        \"currentAssetAmountDueFromAssociatedCompaniesT1\",\n        \"currentAssetAmountDueFromDirectorT1\",\n        \"currentAssetAmountDueFromCustomerT1\",\n        \"currentAssetAmountOwingByShareholdersT1\",\n        \"currentAssetInventoriesT1\",\n        \"currentAssetFinancialAssetAtFairValueT1\",\n        \"currentAssetLandUseRightT1\",\n        \"currentAssetTaxRecoverableT1\",\n        \"currentAssetContractAssetsT1\",\n        \"currentAssetCurrentTaxAssetsT1\",\n        \"currentAssetPrepaymentsT1\",\n        \"currentAssetDerivativeT1\",\n        \"currentAssetCashAndBankBalancesT1\",\n        \"currentAssetOtherReceivablesT1\",\n        \"currentAssetRestrictedCashT1\",\n        \"currentAssetCashAndCashEquivalentsT1\",\n        \"currentAssetDepositsCashAndBankBalancesT1\",\n        \"currentAssetCashAtBanksT1\",\n        \"currentAssetCashOnHandT1\",\n        \"currentAssetDepositsAndPrepaymentsT1\",\n        \"currentAssetTradeAndOtherReceivablesT1\",\n        \"currentAssetOtherReceivablesDepositsAndPrepaymentsT1\",\n        \"currentAssetOtherReceivablesAndDepositsT1\",\n        \"currentAssetOtherReceivablesAndPrepaymentsT1\",\n        \"currentAssetCashT1\",\n        \"totalCurrentAssetsT1\",\n        \"totalAssetsT1\",\n        \"currentLiabilitiesTradeCreditorsT1\",\n        \"currentLiabilitiesHirePurchasePayablesT1\",\n        \"currentLiabilitiesBankOverdraftT1\",\n        \"currentLiabilitiesBankAcceptanceT1\",\n        \"currentLiabilitiesBorrowingsOrTermLoansT1\",\n        \"currentLiabilitiesBankborrowingsT1\",\n        \"currentLiabilitiesAmountsOwingToHoldingCompanyT1\",\n        \"currentLiabilitiesAmountsOwingToSubsidiaryCompaniesT1\",\n        \"currentLiabilitiesAmountOwingToAssociatedCompaniesT1\",\n        \"currentLiabilitiesAmountsOwingToDirectorT1\",\n        \"currentLiabilitiesProvisionForTaxationT1\",\n        \"currentLiabilitiesLeasePayablesT1\",\n        \"currentLiabilitiesFinanceLeasePayablesT1\",\n        \"currentLiabilitiesOtherPayablesT1\",\n        \"currentLiabilitiesDividendPayablesT1\",\n        \"currentLiabilitiesTradeAndOtherPayablesT1\",\n        \"currentLiabilitiesDepositsFromCustomersT1\",\n        \"currentLiabilitiesOtherPayablesAccrualsAndDepositsT1\",\n        \"currentLiabilitiesOtherPayablesAndAccrualsT1\",\n        \"currentLiabilitiesContractLiabilitiesT1\",\n        \"currentLiabilitiesDerivativeT1\",\n        \"totalCurrentLiabilitiesT1\",\n        \"shortTermLiabilitiesT1\",\n        \"nonCurrentLiabilitiesBorrowingsOrTermLoansT1\",\n        \"nonCurrentLiabilitiesBankBorrowingsT1\",\n        \"nonCurrentLiabilitiesLeaseObligationsT1\",\n        \"nonCurrentLiabilitiesFinanceLeaseObligationsT1\",\n        \"nonCurrentLiabilitiesDeferredTaxationT1\",\n        \"nonCurrentLiabilitiesRetirementBenefitsT1\",\n        \"nonCurrentLiabilitiesHirePurchasePayablesT1\",\n        \"nonCurrentLiabilitiesDepositsFromCustomersT1\",\n        \"nonCurrentLiabilitiesContractLiabilitiesT1\",\n        \"totalNonCurrentLiabilitiesT1\",\n        \"totalLiabilitiesT1\",\n        \"tangibleAssetsT1\",\n        \"shareCapitalT1\",\n        \"preferenceShareCapitalT1\",\n        \"sharePremiumT1\",\n        \"reservesT1\",\n        \"capitalReservesT1\",\n        \"revaluationReservesT1\",\n        \"exchangeEqualisationOrFluctuationReservesT1\",\n        \"retainedEarningsT1\",\n        \"totalEquityT1\",\n        \"revenueT1\",\n        \"costOfGoodsSoldT1\",\n        \"grossProfitT1\",\n        \"otherIncomeT1\",\n        \"profitFromOperationsT1\",\n        \"financeCostT1\",\n        \"ebitdaT1\",\n        \"taxesT1\",\n        \"zakatT1\",\n        \"profitAfterTaxT1\",\n        \"netProfitT1\",\n        \"netOperatingCashFlowT1\",\n        \"depreciationT1\",\n        \"depreciationOfPropertyPlantEquipmentT1\",\n        \"depreciationRightOfUseAssetsT1\",\n        \"depreciationOfInvestmentPropertiesT1\",\n        \"depreciationOfInvestmentSecuritiesT1\",\n        \"endOfYearCashT1\",\n        \"nonCurrentAssetsSubsidiaryCompaniesT2\",\n        \"nonCurrentAssetsAssociatedCompaniesT2\",\n        \"nonCurrentAssetsDevelopmentPropertiesOrExpenditureT2\",\n        \"nonCurrentAssetInvestmentPropertiesT2\",\n        \"nonCurrentAssetsInvestmentsT2\",\n        \"nonCurrentAssetInvestmentSecuritiesT2\",\n        \"nonCurrentAssetDeferredAssetsT2\",\n        \"nonCurrentAssetDepositsT2\",\n        \"nonCurrentAssetOwnGoodwillT2\",\n        \"nonCurrentAssetGoodwillOnConsolidationT2\",\n        \"nonCurrentAssetSinkingFundT2\",\n        \"nonCurrentAssetPropertyPlantEquipmentT2\",\n        \"nonCurrentAssetInventoriesT2\",\n        \"nonCurrentAssetRightOfUseAssetsT2\",\n        \"nonCurrentAssetIntangibleAssetsT2\",\n        \"nonCurrentAssetPrepaidLeasePaymentsT2\",\n        \"nonCurrentAssetFinancialAssetAtFairValueT2\",\n        \"nonCurrentAssetLandUseRightT2\",\n        \"nonCurrentAssetTradeReceivablesT2\",\n        \"nonCurrentAssetOtherReceivablesT2\",\n        \"nonCurrentAssetTradeAndOtherReceivablesT2\",\n        \"nonCurrentAssetOtherReceivablesDepositsAndPrepaymentsT2\",\n        \"totalNonCurrentAssetsT2\",\n        \"currentAssetDevelopmentPropertiesOrExpenditureT2\",\n        \"currentAssetShortTermInvestmentsT2\",\n        \"currentAssetTradeDebtorsT2\",\n        \"currentAssetShortTermDepositsT2\",\n        \"currentAssetAmountDueFromHoldingCompanyT2\",\n        \"currentAssetAmountDueFromSubsidiaryCompaniesT2\",\n        \"currentAssetAmountDueFromAssociatedCompaniesT2\",\n        \"currentAssetAmountDueFromDirectorT2\",\n        \"currentAssetAmountDueFromCustomerT2\",\n        \"currentAssetAmountOwingByShareholdersT2\",\n        \"currentAssetInventoriesT2\",\n        \"currentAssetFinancialAssetAtFairValueT2\",\n        \"currentAssetLandUseRightT2\",\n        \"currentAssetTaxRecoverableT2\",\n        \"currentAssetContractAssetsT2\",\n        \"currentAssetCurrentTaxAssetsT2\",\n        \"currentAssetPrepaymentsT2\",\n        \"currentAssetDerivativeT2\",\n        \"currentAssetCashAndBankBalancesT2\",\n        \"currentAssetOtherReceivablesT2\",\n        \"currentAssetRestrictedCashT2\",\n        \"currentAssetCashAndCashEquivalentsT2\",\n        \"currentAssetDepositsCashAndBankBalancesT2\",\n        \"currentAssetCashAtBanksT2\",\n        \"currentAssetCashOnHandT2\",\n        \"currentAssetDepositsAndPrepaymentsT2\",\n        \"currentAssetTradeAndOtherReceivablesT2\",\n        \"currentAssetOtherReceivablesDepositsAndPrepaymentsT2\",\n        \"currentAssetOtherReceivablesAndDepositsT2\",\n        \"currentAssetOtherReceivablesAndPrepaymentsT2\",\n        \"currentAssetCashT2\",\n        \"totalCurrentAssetsT2\",\n        \"totalAssetsT2\",\n        \"currentLiabilitiesTradeCreditorsT2\",\n        \"currentLiabilitiesHirePurchasePayablesT2\",\n        \"currentLiabilitiesBankOverdraftT2\",\n        \"currentLiabilitiesBankAcceptanceT2\",\n        \"currentLiabilitiesBorrowingsOrTermLoansT2\",\n        \"currentLiabilitiesBankborrowingsT2\",\n        \"currentLiabilitiesAmountsOwingToHoldingCompanyT2\",\n        \"currentLiabilitiesAmountsOwingToSubsidiaryCompaniesT2\",\n        \"currentLiabilitiesAmountOwingToAssociatedCompaniesT2\",\n        \"currentLiabilitiesAmountsOwingToDirectorT2\",\n        \"currentLiabilitiesProvisionForTaxationT2\",\n        \"currentLiabilitiesLeasePayablesT2\",\n        \"currentLiabilitiesFinanceLeasePayablesT2\",\n        \"currentLiabilitiesOtherPayablesT2\",\n        \"currentLiabilitiesDividendPayablesT2\",\n        \"currentLiabilitiesTradeAndOtherPayablesT2\",\n        \"currentLiabilitiesDepositsFromCustomersT2\",\n        \"currentLiabilitiesOtherPayablesAccrualsAndDepositsT2\",\n        \"currentLiabilitiesOtherPayablesAndAccrualsT2\",\n        \"currentLiabilitiesContractLiabilitiesT2\",\n        \"currentLiabilitiesDerivativeT2\",\n        \"totalCurrentLiabilitiesT2\",\n        \"shortTermLiabilitiesT2\",\n        \"nonCurrentLiabilitiesBorrowingsOrTermLoansT2\",\n        \"nonCurrentLiabilitiesBankBorrowingsT2\",\n        \"nonCurrentLiabilitiesLeaseObligationsT2\",\n        \"nonCurrentLiabilitiesFinanceLeaseObligationsT2\",\n        \"nonCurrentLiabilitiesDeferredTaxationT2\",\n        \"nonCurrentLiabilitiesRetirementBenefitsT2\",\n        \"nonCurrentLiabilitiesHirePurchasePayablesT2\",\n        \"nonCurrentLiabilitiesDepositsFromCustomersT2\",\n        \"nonCurrentLiabilitiesContractLiabilitiesT2\",\n        \"totalNonCurrentLiabilitiesT2\",\n        \"totalLiabilitiesT2\",\n        \"tangibleAssetsT2\",\n        \"shareCapitalT2\",\n        \"preferenceShareCapitalT2\",\n        \"sharePremiumT2\",\n        \"reservesT2\",\n        \"capitalReservesT2\",\n        \"revaluationReservesT2\",\n        \"exchangeEqualisationOrFluctuationReservesT2\",\n        \"retainedEarningsT2\",\n        \"totalEquityT2\",\n        \"revenueT2\",\n        \"costOfGoodsSoldT2\",\n        \"grossProfitT2\",\n        \"otherIncomeT2\",\n        \"profitFromOperationsT2\",\n        \"financeCostT2\",\n        \"ebitdaT2\",\n        \"taxesT2\",\n        \"zakatT2\",\n        \"profitAfterTaxT2\",\n        \"netProfitT2\",\n        \"netOperatingCashFlowT2\",\n        \"depreciationT2\",\n        \"depreciationOfPropertyPlantEquipmentT2\",\n        \"depreciationRightOfUseAssetsT2\",\n        \"depreciationOfInvestmentPropertiesT2\",\n        \"depreciationOfInvestmentSecuritiesT2\",\n        \"endOfYearCashT2\"\n      ],\n      \"category\": \"13\",\n      \"document_type\": \"financialStatements\",\n      \"document_group\": \"financials\",\n      \"document_group_label\": \"Audited Financial Statements\",\n      \"wire_format\": \"path_array\",\n      \"document_slot\": 1,\n      \"time_period_unit\": \"year\"\n    },\n    {\n      \"name\": \"financials_fincap_t2\",\n      \"displayName\": \"Audited Financial Statement (T-2) (FinCap)\",\n      \"type\": \"file\",\n      \"ihs_column_names\": [\n        \"nonCurrentAssetsSubsidiaryCompaniesT3\",\n        \"nonCurrentAssetsAssociatedCompaniesT3\",\n        \"nonCurrentAssetsDevelopmentPropertiesOrExpenditureT3\",\n        \"nonCurrentAssetInvestmentPropertiesT3\",\n        \"nonCurrentAssetsInvestmentsT3\",\n        \"nonCurrentAssetInvestmentSecuritiesT3\",\n        \"nonCurrentAssetDeferredAssetsT3\",\n        \"nonCurrentAssetDepositsT3\",\n        \"nonCurrentAssetOwnGoodwillT3\",\n        \"nonCurrentAssetGoodwillOnConsolidationT3\",\n        \"nonCurrentAssetSinkingFundT3\",\n        \"nonCurrentAssetPropertyPlantEquipmentT3\",\n        \"nonCurrentAssetInventoriesT3\",\n        \"nonCurrentAssetRightOfUseAssetsT3\",\n        \"nonCurrentAssetIntangibleAssetsT3\",\n        \"nonCurrentAssetPrepaidLeasePaymentsT3\",\n        \"nonCurrentAssetFinancialAssetAtFairValueT3\",\n        \"nonCurrentAssetLandUseRightT3\",\n        \"nonCurrentAssetTradeReceivablesT3\",\n        \"nonCurrentAssetOtherReceivablesT3\",\n        \"nonCurrentAssetTradeAndOtherReceivablesT3\",\n        \"nonCurrentAssetOtherReceivablesDepositsAndPrepaymentsT3\",\n        \"totalNonCurrentAssetsT3\",\n        \"currentAssetDevelopmentPropertiesOrExpenditureT3\",\n        \"currentAssetShortTermInvestmentsT3\",\n        \"currentAssetTradeDebtorsT3\",\n        \"currentAssetShortTermDepositsT3\",\n        \"currentAssetAmountDueFromHoldingCompanyT3\",\n        \"currentAssetAmountDueFromSubsidiaryCompaniesT3\",\n        \"currentAssetAmountDueFromAssociatedCompaniesT3\",\n        \"currentAssetAmountDueFromDirectorT3\",\n        \"currentAssetAmountDueFromCustomerT3\",\n        \"currentAssetAmountOwingByShareholdersT3\",\n        \"currentAssetInventoriesT3\",\n        \"currentAssetFinancialAssetAtFairValueT3\",\n        \"currentAssetLandUseRightT3\",\n        \"currentAssetTaxRecoverableT3\",\n        \"currentAssetContractAssetsT3\",\n        \"currentAssetCurrentTaxAssetsT3\",\n        \"currentAssetPrepaymentsT3\",\n        \"currentAssetDerivativeT3\",\n        \"currentAssetCashAndBankBalancesT3\",\n        \"currentAssetOtherReceivablesT3\",\n        \"currentAssetRestrictedCashT3\",\n        \"currentAssetCashAndCashEquivalentsT3\",\n        \"currentAssetDepositsCashAndBankBalancesT3\",\n        \"currentAssetCashAtBanksT3\",\n        \"currentAssetCashOnHandT3\",\n        \"currentAssetDepositsAndPrepaymentsT3\",\n        \"currentAssetTradeAndOtherReceivablesT3\",\n        \"currentAssetOtherReceivablesDepositsAndPrepaymentsT3\",\n        \"currentAssetOtherReceivablesAndDepositsT3\",\n        \"currentAssetOtherReceivablesAndPrepaymentsT3\",\n        \"currentAssetCashT3\",\n        \"totalCurrentAssetsT3\",\n        \"totalAssetsT3\",\n        \"currentLiabilitiesTradeCreditorsT3\",\n        \"currentLiabilitiesHirePurchasePayablesT3\",\n        \"currentLiabilitiesBankOverdraftT3\",\n        \"currentLiabilitiesBankAcceptanceT3\",\n        \"currentLiabilitiesBorrowingsOrTermLoansT3\",\n        \"currentLiabilitiesBankborrowingsT3\",\n        \"currentLiabilitiesAmountsOwingToHoldingCompanyT3\",\n        \"currentLiabilitiesAmountsOwingToSubsidiaryCompaniesT3\",\n        \"currentLiabilitiesAmountOwingToAssociatedCompaniesT3\",\n        \"currentLiabilitiesAmountsOwingToDirectorT3\",\n        \"currentLiabilitiesProvisionForTaxationT3\",\n        \"currentLiabilitiesLeasePayablesT3\",\n        \"currentLiabilitiesFinanceLeasePayablesT3\",\n        \"currentLiabilitiesOtherPayablesT3\",\n        \"currentLiabilitiesDividendPayablesT3\",\n        \"currentLiabilitiesTradeAndOtherPayablesT3\",\n        \"currentLiabilitiesDepositsFromCustomersT3\",\n        \"currentLiabilitiesOtherPayablesAccrualsAndDepositsT3\",\n        \"currentLiabilitiesOtherPayablesAndAccrualsT3\",\n        \"currentLiabilitiesContractLiabilitiesT3\",\n        \"currentLiabilitiesDerivativeT3\",\n        \"totalCurrentLiabilitiesT3\",\n        \"shortTermLiabilitiesT3\",\n        \"nonCurrentLiabilitiesBorrowingsOrTermLoansT3\",\n        \"nonCurrentLiabilitiesBankBorrowingsT3\",\n        \"nonCurrentLiabilitiesLeaseObligationsT3\",\n        \"nonCurrentLiabilitiesFinanceLeaseObligationsT3\",\n        \"nonCurrentLiabilitiesDeferredTaxationT3\",\n        \"nonCurrentLiabilitiesRetirementBenefitsT3\",\n        \"nonCurrentLiabilitiesHirePurchasePayablesT3\",\n        \"nonCurrentLiabilitiesDepositsFromCustomersT3\",\n        \"nonCurrentLiabilitiesContractLiabilitiesT3\",\n        \"totalNonCurrentLiabilitiesT3\",\n        \"totalLiabilitiesT3\",\n        \"tangibleAssetsT3\",\n        \"shareCapitalT3\",\n        \"preferenceShareCapitalT3\",\n        \"sharePremiumT3\",\n        \"reservesT3\",\n        \"capitalReservesT3\",\n        \"revaluationReservesT3\",\n        \"exchangeEqualisationOrFluctuationReservesT3\",\n        \"retainedEarningsT3\",\n        \"totalEquityT3\",\n        \"revenueT3\",\n        \"costOfGoodsSoldT3\",\n        \"grossProfitT3\",\n        \"otherIncomeT3\",\n        \"profitFromOperationsT3\",\n        \"financeCostT3\",\n        \"ebitdaT3\",\n        \"taxesT3\",\n        \"zakatT3\",\n        \"profitAfterTaxT3\",\n        \"netProfitT3\",\n        \"netOperatingCashFlowT3\",\n        \"depreciationT3\",\n        \"depreciationOfPropertyPlantEquipmentT3\",\n        \"depreciationRightOfUseAssetsT3\",\n        \"depreciationOfInvestmentPropertiesT3\",\n        \"depreciationOfInvestmentSecuritiesT3\",\n        \"endOfYearCashT3\"\n      ],\n      \"category\": \"13\",\n      \"document_type\": \"financialStatements\",\n      \"document_group\": \"financials\",\n      \"document_group_label\": \"Audited Financial Statements\",\n      \"wire_format\": \"path_array\",\n      \"document_slot\": 2,\n      \"time_period_unit\": \"year\"\n    },\n    {\n      \"name\": \"form9\",\n      \"displayName\": \"Form 9 / Section 17 / Form D\",\n      \"type\": \"file\",\n      \"ihs_column_names\": [\n        \"incorporatedDate\",\n        \"companyName\",\n        \"companyRegNo\"\n      ],\n      \"category\": \"13\",\n      \"document_type\": \"form9\",\n      \"document_group\": \"form9\",\n      \"document_group_label\": \"Form 9 / Section 17 / Form D\",\n      \"wire_format\": \"url_string\"\n    },\n    {\n      \"name\": \"ssm\",\n      \"displayName\": \"SSM Company Profile\",\n      \"type\": \"file\",\n      \"ihs_column_names\": [\n        \"ssmCompanyName\",\n        \"ssmCompanyRegNo\",\n        \"incorporatedDate\",\n        \"businessCommencementDate\",\n        \"businessNature\",\n        \"ssmCompanyEntityType\",\n        \"ssmPaidUpCapital\",\n        \"companyStatus\",\n        \"shareholders\",\n        \"directors\",\n        \"previousDirectors\",\n        \"totalShareIssued\",\n        \"companyLastOldName\",\n        \"companyNameDateOfChange\",\n        \"businessOrigin\",\n        \"registeredAddress\"\n      ],\n      \"category\": \"13\",\n      \"document_type\": \"ssm\",\n      \"document_group\": \"ssm_documents\",\n      \"document_group_label\": \"SSM Company Information\",\n      \"wire_format\": \"url_string\"\n    },\n    {\n      \"name\": \"ic\",\n      \"displayName\": \"Identification Card (Front)\",\n      \"type\": \"file\",\n      \"ihs_column_names\": [\n        \"icNumber\",\n        \"icName\",\n        \"icAddress\",\n        \"icGender\",\n        \"icReligion\",\n        \"icDateOfBirth\",\n        \"icPlaceOfBirth\",\n        \"icNationality\",\n        \"icRace\"\n      ],\n      \"category\": \"13\",\n      \"document_type\": \"ic\",\n      \"document_group\": \"ic_documents\",\n      \"document_group_label\": \"Identification Card\",\n      \"wire_format\": \"url_string\"\n    },\n    {\n      \"name\": \"epf_statement_t1\",\n      \"displayName\": \"Employees' Provident Fund (T-1)\",\n      \"type\": \"file\",\n      \"ihs_column_names\": [\n        \"epfAccountHolderNameT1\",\n        \"epfAccountHolderAddressT1\",\n        \"epfStatementYearT1\",\n        \"epfKwspMemberNumberT1\",\n        \"epfIcNumberT1\",\n        \"epfEmployerNumberT1\",\n        \"epfDateOfStatementT1\",\n        \"epfTotalContributionT1\",\n        \"epfTotalCurrentContributionT1\"\n      ],\n      \"category\": \"13\",\n      \"document_type\": \"epfStatements\",\n      \"document_group\": \"epf_statements\",\n      \"document_group_label\": \"EPF Statements\",\n      \"wire_format\": \"path_array\",\n      \"document_slot\": 1,\n      \"time_period_unit\": \"year\"\n    },\n    {\n      \"name\": \"epf_statement_t2\",\n      \"displayName\": \"Employees' Provident Fund (T-2)\",\n      \"type\": \"file\",\n      \"ihs_column_names\": [\n        \"epfAccountHolderNameT2\",\n        \"epfAccountHolderAddressT2\",\n        \"epfStatementYearT2\",\n        \"epfKwspMemberNumberT2\",\n        \"epfIcNumberT2\",\n        \"epfEmployerNumberT2\",\n        \"epfDateOfStatementT2\",\n        \"epfTotalContributionT2\",\n        \"epfTotalCurrentContributionT2\"\n      ],\n      \"category\": \"13\",\n      \"document_type\": \"epfStatements\",\n      \"document_group\": \"epf_statements\",\n      \"document_group_label\": \"EPF Statements\",\n      \"wire_format\": \"path_array\",\n      \"document_slot\": 2,\n      \"time_period_unit\": \"year\"\n    },\n    {\n      \"name\": \"payslip_statement_t1\",\n      \"displayName\": \"Payslip Statement (Month T-1)\",\n      \"type\": \"file\",\n      \"ihs_column_names\": [\n        \"payslipEmployerNameT1\",\n        \"payslipEmployeeNameT1\",\n        \"payslipPayPeriodT1\",\n        \"payslipPayDateT1\",\n        \"payslipGrossPayT1\",\n        \"payslipDeductionT1\",\n        \"payslipEmployeeEpfContributionT1\",\n        \"payslipEmployeeSocsoContributionT1\",\n        \"payslipNetPayT1\",\n        \"payslipBasicPayT1\",\n        \"payslipFixedAllowancesT1\",\n        \"payslipVariableIncomeT1\",\n        \"payslipEmployeeEisContributionT1\",\n        \"payslipEmployeeTaxT1\",\n        \"payslipOtherDeductionT1\"\n      ],\n      \"category\": \"13\",\n      \"document_type\": \"payslips\",\n      \"document_group\": \"payslip_statements\",\n      \"document_group_label\": \"Payslip Statements\",\n      \"wire_format\": \"path_array\",\n      \"document_slot\": 1,\n      \"time_period_unit\": \"month\"\n    },\n    {\n      \"name\": \"payslip_statement_t2\",\n      \"displayName\": \"Payslip Statement (Month T-2)\",\n      \"type\": \"file\",\n      \"ihs_column_names\": [\n        \"payslipEmployerNameT2\",\n        \"payslipEmployeeNameT2\",\n        \"payslipPayPeriodT2\",\n        \"payslipPayDateT2\",\n        \"payslipGrossPayT2\",\n        \"payslipDeductionT2\",\n        \"payslipEmployeeEpfContributionT2\",\n        \"payslipEmployeeSocsoContributionT2\",\n        \"payslipNetPayT2\",\n        \"payslipBasicPayT2\",\n        \"payslipFixedAllowancesT2\",\n        \"payslipVariableIncomeT2\",\n        \"payslipEmployeeEisContributionT2\",\n        \"payslipEmployeeTaxT2\",\n        \"payslipOtherDeductionT2\"\n      ],\n      \"category\": \"13\",\n      \"document_type\": \"payslips\",\n      \"document_group\": \"payslip_statements\",\n      \"document_group_label\": \"Payslip Statements\",\n      \"wire_format\": \"path_array\",\n      \"document_slot\": 2,\n      \"time_period_unit\": \"month\"\n    },\n    {\n      \"name\": \"payslip_statement_t3\",\n      \"displayName\": \"Payslip Statement (Month T-3)\",\n      \"type\": \"file\",\n      \"ihs_column_names\": [\n        \"payslipEmployerNameT3\",\n        \"payslipEmployeeNameT3\",\n        \"payslipPayPeriodT3\",\n        \"payslipPayDateT3\",\n        \"payslipGrossPayT3\",\n        \"payslipDeductionT3\",\n        \"payslipEmployeeEpfContributionT3\",\n        \"payslipEmployeeSocsoContributionT3\",\n        \"payslipNetPayT3\",\n        \"payslipBasicPayT3\",\n        \"payslipFixedAllowancesT3\",\n        \"payslipVariableIncomeT3\",\n        \"payslipEmployeeEisContributionT3\",\n        \"payslipEmployeeTaxT3\",\n        \"payslipOtherDeductionT3\"\n      ],\n      \"category\": \"13\",\n      \"document_type\": \"payslips\",\n      \"document_group\": \"payslip_statements\",\n      \"document_group_label\": \"Payslip Statements\",\n      \"wire_format\": \"path_array\",\n      \"document_slot\": 3,\n      \"time_period_unit\": \"month\"\n    },\n    {\n      \"name\": \"payslip_statement_t4\",\n      \"displayName\": \"Payslip Statement (Month T-4)\",\n      \"type\": \"file\",\n      \"ihs_column_names\": [\n        \"payslipEmployerNameT4\",\n        \"payslipEmployeeNameT4\",\n        \"payslipPayPeriodT4\",\n        \"payslipPayDateT4\",\n        \"payslipGrossPayT4\",\n        \"payslipDeductionT4\",\n        \"payslipEmployeeEpfContributionT4\",\n        \"payslipEmployeeSocsoContributionT4\",\n        \"payslipNetPayT4\",\n        \"payslipBasicPayT4\",\n        \"payslipFixedAllowancesT4\",\n        \"payslipVariableIncomeT4\",\n        \"payslipEmployeeEisContributionT4\",\n        \"payslipEmployeeTaxT4\",\n        \"payslipOtherDeductionT4\"\n      ],\n      \"category\": \"13\",\n      \"document_type\": \"payslips\",\n      \"document_group\": \"payslip_statements\",\n      \"document_group_label\": \"Payslip Statements\",\n      \"wire_format\": \"path_array\",\n      \"document_slot\": 4,\n      \"time_period_unit\": \"month\"\n    },\n    {\n      \"name\": \"payslip_statement_t5\",\n      \"displayName\": \"Payslip Statement (Month T-5)\",\n      \"type\": \"file\",\n      \"ihs_column_names\": [\n        \"payslipEmployerNameT5\",\n        \"payslipEmployeeNameT5\",\n        \"payslipPayPeriodT5\",\n        \"payslipPayDateT5\",\n        \"payslipGrossPayT5\",\n        \"payslipDeductionT5\",\n        \"payslipEmployeeEpfContributionT5\",\n        \"payslipEmployeeSocsoContributionT5\",\n        \"payslipNetPayT5\",\n        \"payslipBasicPayT5\",\n        \"payslipFixedAllowancesT5\",\n        \"payslipVariableIncomeT5\",\n        \"payslipEmployeeEisContributionT5\",\n        \"payslipEmployeeTaxT5\",\n        \"payslipOtherDeductionT5\"\n      ],\n      \"category\": \"13\",\n      \"document_type\": \"payslips\",\n      \"document_group\": \"payslip_statements\",\n      \"document_group_label\": \"Payslip Statements\",\n      \"wire_format\": \"path_array\",\n      \"document_slot\": 5,\n      \"time_period_unit\": \"month\"\n    },\n    {\n      \"name\": \"payslip_statement_t6\",\n      \"displayName\": \"Payslip Statement (Month T-6)\",\n      \"type\": \"file\",\n      \"ihs_column_names\": [\n        \"payslipEmployerNameT6\",\n        \"payslipEmployeeNameT6\",\n        \"payslipPayPeriodT6\",\n        \"payslipPayDateT6\",\n        \"payslipGrossPayT6\",\n        \"payslipDeductionT6\",\n        \"payslipEmployeeEpfContributionT6\",\n        \"payslipEmployeeSocsoContributionT6\",\n        \"payslipNetPayT6\",\n        \"payslipBasicPayT6\",\n        \"payslipFixedAllowancesT6\",\n        \"payslipVariableIncomeT6\",\n        \"payslipEmployeeEisContributionT6\",\n        \"payslipEmployeeTaxT6\",\n        \"payslipOtherDeductionT6\"\n      ],\n      \"category\": \"13\",\n      \"document_type\": \"payslips\",\n      \"document_group\": \"payslip_statements\",\n      \"document_group_label\": \"Payslip Statements\",\n      \"wire_format\": \"path_array\",\n      \"document_slot\": 6,\n      \"time_period_unit\": \"month\"\n    }\n  ]\n}\n","{\n  \"version\": 2,\n  \"types\": [\n    {\n      \"displayName\": \"Text\",\n      \"name\": \"text\"\n    },\n    {\n      \"displayName\": \"Number\",\n      \"name\": \"number\"\n    },\n    {\n      \"displayName\": \"Email\",\n      \"name\": \"email\"\n    },\n    {\n      \"displayName\": \"Dropdown\",\n      \"name\": \"dropdown\"\n    },\n    {\n      \"displayName\": \"Checkbox\",\n      \"name\": \"checkbox\"\n    },\n    {\n      \"displayName\": \"Radio Group\",\n      \"name\": \"radiogroup\"\n    },\n    {\n      \"displayName\": \"Boolean\",\n      \"name\": \"boolean\"\n    },\n    {\n      \"displayName\": \"File\",\n      \"name\": \"file\"\n    },\n    {\n      \"displayName\": \"Slider\",\n      \"name\": \"slider\"\n    },\n    {\n      \"displayName\": \"Range\",\n      \"name\": \"range\"\n    },\n    {\n      \"displayName\": \"Long Text (Comment)\",\n      \"name\": \"comment\"\n    },\n    {\n      \"displayName\": \"HTML Content\",\n      \"name\": \"html\"\n    }\n  ],\n  \"input_types\": [\n    {\n      \"displayName\": \"Text\",\n      \"name\": \"text\"\n    },\n    {\n      \"displayName\": \"Number\",\n      \"name\": \"number\"\n    },\n    {\n      \"displayName\": \"Email\",\n      \"name\": \"email\"\n    },\n    {\n      \"displayName\": \"Tel\",\n      \"name\": \"tel\"\n    },\n    {\n      \"displayName\": \"Date\",\n      \"name\": \"date\"\n    },\n    {\n      \"displayName\": \"Password\",\n      \"name\": \"password\"\n    },\n    {\n      \"displayName\": \"URL\",\n      \"name\": \"url\"\n    }\n  ]\n}\n","{\n  \"version\": 1,\n  \"options\": [\n    {\n      \"id\": 1,\n      \"displayName\": \"Numeric Validator\",\n      \"class\": \"NumericValidator\",\n      \"description\": \"Ensures the answer is a number within the specified range of minValue and maxValue.\",\n      \"isRequired\": true,\n      \"validators\": [\n        {\n          \"type\": \"numeric\",\n          \"text\": \"Value must be within the range of 0 to 100\",\n          \"minValue\": 0,\n          \"maxValue\": 100\n        }\n      ]\n    },\n    {\n      \"id\": 2,\n      \"displayName\": \"Text Length Validator\",\n      \"class\": \"TextValidator\",\n      \"description\": \"Confirms the length of entered text is between minLength and maxLength.\",\n      \"isRequired\": true,\n      \"validators\": [\n        {\n          \"type\": \"text\",\n          \"minLength\": 10,\n          \"maxLength\": 280\n        }\n      ]\n    },\n    {\n      \"id\": 3,\n      \"displayName\": \"Regex Validator\",\n      \"class\": \"RegexValidator\",\n      \"description\": \"Throws an error if an entered value does not match a regular expression defined in the regex property.\",\n      \"isRequired\": true,\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"text\": \"The value must match the required pattern.\",\n          \"regex\": \"your-regex-pattern-here\"\n        }\n      ]\n    },\n    {\n      \"id\": 4,\n      \"displayName\": \"Email Validator\",\n      \"class\": \"EmailValidator\",\n      \"description\": \"Confirms that the entered value is a valid e-mail address.\",\n      \"isRequired\": true,\n      \"validators\": [\n        {\n          \"type\": \"email\",\n          \"text\": \"Value must be a valid email\"\n        }\n      ]\n    },\n    {\n      \"id\": 5,\n      \"displayName\": \"Expression Validator\",\n      \"class\": \"ExpressionValidator\",\n      \"isRequired\": true,\n      \"description\": \"Ensures that the field's expression always evaluates to true.\",\n      \"validators\": [\n        {\n          \"type\": \"expression\",\n          \"expression\": \"{fields} = true\",\n          \"text\": \"The value must be true and cannot be false.\"\n        }\n      ]\n    },\n    {\n      \"id\": 6,\n      \"displayName\": \"Answer Count Validator\",\n      \"class\": \"AnswerCountValidator\",\n      \"isRequired\": true,\n      \"description\": \"Ensures selection of an appropriate number of choices, keeping responses within the minCount and maxCount range.\",\n      \"validators\": [\n        {\n          \"type\": \"answercount\",\n          \"minCount\": 2,\n          \"maxCount\": 4\n        }\n      ]\n    },\n    {\n      \"id\": 7,\n      \"displayName\": \"Full Name Regex Validator\",\n      \"class\": \"RegexValidator\",\n      \"isRequired\": true,\n      \"description\": \"Ensures that the entered value is a valid full name.\",\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"text\": \"Please make sure the name doesn't include extra spaces, numbers, or invalid symbols\",\n          \"regex\": \"^[A-Za-z'-]+(?:\\\\s[A-Za-z'-]+)*\\\\s?[A-Za-z'-]+$\"\n        }\n      ]\n    },\n    {\n      \"id\": 8,\n      \"displayName\": \"Mobile Phone No Regex Validator\",\n      \"class\": \"RegexValidator\",\n      \"isRequired\": true,\n      \"description\": \"Ensures valid Malaysia phone number is entered.\",\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"text\": \"A valid Malaysia phone number is required.\",\n          \"regex\": \"^(011[0-9]{8}|01[2346789][0-9]{7}|[2-9][0-9]{0,8})$\"\n        }\n      ]\n    },\n    {\n      \"id\": 9,\n      \"displayName\": \"IC Number Total Digits Regex Validator\",\n      \"class\": \"RegexValidator\",\n      \"isRequired\": true,\n      \"description\": \"Ensures exactly 12 digits are entered for the IC number.\",\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"regex\": \"^\\\\d{12}$\",\n          \"text\": \"Please enter exactly 12 digits numbers\"\n        }\n      ]\n    },\n    {\n      \"id\": 10,\n      \"displayName\": \"IC Number Valid Birth Year, Month, and Date Regex Validator\",\n      \"class\": \"RegexValidator\",\n      \"isRequired\": true,\n      \"description\": \"Ensures valid birth year, month, and day are entered for the IC number.\",\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"regex\": \"^(\\\\d{2})(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])\\\\d{6}$\",\n          \"text\": \"First 6 digits must be valid birth year (00-99), month (01-12), and day (01-31)\"\n        }\n      ]\n    },\n    {\n      \"id\": 11,\n      \"displayName\": \"Duration in Current Residence (Months) Regex Validator\",\n      \"class\": \"RegexValidator\",\n      \"isRequired\": true,\n      \"description\": \"Ensures duration includes a number between 0-11.\",\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"regex\": \"^([0-9]|10|11)$\",\n          \"text\": \"Value must be a number between 0-11.\"\n        }\n      ]\n    },\n    {\n      \"id\": 12,\n      \"displayName\": \"Duration in Current Residence (Years) Regex Validator\",\n      \"class\": \"RegexValidator\",\n      \"isRequired\": true,\n      \"description\": \"Ensures duration includes a number between 0-99.\",\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"regex\": \"^([0-9]|[1-9][0-9])$\",\n          \"text\": \"Value must be a number between 0-99.\"\n        }\n      ]\n    },\n    {\n      \"id\": 13,\n      \"displayName\": \"Office Phone No. Regex Validator\",\n      \"class\": \"RegexValidator\",\n      \"isRequired\": true,\n      \"description\": \"Ensures office phone number is entered in the correct format.\",\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"text\": \"The phone number must be a valid Malaysian number\",\n          \"regex\": \"^(011[0-9]{8}|(60[4-7]|004|005|006|007|009|609|012|013|014|016|017|019)[0-9]{7})$\"\n        }\n      ]\n    },\n    {\n      \"id\": 14,\n      \"displayName\": \"Age Regex Validator\",\n      \"class\": \"RegexValidator\",\n      \"isRequired\": true,\n      \"description\": \"Ensures age entered is between 21-55.\",\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"text\": \"Please enter a valid whole number age between 21 and 55.\",\n          \"regex\": \"^(2[1-9]|[3-4][0-9]|55)$\"\n        }\n      ]\n    },\n    {\n      \"id\": 15,\n      \"displayName\": \"Consent(s) Expression Validator\",\n      \"class\": \"ExpressionValidator\",\n      \"isRequired\": true,\n      \"description\": \"Ensures that the field's expression always evaluates to true.\",\n      \"validators\": [\n        {\n          \"type\": \"expression\",\n          \"expression\": \"{consentCrossSelling} = true\",\n          \"text\": \"You must provide consent to Consent Cross-Selling.\"\n        }\n      ]\n    },\n    {\n      \"id\": 16,\n      \"displayName\": \"Date Joined Regex Validator\",\n      \"class\": \"RegexValidator\",\n      \"isRequired\": true,\n      \"description\": \"Ensures date joined is in the correct format.\",\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"regex\": \"^\\\\d{4}-\\\\d{2}-\\\\d{2}$\",\n          \"text\": \"Date must be in YYYY-MM-DD format\"\n        }\n      ]\n    },\n    {\n      \"id\": 17,\n      \"displayName\": \"Date Joined Custom Validator\",\n      \"class\": \"CustomValidator\",\n      \"isRequired\": true,\n      \"description\": \"Ensures date joined is not in the future.\",\n      \"validators\": [\n        {\n          \"type\": \"custom\",\n          \"validator\": \"validateNotFutureDate\",\n          \"text\": \"Date of joining cannot be in the future\"\n        }\n      ]\n    },\n    {\n      \"id\": 18,\n      \"displayName\": \"Emergency Contact No. Regex Validator\",\n      \"class\": \"RegexValidator\",\n      \"isRequired\": true,\n      \"description\": \"Ensures emergency contact number is entered in the correct format.\",\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"text\": \"A valid Malaysia phone number is required.\",\n          \"regex\": \"^((60[4-79]|0[4-79])[0-9]{7}|011[0-9]{8}|01[2346789][0-9]{7})$\"\n        }\n      ]\n    },\n    {\n      \"id\": 19,\n      \"displayName\": \"Monthly Gross Income Regex Validator\",\n      \"class\": \"RegexValidator\",\n      \"isRequired\": true,\n      \"description\": \"Ensures monthly gross income is entered in the correct format.\",\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"regex\": \"^\\\\d+(\\\\.\\\\d+)?$\",\n          \"text\": \"Please enter a valid non-negative number.\"\n        }\n      ]\n    },\n    {\n      \"id\": 20,\n      \"displayName\": \"Monthly Gross Income Expression Validator\",\n      \"class\": \"ExpressionValidator\",\n      \"isRequired\": true,\n      \"description\": \"Ensures monthly gross income is at least RM 2000.\",\n      \"validators\": [\n        {\n          \"type\": \"expression\",\n          \"expression\": \"{monthlyGrossIncome} >= 2000\",\n          \"text\": \"Income must be at least RM 2000.\"\n        }\n      ]\n    },\n    {\n      \"id\": 21,\n      \"displayName\": \"No of Dependants Regex Validator\",\n      \"class\": \"RegexValidator\",\n      \"isRequired\": true,\n      \"description\": \"Ensures number of dependants is entered in the correct format.\",\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"text\": \"Please enter a valid whole number between 0 and 99.\",\n          \"regex\": \"^[0-9][0-9]?$\"\n        }\n      ]\n    },\n    {\n      \"id\": 22,\n      \"displayName\": \"Financing Tenure (Years) Regex Validator\",\n      \"class\": \"RegexValidator\",\n      \"isRequired\": true,\n      \"description\": \"Ensures financing tenure is entered in the correct format.\",\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"text\": \"Please enter a valid financing tenure from 1 to 7 years.\",\n          \"regex\": \"^[1-7]$\"\n        }\n      ]\n    },\n    {\n      \"id\": 23,\n      \"displayName\": \"Financing Amount Range Regex Validator\",\n      \"class\": \"RegexValidator\",\n      \"isRequired\": true,\n      \"description\": \"Ensures financing amount is entered in the correct format.\",\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"text\": \"Please enter a financing amount between 2,000 and 150,000.\",\n          \"regex\": \"^(2000|[1-9][0-9]{3}|[1-9][0-9]{4}|150000)$\"\n        }\n      ]\n    },\n    {\n      \"id\": 24,\n      \"displayName\": \"Financing Amount Incrementals Regex Validator\",\n      \"class\": \"RegexValidator\",\n      \"isRequired\": true,\n      \"description\": \"Ensures financing amount is entered incrementally in the correct format.\",\n      \"validators\": [\n        {\n          \"type\": \"regex\",\n          \"text\": \"Please enter an amount in increments of 1,000.\",\n          \"regex\": \"^([1-9][0-9]*000|150000)$\"\n        }\n      ]\n    }\n  ]\n}\n","/*\n * Copyright 2025 Sisters Inspire Sdn Bhd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { FieldData, Category } from \"./survey-generator.js\";\nimport type { FormFieldTypeDefinitions, EditorValidator } from \"./form-field.js\";\nimport type { FormValidatorDefinitions } from \"./form-field-validator.js\";\nimport FormField from \"./form-field.js\";\nimport baseSpecsData from \"./data/form-field-base-specs.json\" with { type: \"json\" };\nimport typeDefsData from \"./data/form-field-types.json\" with { type: \"json\" };\nimport validatorDefsData from \"./data/form-field-validators.json\" with { type: \"json\" };\n\nexport const BASE_FIELD_SPECS: {\n  schemaVersion: string;\n  categories: Category[];\n  fields: FieldData[];\n} = baseSpecsData as any;\n\nexport const FIELD_TYPE_DEFINITIONS: FormFieldTypeDefinitions = typeDefsData as FormFieldTypeDefinitions;\n\nexport const DEFAULT_VALIDATOR_DEFINITIONS: FormValidatorDefinitions = {\n  version: (validatorDefsData as any).version,\n  options: (validatorDefsData as any).options as EditorValidator[],\n};\n\nexport function getBaseFieldSpecs(): FieldData[] {\n  return BASE_FIELD_SPECS.fields;\n}\n\nexport function getBaseCategories(): Category[] {\n  return BASE_FIELD_SPECS.categories;\n}\n\nlet cachedFieldSpecMap: Map<string, FieldData> | null = null;\n\n/**\n * Returns a cached Map of base field name → FieldData.\n * Keyed by each field's `name` property from the base specs.\n */\nexport function getBaseFieldSpecMap(): Map<string, FieldData> {\n  if (cachedFieldSpecMap) {\n    return cachedFieldSpecMap;\n  }\n\n  const map = new Map<string, FieldData>();\n  for (const field of BASE_FIELD_SPECS.fields) {\n    if (field.name) {\n      map.set(field.name, field);\n    }\n  }\n\n  cachedFieldSpecMap = map;\n  return cachedFieldSpecMap;\n}\n\nlet cachedFieldNames: string[] | null = null;\n\nexport function getBaseFieldNames(): string[] {\n  if (cachedFieldNames) {\n    return cachedFieldNames;\n  }\n\n  const fields = BASE_FIELD_SPECS.fields;\n  const names: string[] = [];\n\n  for (const field of fields) {\n    try {\n      const formField = FormField.fromObject(field);\n      names.push(...formField.getFieldNames());\n    } catch {\n      // Skip fields that fail to parse\n    }\n  }\n\n  cachedFieldNames = [...new Set(names)];\n  return cachedFieldNames;\n}\n","/*\n * IHS data processing types.\n * Used by finsys-client and finhub-adonisjs to render application details.\n */\n\nexport enum IhsValueFormat {\n  STRING = 'string',\n  CURRENCY = 'currency',\n  NUMBER = 'number',\n  PERCENTAGE = 'percentage',\n  DATE = 'date',\n  TABLE = 'table',\n}\n\nexport interface IhsFieldDetail {\n  name: string\n  displayName: string\n  category: string\n  value: unknown\n  valueFormat: IhsValueFormat\n}\n\nexport interface IhsDetailCategory {\n  category: string\n  items: { name: string; displayName: string; value: unknown; valueFormat: IhsValueFormat }[]\n}\n\nexport enum FileFieldTableType {\n  TIME_SERIES = 'timeSeries',\n  KEY_VALUE = 'keyValue',\n}\n\n/**\n * Per-field extraction provenance (SYS-2737/SYS-2741). The single canonical\n * envelope — finsys-api writes it (ihs_field_metadata), finsys-core surfaces it\n * onto detail cells, both consumers render it. Vocabulary mirrors adapter_runs\n * (SYS-2441) so FinXtract + adapter provenance converge at SYS-2499 Phase 5.\n *\n *   source      — who produced the value, e.g. \"finxtract:ssm\"\n *   confidence  — normalized 0..1; null when derived/computed (no score)\n *   observedAt  — ISO wall-clock of the extraction run\n *   sourceRunId — the extraction run/job id that wrote it\n *   origin      — \"extracted\" (a real {value,confidence} leaf) vs \"derived\"\n *                 (computed / no-confidence path) vs \"manual\" (SYS-2806, a\n *                 lender-entered correction, committed once its edit overlay\n *                 is approved). A \"derived\" field must render as \"no\n *                 confidence available\", never a fabricated low score; a\n *                 \"manual\" field must render as an edit indicator, not a\n *                 confidence dot — confidence is always null for it too.\n */\n/**\n * Canonical origin values, single source of truth (Gemini-review finding:\n * avoids duplicating the literal strings between the type and the runtime\n * guard) -- mirrors the IhsStatus/IHS_VALID_STATUSES pattern in\n * ihs-status.ts.\n */\nexport const IHS_FIELD_ORIGINS = ['extracted', 'derived', 'manual'] as const\nexport type IhsFieldOrigin = (typeof IHS_FIELD_ORIGINS)[number]\n\nexport interface IhsFieldProvenance {\n  source: string\n  confidence: number | null\n  /**\n   * ISO wall-clock of the extraction run.\n   *\n   * SYS-3334 F7/F10 (round 2): `fieldProvenanceFromView` (ihs-processing.ts)\n   * writes `''` here when the source instance carries no `observedAt` at\n   * all — kept a required `string` rather than made optional, because\n   * loosening this type ripples into every consumer that already\n   * destructures it as one (a required→optional change is exactly the kind\n   * of narrowing-at-the-read-site this package's semver discipline tries to\n   * avoid inflicting on downstream `tsc` builds). A reader that formats this\n   * value must treat `''` the same as \"unknown\", exactly as it must already\n   * treat a value that never arrived: `new Date('')` is `Invalid Date`, not\n   * a thrown error, so a caller that skips the guard fails quietly rather\n   * than loudly. Documented here rather than fixed silently, so the sentinel\n   * is a decision on record instead of a bug waiting to be rediscovered.\n   */\n  observedAt: string\n  sourceRunId: string | null\n  origin: IhsFieldOrigin\n  /**\n   * SYS-3249: the denomination of a monetary value (ISO 4217, e.g. \"MYR\",\n   * \"VND\", \"THB\"). Present only for `kind: \"money\"` canonical fields.\n   *\n   * It lives here rather than on the field definition because currency is\n   * a property of the OBSERVATION, not of the field: one source can report\n   * several currencies in a single document, so a field-level currency\n   * could never be right for more than one of them. This envelope is\n   * already written per-field, by the same call that writes the value, at\n   * the same instant — which is exactly the granularity a denomination\n   * needs.\n   *\n   * OPTIONAL, and absence is not \"no currency\" — it is \"written before\n   * SYS-3249, or by a producer that does not yet record one\". Readers must\n   * treat absence as unknown and say so, never as a default currency. A\n   * value silently rendered in the wrong denomination is the failure this\n   * field exists to prevent, and defaulting would reintroduce it wearing a\n   * different hat.\n   *\n   * PRECEDENCE against the document-level `currency` canonical field.\n   * `finxtract-financial-statement` also declares a canonical field named\n   * `currency` (\"Reporting currency stated on the document\"). The two are\n   * not rivals and must not be merged:\n   *\n   *   - that field is the DOCUMENT's declared reporting currency, one value\n   *     per statement, and is a data point in its own right;\n   *   - this is the denomination of ONE observed value.\n   *\n   * This wins wherever both exist, because the whole reason currency sits on\n   * the observation is that a single document can report several — an FX\n   * transaction, a foreign-currency balance. When this is absent the document\n   * field is a reasonable SOURCE for a producer populating it, but it is not\n   * a substitute at read time: a reader that falls back to it would state a\n   * denomination the value never claimed.\n   */\n  currency?: string\n}\n\n/**\n * `IhsFieldProvenance` plus the value an overlay projection REPLACED.\n *\n * SYS-3334 F3 (round 2): `fieldProvenanceFromView` synthesizes provenance\n * from `CanonicalView` envelopes, which — under a lender-overlay projection\n * (`?overlay=mine`) — can carry `originalValue` (`CanonicalFieldEnvelope`'s\n * own member: the attested value a staged edit is standing in for). Plain\n * `IhsFieldProvenance` has nowhere to put that; widening it for every\n * consumer to carry an almost-always-absent member is the wrong trade for\n * what only this one path needs, so it is a separate, ADDITIVE type instead.\n * `originalValue` is `unknown` rather than the envelope's own\n * `number | boolean | string`, because a table cell already renders `unknown`\n * data (`FileFieldTableItem.data`) and narrowing it here would just move the\n * cast to every caller.\n */\nexport type IhsFieldProvenanceWithOriginal = IhsFieldProvenance & { originalValue?: unknown }\n\n/**\n * Type guard: narrows an unknown value to `IhsFieldOrigin` iff it is one of\n * the three canonical origin strings. `origin` was previously validated\n * only by the TS union — this is the first runtime check.\n */\nexport function isValidIhsFieldOrigin(origin: unknown): origin is IhsFieldOrigin {\n  return typeof origin === 'string' && (IHS_FIELD_ORIGINS as readonly string[]).includes(origin)\n}\n\nexport interface FileFieldTableItem {\n  displayName: string\n  timePeriods: string[]\n  data: Record<string, unknown>\n  formattedData: Record<string, string>\n  type: FileFieldTableType\n  isNumeric: boolean\n  /**\n   * SYS-2741: per-cell extraction provenance, keyed exactly like `data` (period\n   * key for TIME_SERIES, `'value'` for KEY_VALUE). `confidence` carries only\n   * scored (origin 'extracted') cells so a numeric dot never renders for a\n   * derived value; `provenance` carries the full envelope for every known cell.\n   */\n  confidence?: Record<string, number>\n  provenance?: Record<string, IhsFieldProvenance>\n}\n\nexport interface FileFieldTableData {\n  name: string\n  displayName: string\n  type: FileFieldTableType\n  items: FileFieldTableItem[]\n  hasData: boolean\n}\n\n/**\n * One sibling-table row as finsys-api's `docInstanceStorageService` writes\n * it (SYS-2842) -- the unbounded counterpart to a T{n}-suffixed wide-table\n * slot. `instanceKey` is the real, collision-free per-document key;\n * `sourceLabel` is a human label when the doc type has one (e.g. a bank\n * name); `timePeriod` is the same descriptive value column the legacy\n * T{n} scheme used, kept for period-labeling and legacy provenance lookup\n * (SYS-2886 Phase 5) -- no longer the row's key. Metric fields are the\n * category's own base (unsuffixed) column names.\n */\nexport interface InstanceRow {\n  instanceKey: string\n  sourceLabel?: string | null\n  timePeriod?: string | null\n  [metricKey: string]: unknown\n}\n\n// ── Documents table (SYS-2765 / SYS-2766) ──────────────────────\n\n/**\n * Per-document File metadata attached by finsys-api `getIhsDetailsById` as the\n * `documentMetadata` sibling map (SYS-2765), keyed by the document's raw stored\n * path. The single source for the documents table's Type / Size / Uploaded\n * columns — the IHS doc fields themselves carry only the path.\n */\nexport interface DocumentFileMetadata {\n  fileName: string | null\n  fileType: string | null\n  fileSize: number | null\n  createdAt: string | null\n}\n\n/**\n * Intrinsic, data-derived capability eligibility for a document row. Reflects\n * ONLY what the IHS payload implies (doc type + a resolvable file); the consumer\n * ANDs in its own runtime gates (readOnly, allowReupload, and — for viewJson —\n * whether extraction has actually completed) before showing a control.\n */\nexport interface DocumentRowCapabilities {\n  /** A downloadable original exists (a resolvable documentId). */\n  download: boolean\n  /** The doc type produces extracted JSON (consumer still gates on \"Extracted\"). */\n  viewJson: boolean\n  /** The doc type can be re-extracted. */\n  reExtract: boolean\n  /** The doc type accepts a replacement upload (finsys-api /ihs/client/update/document). */\n  reUpload: boolean\n}\n\n/**\n * One uploaded document, presentation-agnostic — built by `buildDocumentRows`\n * from the IHS payload + its `documentMetadata` map. Rendered identically by\n * FinHub (React) and finsys-client (Edge). Live extraction status + confidence\n * are NOT payload-derived; the consumer overlays them by matching\n * `(docType, timePeriod)`.\n */\nexport interface DocumentRow {\n  /** IHS field key, e.g. 'bankStatements'. */\n  docType: string\n  /** Human label for the doc-type group, e.g. 'Bank Statements'. */\n  label: string\n  /** 0-based position within the docType group. */\n  index: number\n  /** Best display name (resolved file name, or a label + period/index fallback). */\n  displayName: string\n  /** Id for the download link; null when no file path is resolvable. */\n  documentId: string | null\n  /** Raw stored path — the join key back to `documentMetadata`. */\n  path: string | null\n  /** Extraction time-period token: 'T{month|year}' or 'ALL'. */\n  timePeriod: string\n  /** Human period label ('Jan 2026' / 'Year 2024') or null. */\n  periodLabel: string | null\n  /** Resolved file name; null when the stored name looks like an opaque id. */\n  fileName: string | null\n  /** File type label (extension → MIME subtype, upper-cased) or null. */\n  fileType: string | null\n  /** File size in bytes, or null when unknown. */\n  fileSize: number | null\n  /** ISO upload timestamp (File.createdAt) or null. */\n  uploadedAt: string | null\n  /** Intrinsic capability eligibility (consumer overlays its runtime gates). */\n  capabilities: DocumentRowCapabilities\n}\n","/*\n * Document type registry.\n *\n * Single source of truth for \"which FinXtract document types exist,\"\n * derived directly from the field-spec catalog (form-field-base-specs.json)\n * instead of hand-synchronized code. This replaces four previously-separate\n * structures that had to be edited together by hand:\n *   - extraction.ts's closed ExtractionFileType enum\n *   - extraction-status.ts's FILE_TYPE_TO_GROUP map\n *   - ihs-processing.ts's FIELD_GROUP_PREFIXES + GROUP_DISPLAY_NAMES\n *\n * Adding a new document type (e.g. invoices) is now a data-only edit to\n * form-field-base-specs.json -- tag its `type: 'file'` entries with\n * document_type/document_group/document_group_label/wire_format, no\n * TypeScript union to edit, no exhaustive map to keep in sync by hand.\n *\n * Six distinct properties, because real consumer code depends on each\n * independently (confirmed by direct trace, not assumed):\n *   - document_type: the wire/dispatch value (e.g. \"bankStatements\") --\n *     what File.type, processIhsUpdate's switch, and ocrValidator's\n *     allowlist key on.\n *   - document_group: the render/table grouping key (e.g. \"ssm_documents\")\n *     -- what buildFileFieldTables's output is keyed by. finsys-client's\n *     ihs_controller.ts specifically special-cases the literal string\n *     \"ssm_documents\" (skips it in favor of a dedicated partial), so this\n *     must stay a distinct, stable value from document_type, not merged.\n *   - document_group_label: human-friendly table/status display label.\n *   - wire_format: reserved for a future @finsys/borrower-client\n *     consolidation of its own payload-transfer.ts registry (not consumed\n *     by anything in this package yet) -- 'path_array' | 'url_string' |\n *     'path_only', mirroring the shapes borrower-client already uses.\n *   - document_slot: which UPLOAD position this field represents (1st\n *     document, 2nd, etc.) -- known at upload time, before extraction\n *     ever runs. Distinct from a \"time period slot\" (which final\n *     displayed period the EXTRACTED DATA populates): for bank\n *     statements/EPF/payslips these are always 1:1 (one document, one\n *     period), but for financial statements one document can supply TWO\n *     periods' worth of data (audited financials show two comparative\n *     years per document) -- that reconciliation is genuinely\n *     extraction-time behavior, not catalog data, and is NOT captured\n *     by document_slot. document_slot is exactly what\n *     @finsys/borrower-client's payload-transfer.ts currently has to\n *     regex-capture out of the field name (e.g. `bank_statement_t(\\d+)`)\n *     -- reserved here for that future consolidation, not consumed by\n *     anything in this package yet. `financials` (slot 1) and\n *     `financials_fincap_t1` (also slot 1) are NOT a duplicate-slot bug:\n *     they're alternate catalog entries for different form variants\n *     (confirmed by direct read -- both share document_group \"financials\"\n *     but represent mutually exclusive form paths, never populated\n *     together on one IHS), so both correctly describe \"the first\n *     physical document uploaded\" for their respective variant.\n *   - time_period_unit: what unit document_slot's number measures for\n *     this field -- 'month' | 'year'. Confirmed by the actual catalog\n *     data, not assumed: bank statements and payslips are monthly,\n *     financial statements and EPF statements are annual (EPF's own\n *     column names literally contain \"Year\", e.g. epfStatementYearT1).\n *\n * Mirrors the AdapterCategory pattern (SYS-2500): runtime lookup/grouping\n * derived from JSON data, no compile-time exhaustiveness. Same trade-off\n * applies -- no autocomplete on a document-type string; a wrong one is\n * caught by isDocumentType/assertDocumentType at the trust boundary\n * instead of by the compiler.\n */\n\nimport { getBaseFieldSpecs } from './catalogs.js'\nimport type { FieldData } from './survey-generator.js'\n\nexport type WireFormat = 'path_array' | 'url_string' | 'path_only'\nexport type TimePeriodUnit = 'month' | 'year'\n\nexport interface DocumentTypeGroup {\n  /** Wire/dispatch value, e.g. \"bankStatements\". */\n  readonly documentType: string\n  /** Render/table grouping key, e.g. \"ssm_documents\". Distinct from documentType -- see module doc. */\n  readonly documentGroup: string\n  /** Human-friendly label, e.g. \"Bank Statements\". */\n  readonly label: string\n  /** Reserved for a future borrower-client payload-routing consolidation. Taken from the group's first entry; not enforced consistent across entries (all groups agree today, but a future mixed-format group would silently inherit the first entry's value). */\n  readonly wireFormat?: WireFormat\n  /**\n   * The catalog's own `type: 'file'` entries belonging to this group, in\n   * catalog order. Each entry may carry its own document_slot/\n   * time_period_unit -- see TaggedFieldData and the module doc.\n   */\n  readonly fields: readonly TaggedFieldData[]\n}\n\nexport interface TaggedFieldData extends FieldData {\n  document_type?: string\n  document_group?: string\n  document_group_label?: string\n  wire_format?: WireFormat\n  /** Which upload position this field represents (1st document, 2nd, etc). See module doc for why this is distinct from a \"time period\". */\n  document_slot?: number\n  /** What unit document_slot's number measures for this field. */\n  time_period_unit?: TimePeriodUnit\n  /**\n   * SYS-2873: languages this upload slot's per-file document-language\n   * selector offers (e.g. [\"vi\", \"en\"]). Presence of the tag is what makes\n   * a renderer show the selector at all — entries without it (every\n   * Malaysia slot) render no language UI. The uploader's per-file choice\n   * travels with each uploaded file entry (ParsedDocFile.documentLanguage)\n   * and selects the extraction endpoint upstream. This tag is UX metadata:\n   * the server-side endpoint registry stays authoritative for which\n   * languages are actually callable.\n   */\n  document_language_options?: readonly string[]\n}\n\nlet cached: readonly DocumentTypeGroup[] | null = null\n\nfunction buildDocumentTypeGroups(): readonly DocumentTypeGroup[] {\n  const fileFields = getBaseFieldSpecs().filter(\n    (f): f is TaggedFieldData => f.type === 'file' && !!f.name,\n  )\n\n  const order: string[] = []\n  const byDocumentType = new Map<\n    string,\n    {\n      documentGroup: string\n      label: string\n      wireFormat: WireFormat | undefined\n      fields: TaggedFieldData[]\n    }\n  >()\n\n  for (const f of fileFields) {\n    // Untagged entries (none exist today, but future-proofed): fall back\n    // to the entry's own name/displayName as a single-entry group.\n    const documentType = f.document_type ?? f.name!\n    const documentGroup = f.document_group ?? documentType\n    const label = f.document_group_label ?? f.displayName ?? documentType\n\n    if (!byDocumentType.has(documentType)) {\n      order.push(documentType)\n      byDocumentType.set(documentType, {\n        documentGroup,\n        label,\n        wireFormat: f.wire_format,\n        fields: [],\n      })\n    }\n    byDocumentType.get(documentType)!.fields.push(f)\n  }\n\n  return order.map((documentType) => {\n    const entry = byDocumentType.get(documentType)!\n    return {\n      documentType,\n      documentGroup: entry.documentGroup,\n      label: entry.label,\n      wireFormat: entry.wireFormat,\n      fields: entry.fields,\n    }\n  })\n}\n\n/** Every registered document type, in catalog declaration order. */\nexport function getDocumentTypeGroups(): readonly DocumentTypeGroup[] {\n  if (!cached) cached = buildDocumentTypeGroups()\n  return cached\n}\n\n/** True if `id` is a registered document type (the wire/dispatch value). */\nexport function isDocumentType(id: string): boolean {\n  return getDocumentTypeGroups().some((g) => g.documentType === id)\n}\n\n/** Returns `id` if it's a registered document type, otherwise throws. */\nexport function assertDocumentType(id: string): string {\n  if (!isDocumentType(id)) {\n    const known = getDocumentTypeGroups().map((g) => g.documentType)\n    throw new Error(`Unknown document type: \"${id}\". Available: ${known.join(', ')}`)\n  }\n  return id\n}\n","{\n  \"schemaVersion\": \"1.4.0\",\n  \"categories\": [\n    {\n      \"id\": \"telco-carrier\",\n      \"displayName\": \"Telco Carrier\",\n      \"description\": \"Mobile carrier bill-payment + account-history signals. Any mobile carrier implementing this category produces the same canonical field set.\",\n      \"canonicalTable\": \"ihs_alt_data_telco\",\n      \"fields\": [\n        {\n          \"name\": \"onTimePaymentRatio24m\",\n          \"type\": \"number\",\n          \"unit\": \"ratio\",\n          \"range\": [\n            0,\n            1\n          ],\n          \"description\": \"Fraction of bills paid on time over the last 24 months. Strongest single telco predictor; \\u22650.95 is the clean-history signal.\",\n          \"legacyName\": \"telcoOnTimePaymentRatio24m\"\n        },\n        {\n          \"name\": \"tenureMonths\",\n          \"type\": \"number\",\n          \"unit\": \"months\",\n          \"range\": [\n            0,\n            600\n          ],\n          \"description\": \"Account age. \\u226548 months is the thin-file uplift trigger.\",\n          \"legacyName\": \"telcoTenureMonths\"\n        },\n        {\n          \"name\": \"suspensionsCount24m\",\n          \"type\": \"number\",\n          \"unit\": \"count\",\n          \"range\": [\n            0,\n            100\n          ],\n          \"description\": \"Non-payment-driven account suspensions in the last 24 months. \\u22653 is a strong distress signal.\",\n          \"legacyName\": \"telcoSuspensionsCount24m\"\n        },\n        {\n          \"name\": \"lateDays24m\",\n          \"type\": \"number\",\n          \"unit\": \"days\",\n          \"range\": [\n            0,\n            800\n          ],\n          \"description\": \"Cumulative days late across all bills in the trailing 24-month window.\",\n          \"legacyName\": \"telcoLateDays24m\"\n        },\n        {\n          \"name\": \"handsetFinancingActive\",\n          \"type\": \"boolean\",\n          \"description\": \"Has an active handset-EMI account currently. Proxy for financing capacity already extended.\",\n          \"legacyName\": \"telcoHandsetFinancingActive\"\n        },\n        {\n          \"name\": \"handsetFinancingDelinquent\",\n          \"type\": \"boolean\",\n          \"description\": \"Recent handset-EMI delinquency in the last 24 months. Distress signal even with otherwise clean bill payment.\",\n          \"legacyName\": \"telcoHandsetFinancingDelinquent\"\n        },\n        {\n          \"name\": \"arpu\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Average Revenue Per User (monthly). Coarse spending-capacity proxy. The Myr suffix in the field name is legacy: the denomination is carried per value, not fixed by the field. Rename deferred (breaking \\u2014 field names are fact ids).\",\n          \"legacyName\": \"telcoArpuMyr\"\n        },\n        {\n          \"name\": \"paymentReliabilityTier\",\n          \"type\": \"string\",\n          \"kind\": \"enum\",\n          \"description\": \"Coarse bill-payment reliability bucket, for partners that return a tier label instead of a continuous ratio. Parallel signal to telcoOnTimePaymentRatio24m. Labels are vendor-declared (see the adapter manifest's enumValues); ordering and scoring live in the consumer's per-value mapping.\",\n          \"legacyName\": \"telcoPaymentReliabilityTier\"\n        },\n        {\n          \"name\": \"tenureTier\",\n          \"type\": \"string\",\n          \"kind\": \"enum\",\n          \"description\": \"Coarse account-age bucket, for partners that return a tenure tier label instead of a continuous month count. Parallel signal to telcoTenureMonths. Labels are vendor-declared (see the adapter manifest's enumValues).\",\n          \"legacyName\": \"telcoTenureTier\"\n        },\n        {\n          \"name\": \"distressTier\",\n          \"type\": \"string\",\n          \"kind\": \"enum\",\n          \"description\": \"Coarse account-distress bucket, for partners that return a distress tier label instead of discrete counts. Parallel signal to telcoSuspensionsCount24m / telcoLateDays24m. Labels are vendor-declared (see the adapter manifest's enumValues).\",\n          \"legacyName\": \"telcoDistressTier\"\n        },\n        {\n          \"name\": \"handsetRiskTier\",\n          \"type\": \"string\",\n          \"kind\": \"enum\",\n          \"description\": \"Coarse handset-financing risk bucket, for partners that return a tier label instead of the discrete handset flags. Parallel signal to telcoHandsetFinancingActive / telcoHandsetFinancingDelinquent. Labels are vendor-declared (see the adapter manifest's enumValues).\",\n          \"legacyName\": \"telcoHandsetRiskTier\"\n        }\n      ]\n    },\n    {\n      \"id\": \"payment-network\",\n      \"displayName\": \"Payment Network\",\n      \"description\": \"Merchant-side payment-flow signals from POS / payment-gateway networks. Captures actual transaction velocity rather than self-reported revenue.\",\n      \"canonicalTable\": \"ihs_alt_data_payments\",\n      \"fields\": [\n        {\n          \"name\": \"monthlyVolume3m\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Mean monthly inbound transaction volume over the trailing 3 months. The Myr suffix in the field name is legacy: the denomination is carried per value, not fixed by the field. Rename deferred (breaking \\u2014 field names are fact ids).\",\n          \"legacyName\": \"paymentsMonthlyVolumeMyrT3\"\n        },\n        {\n          \"name\": \"monthlyVolume12m\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Mean monthly inbound transaction volume over the trailing 12 months. Pair with T3 for trend direction. The Myr suffix in the field name is legacy: the denomination is carried per value, not fixed by the field. Rename deferred (breaking \\u2014 field names are fact ids).\",\n          \"legacyName\": \"paymentsMonthlyVolumeMyrT12\"\n        },\n        {\n          \"name\": \"arpuStability12m\",\n          \"type\": \"number\",\n          \"unit\": \"ratio\",\n          \"range\": [\n            0,\n            1\n          ],\n          \"description\": \"Coefficient-of-variation inverse over monthly ARPU in the trailing 12 months. Closer to 1 = steadier; closer to 0 = volatile.\",\n          \"legacyName\": \"paymentsArpuStability12m\"\n        },\n        {\n          \"name\": \"disputeRate12m\",\n          \"type\": \"number\",\n          \"unit\": \"ratio\",\n          \"range\": [\n            0,\n            1\n          ],\n          \"description\": \"Fraction of transactions disputed or refunded in the trailing 12 months.\",\n          \"legacyName\": \"paymentsDisputeRate12m\"\n        },\n        {\n          \"name\": \"customerConcentrationTop5Pct\",\n          \"type\": \"number\",\n          \"unit\": \"ratio\",\n          \"range\": [\n            0,\n            1\n          ],\n          \"description\": \"Revenue share from the top-5 recurring customers. Above ~0.7 is concentration risk.\",\n          \"legacyName\": \"paymentsCustomerConcentrationTop5Pct\"\n        },\n        {\n          \"name\": \"activeTenureMonths\",\n          \"type\": \"number\",\n          \"unit\": \"months\",\n          \"range\": [\n            0,\n            600\n          ],\n          \"description\": \"Months since first transaction on the payment network. Establishment / continuity proxy.\",\n          \"legacyName\": \"paymentsActiveTenureMonths\"\n        }\n      ]\n    },\n    {\n      \"id\": \"bank-statement\",\n      \"displayName\": \"Bank Statement\",\n      \"description\": \"Per-month bank-statement extractions. Naturally multi-instance: one statement per (account, month). Eval components typically aggregate across instances (sum closing balance, max debit, count of bounced transactions).\",\n      \"canonicalTable\": \"ihs_alt_data_bank_statements\",\n      \"fields\": [\n        {\n          \"name\": \"statementMonth\",\n          \"type\": \"string\",\n          \"description\": \"Statement period in YYYY-MM format. Used as the instance_key discriminator + by the `latest` aggregation operator.\",\n          \"legacyName\": \"bankStatementMonth\"\n        },\n        {\n          \"name\": \"closingBalance\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Closing balance for the statement period.\",\n          \"fact\": \"closingBalance\",\n          \"legacyName\": \"bankClosingBalanceMyr\"\n        },\n        {\n          \"name\": \"totalCredits\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Sum of credit transactions during the period.\",\n          \"fact\": \"totalCredits\",\n          \"legacyName\": \"bankTotalCreditsMyr\"\n        },\n        {\n          \"name\": \"totalDebits\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Sum of debit transactions during the period.\",\n          \"fact\": \"totalDebits\",\n          \"legacyName\": \"bankTotalDebitsMyr\"\n        },\n        {\n          \"name\": \"largestSingleCredit\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Largest single inbound transaction in the period. Useful for spotting one-off injections vs steady revenue.\",\n          \"legacyName\": \"bankLargestSingleCreditMyr\"\n        },\n        {\n          \"name\": \"bouncedTransactionsCount\",\n          \"type\": \"number\",\n          \"unit\": \"count\",\n          \"range\": [\n            0,\n            1000\n          ],\n          \"description\": \"Bounced / returned transactions in the period. Distress signal at counts > 0.\",\n          \"legacyName\": \"bankBouncedTransactionsCount\"\n        }\n      ]\n    },\n    {\n      \"id\": \"social-media\",\n      \"displayName\": \"Social Media Presence\",\n      \"description\": \"Public business-presence signals from social / commerce platforms \\u2014 establishment, reach, engagement authenticity, customer reputation, and account standing. Vendor-agnostic: any platform exposing a public business profile maps its data to this canonical field set. Useful as thin-file corroboration of a borrower's operating reality where formal financials are sparse.\",\n      \"canonicalTable\": \"ihs_alt_data_social_media\",\n      \"fields\": [\n        {\n          \"name\": \"accountTenureMonths\",\n          \"type\": \"number\",\n          \"unit\": \"months\",\n          \"range\": [\n            0,\n            600\n          ],\n          \"description\": \"Age of the oldest verified public business presence across linked profiles. Establishment / continuity proxy, parallel to telco + payment-network tenure.\",\n          \"legacyName\": \"socialAccountTenureMonths\"\n        },\n        {\n          \"name\": \"followerCount\",\n          \"type\": \"number\",\n          \"unit\": \"count\",\n          \"range\": [\n            0,\n            100000000\n          ],\n          \"description\": \"Aggregate audience size across linked public profiles. Coarse reach / scale proxy \\u2014 gameable on its own, so read alongside socialEngagementRate90d.\",\n          \"legacyName\": \"socialFollowerCount\"\n        },\n        {\n          \"name\": \"engagementRate90d\",\n          \"type\": \"number\",\n          \"unit\": \"ratio\",\n          \"range\": [\n            0,\n            1\n          ],\n          \"description\": \"Mean interactions per impression over the trailing 90 days. Authenticity signal: a large follower count with near-zero engagement indicates a bought or dormant audience.\",\n          \"legacyName\": \"socialEngagementRate90d\"\n        },\n        {\n          \"name\": \"postingConsistency12m\",\n          \"type\": \"number\",\n          \"unit\": \"ratio\",\n          \"range\": [\n            0,\n            1\n          ],\n          \"description\": \"Fraction of weeks in the trailing 12 months with at least one public post. Ongoing-operation signal \\u2014 distinguishes an active business from a stale listing.\",\n          \"legacyName\": \"socialPostingConsistency12m\"\n        },\n        {\n          \"name\": \"verifiedBusinessAccount\",\n          \"type\": \"boolean\",\n          \"description\": \"Has at least one platform-verified business / commerce profile. Legitimacy signal \\u2014 the platform has performed its own business-identity check.\",\n          \"legacyName\": \"socialVerifiedBusinessAccount\"\n        },\n        {\n          \"name\": \"customerRatingAvg\",\n          \"type\": \"number\",\n          \"unit\": \"rating\",\n          \"range\": [\n            0,\n            5\n          ],\n          \"description\": \"Mean public customer rating (normalised to a 0\\u20135 scale) across review-bearing profiles. Reputation signal; especially predictive for consumer-facing SMEs.\",\n          \"legacyName\": \"socialCustomerRatingAvg\"\n        },\n        {\n          \"name\": \"negativeSentimentRatio90d\",\n          \"type\": \"number\",\n          \"unit\": \"ratio\",\n          \"range\": [\n            0,\n            1\n          ],\n          \"description\": \"Fraction of public mentions / reviews classified as negative over the trailing 90 days. Reputation-risk / distress signal independent of overall rating volume.\",\n          \"legacyName\": \"socialNegativeSentimentRatio90d\"\n        },\n        {\n          \"name\": \"accountFlags24m\",\n          \"type\": \"number\",\n          \"unit\": \"count\",\n          \"range\": [\n            0,\n            100\n          ],\n          \"description\": \"Policy strikes, suspensions, or content takedowns across linked profiles in the last 24 months. Distress signal, parallel to telcoSuspensionsCount24m.\",\n          \"legacyName\": \"socialAccountFlags24m\"\n        }\n      ]\n    },\n    {\n      \"id\": \"trade-credit\",\n      \"displayName\": \"Trade Credit (Accounting)\",\n      \"description\": \"Accounts-receivable / accounts-payable aging and ledger-derived working-capital signals sourced from a business's accounting / ERP system. Captures how promptly the business collects from its debtors and pays its creditors, the aging profile and concentration of its receivables, and P&L / cash-conversion efficiency. Vendor-agnostic: any accounting or ERP system that exposes an AR/AP aging report plus a P&L summary maps its data to this canonical field set. A direct, high-signal view of trade-obligation behaviour \\u2014 closer to formal credit history than most alternative data \\u2014 and the anchor for cross-referencing self-reported accounting figures against bank-statement reality.\",\n      \"canonicalTable\": \"ihs_alt_data_trade_credit\",\n      \"fields\": [\n        {\n          \"name\": \"arDaysSalesOutstanding\",\n          \"type\": \"number\",\n          \"unit\": \"days\",\n          \"range\": [\n            0,\n            400\n          ],\n          \"description\": \"Days Sales Outstanding \\u2014 average days to collect a receivable. The headline collection-efficiency metric; lower is healthier, and a rising DSO is an early liquidity-stress signal.\"\n        },\n        {\n          \"name\": \"apDaysPayableOutstanding\",\n          \"type\": \"number\",\n          \"unit\": \"days\",\n          \"range\": [\n            0,\n            400\n          ],\n          \"description\": \"Days Payable Outstanding \\u2014 average days the business takes to pay its suppliers. Context for DSO; a very high DPO can indicate the business is stretching its creditors to fund operations.\"\n        },\n        {\n          \"name\": \"arTotalOutstanding\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Total accounts-receivable balance outstanding. The size of the debtor book the business is carrying. The Myr suffix in the field name is legacy: the denomination is carried per value, not fixed by the field. Rename deferred (breaking \\u2014 field names are fact ids).\",\n          \"legacyName\": \"arTotalOutstandingMyr\"\n        },\n        {\n          \"name\": \"arCurrentRatio\",\n          \"type\": \"number\",\n          \"unit\": \"ratio\",\n          \"range\": [\n            0,\n            1\n          ],\n          \"description\": \"Fraction of the receivables book that is current (within payment terms, not yet overdue). Higher is healthier; the complement is the overdue share across all aging buckets.\"\n        },\n        {\n          \"name\": \"arOverdue90PlusRatio\",\n          \"type\": \"number\",\n          \"unit\": \"ratio\",\n          \"range\": [\n            0,\n            1\n          ],\n          \"description\": \"Fraction of the receivables book aged more than 90 days past terms. The key impairment / bad-debt risk signal from the AR aging report; elevated values indicate collection difficulty.\"\n        },\n        {\n          \"name\": \"debtorConcentrationTop5Ratio\",\n          \"type\": \"number\",\n          \"unit\": \"ratio\",\n          \"range\": [\n            0,\n            1\n          ],\n          \"description\": \"Share of total receivables owed by the top-5 debtors. Above ~0.6 is single-customer concentration risk \\u2014 one debtor default would materially impair cash flow.\"\n        },\n        {\n          \"name\": \"tradeReferenceDefaults12m\",\n          \"type\": \"number\",\n          \"unit\": \"count\",\n          \"range\": [\n            0,\n            1000\n          ],\n          \"description\": \"Count of supplier-reported defaults or dishonoured / returned payments against the business in the trailing 12 months. Direct distress signal, parallel to a bureau default record.\"\n        },\n        {\n          \"name\": \"accountingRevenue12m\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Trailing-12-month turnover per the general ledger. The cross-reference anchor: comparing this self-reported accounting revenue against payment-network volume and bank-statement inflows surfaces book-vs-reality inconsistencies. The Myr suffix in the field name is legacy: the denomination is carried per value, not fixed by the field. Rename deferred (breaking \\u2014 field names are fact ids).\",\n          \"legacyName\": \"accountingRevenue12mMyr\"\n        },\n        {\n          \"name\": \"grossMarginPct\",\n          \"type\": \"number\",\n          \"unit\": \"ratio\",\n          \"range\": [\n            0,\n            1\n          ],\n          \"description\": \"Gross margin from the P&L (gross profit / revenue). Profitability-quality signal; a thin or declining margin constrains debt-service capacity even at healthy revenue.\"\n        },\n        {\n          \"name\": \"cashConversionCycleDays\",\n          \"type\": \"number\",\n          \"unit\": \"days\",\n          \"range\": [\n            -200,\n            600\n          ],\n          \"description\": \"Cash Conversion Cycle (DSO + days-inventory-outstanding \\u2212 DPO). Working-capital efficiency; negative values (collect before paying suppliers) are strongest, very high values indicate cash tied up in operations.\"\n        }\n      ]\n    },\n    {\n      \"id\": \"geolocation\",\n      \"displayName\": \"Geolocation\",\n      \"description\": \"Hourly-granularity movement track plus derived mobility signals for an applicant, sourced from any location-capable provider (telco network location, mobile-SDK GPS, GIS / address-verification services). Two instance kinds share this category: point instances (instanceKey 'pt:<ISO-hour>') carry one observed position per hourly bucket, mirroring the bank-statement multi-instance pattern; a single summary instance (instanceKey 'summary') carries adapter-derived behaviour signals \\u2014 most importantly work-pattern regularity (sustained weekday dwell at a stable work anchor corroborates income reliability), residential stability, vacation windows, and dwell in operator-flagged hotspot zones. Vendor-agnostic: the source classifies or the adapter infers place labels; no provider-specific semantics leak into the field set. Raw coordinates are sensitive personal data \\u2014 product-plane persistence is gated on PDPA consent + CRA Act 710 s25 retention review.\",\n      \"canonicalTable\": \"ihs_alt_data_geolocation\",\n      \"fields\": [\n        {\n          \"name\": \"latitude\",\n          \"type\": \"number\",\n          \"unit\": \"deg\",\n          \"range\": [\n            -90,\n            90\n          ],\n          \"description\": \"Observed latitude for this hourly bucket (point instances only).\",\n          \"legacyName\": \"geoLatitude\"\n        },\n        {\n          \"name\": \"longitude\",\n          \"type\": \"number\",\n          \"unit\": \"deg\",\n          \"range\": [\n            -180,\n            180\n          ],\n          \"description\": \"Observed longitude for this hourly bucket (point instances only).\",\n          \"legacyName\": \"geoLongitude\"\n        },\n        {\n          \"name\": \"accuracyMeters\",\n          \"type\": \"number\",\n          \"unit\": \"meters\",\n          \"range\": [\n            0,\n            100000\n          ],\n          \"description\": \"Source-reported horizontal accuracy radius of the observation. Cell-tower fixes are typically hundreds of meters; GPS fixes tens.\",\n          \"legacyName\": \"geoAccuracyM\"\n        },\n        {\n          \"name\": \"bucket\",\n          \"type\": \"string\",\n          \"description\": \"ISO-8601 hour bucket of the observation, e.g. '2026-06-01T08'. Redundant with the instance key (pt:<bucket>) so consumers can query without parsing keys.\",\n          \"legacyName\": \"geoBucket\"\n        },\n        {\n          \"name\": \"placeLabel\",\n          \"type\": \"string\",\n          \"description\": \"Classified place for the bucket: home | work | commute | leisure | travel | hotspot | other. Classified by the source or inferred by the adapter from anchor dwell.\",\n          \"legacyName\": \"geoPlaceLabel\"\n        },\n        {\n          \"name\": \"workAttendanceRatio30d\",\n          \"type\": \"number\",\n          \"unit\": \"ratio\",\n          \"range\": [\n            0,\n            1\n          ],\n          \"description\": \"Fraction of the last 30 weekdays with >= 6 hours of dwell at the inferred work anchor. The income-reliability headline: regular full-time work patterns corroborate declared employment income (summary instance only).\",\n          \"legacyName\": \"geoWorkAttendanceRatio30d\"\n        },\n        {\n          \"name\": \"workDailyHoursAvg30d\",\n          \"type\": \"number\",\n          \"unit\": \"hours\",\n          \"range\": [\n            0,\n            24\n          ],\n          \"description\": \"Mean daily hours of work-anchor dwell across the last 30 weekdays (summary instance only).\",\n          \"legacyName\": \"geoWorkDailyHoursAvg30d\"\n        },\n        {\n          \"name\": \"locationStabilityScore\",\n          \"type\": \"number\",\n          \"unit\": \"score\",\n          \"range\": [\n            0,\n            1\n          ],\n          \"description\": \"Residential stability: share of nights spent at the primary home anchor over the observation window. 1 = every night at home (summary instance only).\",\n          \"legacyName\": \"geoLocationStabilityScore\"\n        },\n        {\n          \"name\": \"commuteRegularityRatio\",\n          \"type\": \"number\",\n          \"unit\": \"ratio\",\n          \"range\": [\n            0,\n            1\n          ],\n          \"description\": \"Consistency of the weekday home->work->home rhythm: fraction of weekdays matching the dominant commute pattern within an hour's tolerance (summary instance only).\",\n          \"legacyName\": \"geoCommuteRegularityRatio\"\n        },\n        {\n          \"name\": \"vacationDays90d\",\n          \"type\": \"number\",\n          \"unit\": \"days\",\n          \"range\": [\n            0,\n            90\n          ],\n          \"description\": \"Days in the last 90 spent fully away from both home and work anchors (contiguous travel windows; summary instance only).\",\n          \"legacyName\": \"geoVacationDays90d\"\n        },\n        {\n          \"name\": \"hotspotDwellRatio\",\n          \"type\": \"number\",\n          \"unit\": \"ratio\",\n          \"range\": [\n            0,\n            1\n          ],\n          \"description\": \"Share of observed buckets spent inside operator-flagged hotspot zones (known fraud / illicit-activity locations supplied to the adapter). Non-zero values warrant review, not automatic decline (summary instance only).\",\n          \"legacyName\": \"geoHotspotDwellRatio\"\n        },\n        {\n          \"name\": \"primaryStateCode\",\n          \"type\": \"string\",\n          \"description\": \"Malaysian state / federal-territory code of the primary home anchor, e.g. PNG, KUL, JHR (summary instance only).\",\n          \"legacyName\": \"geoPrimaryStateCode\"\n        },\n        {\n          \"name\": \"addressMatchScore\",\n          \"type\": \"number\",\n          \"unit\": \"score\",\n          \"range\": [\n            0,\n            1\n          ],\n          \"description\": \"Agreement between the inferred home anchor and the applicant's registered residential address. 1 = same premises, 0 = different state (summary instance only).\",\n          \"legacyName\": \"geoAddressMatchScore\"\n        }\n      ]\n    },\n    {\n      \"id\": \"person-identity\",\n      \"displayName\": \"Identity Document (IC / Passport)\",\n      \"description\": \"Identity fields extracted from a Malaysian IC (MyKad) or passport document. Produced by the host's document-extraction pipeline; one instance per identity document.\",\n      \"canonicalTable\": \"ihs_alt_data_ic\",\n      \"fields\": [\n        {\n          \"name\": \"personName\",\n          \"type\": \"string\",\n          \"description\": \"Full name as printed on the identity document.\",\n          \"fact\": \"personName\",\n          \"legacyName\": \"icName\"\n        },\n        {\n          \"name\": \"personIdNumber\",\n          \"type\": \"string\",\n          \"description\": \"IC (MyKad) number, or passport number for passport documents.\",\n          \"fact\": \"personIdNumber\",\n          \"legacyName\": \"icNumber\"\n        },\n        {\n          \"name\": \"personAddress\",\n          \"type\": \"string\",\n          \"description\": \"Registered address as printed on the document.\",\n          \"fact\": \"personAddress\",\n          \"legacyName\": \"icAddress\"\n        },\n        {\n          \"name\": \"personGender\",\n          \"type\": \"string\",\n          \"description\": \"Gender as stated on the document.\",\n          \"fact\": \"personGender\",\n          \"legacyName\": \"icGender\"\n        },\n        {\n          \"name\": \"personReligion\",\n          \"type\": \"string\",\n          \"description\": \"Religion as stated on the document (MyKad-only; absent on passports).\",\n          \"fact\": \"personReligion\",\n          \"legacyName\": \"icReligion\"\n        },\n        {\n          \"name\": \"personDateOfBirth\",\n          \"type\": \"string\",\n          \"description\": \"Date of birth as stated on the document.\",\n          \"fact\": \"personDateOfBirth\",\n          \"legacyName\": \"icDateOfBirth\"\n        },\n        {\n          \"name\": \"personPlaceOfBirth\",\n          \"type\": \"string\",\n          \"description\": \"Place of birth as stated on the document.\",\n          \"fact\": \"personPlaceOfBirth\",\n          \"legacyName\": \"icPlaceOfBirth\"\n        },\n        {\n          \"name\": \"personNationality\",\n          \"type\": \"string\",\n          \"description\": \"Nationality as stated on the document.\",\n          \"fact\": \"personNationality\",\n          \"legacyName\": \"icNationality\"\n        },\n        {\n          \"name\": \"personRace\",\n          \"type\": \"string\",\n          \"description\": \"Race as stated on the document (MyKad-only; absent on passports).\",\n          \"fact\": \"personRace\",\n          \"legacyName\": \"icRace\"\n        }\n      ],\n      \"legacyId\": \"ic\"\n    },\n    {\n      \"id\": \"finxtract-bank-statement\",\n      \"displayName\": \"Bank Statement (Document Extraction)\",\n      \"description\": \"Fields extracted from an uploaded bank-statement document by the host's extraction pipeline. One instance per statement document; each statement covers a single month. Distinct from the partner-API 'bank-statement' category: same real-world domain, different source and different canonical vocabulary.\",\n      \"canonicalTable\": \"ihsbankstatement\",\n      \"fields\": [\n        {\n          \"name\": \"issuingBankName\",\n          \"type\": \"string\",\n          \"description\": \"Issuing bank's name as printed on the statement.\",\n          \"legacyName\": \"bankName\"\n        },\n        {\n          \"name\": \"personName\",\n          \"type\": \"string\",\n          \"description\": \"Account holder's name as printed on the statement.\",\n          \"fact\": \"personName\",\n          \"legacyName\": \"accountHolderName\"\n        },\n        {\n          \"name\": \"accountNumber\",\n          \"type\": \"string\",\n          \"description\": \"Bank account number as printed on the statement.\"\n        },\n        {\n          \"name\": \"statementDate\",\n          \"type\": \"string\",\n          \"description\": \"Statement date, normalized to ISO YYYY-MM-DD.\"\n        },\n        {\n          \"name\": \"openingBalance\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Opening balance for the statement period.\"\n        },\n        {\n          \"name\": \"closingBalance\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Closing balance for the statement period.\",\n          \"fact\": \"closingBalance\",\n          \"legacyName\": \"bankBalance\"\n        },\n        {\n          \"name\": \"totalCredits\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Sum of credit transactions in the statement period.\",\n          \"fact\": \"totalCredits\"\n        },\n        {\n          \"name\": \"totalDebits\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Sum of debit transactions in the statement period.\",\n          \"fact\": \"totalDebits\"\n        }\n      ]\n    },\n    {\n      \"id\": \"epf-statement\",\n      \"displayName\": \"EPF Statement (Document Extraction)\",\n      \"description\": \"Fields extracted from an uploaded EPF (KWSP) statement document by the host's extraction pipeline. One instance per statement document. Field names carry the 'epf' prefix \\u2014 the same prefix-namespaced vocabulary the host's flat read path and the eval engine already use, which also keeps canonical names globally unique across categories.\",\n      \"canonicalTable\": \"ihsepfstatement\",\n      \"fields\": [\n        {\n          \"name\": \"personName\",\n          \"type\": \"string\",\n          \"description\": \"Member's name as printed on the statement.\",\n          \"fact\": \"personName\",\n          \"legacyName\": \"epfAccountHolderName\"\n        },\n        {\n          \"name\": \"personAddress\",\n          \"type\": \"string\",\n          \"description\": \"Member's address as printed on the statement.\",\n          \"fact\": \"personAddress\",\n          \"legacyName\": \"epfAccountHolderAddress\"\n        },\n        {\n          \"name\": \"statementYear\",\n          \"type\": \"string\",\n          \"description\": \"The contribution year the statement covers.\",\n          \"legacyName\": \"epfStatementYear\"\n        },\n        {\n          \"name\": \"kwspMemberNumber\",\n          \"type\": \"string\",\n          \"description\": \"KWSP membership number.\",\n          \"legacyName\": \"epfKwspMemberNumber\"\n        },\n        {\n          \"name\": \"personIdNumber\",\n          \"type\": \"string\",\n          \"description\": \"Member's IC number as printed on the statement.\",\n          \"fact\": \"personIdNumber\",\n          \"legacyName\": \"epfIcNumber\"\n        },\n        {\n          \"name\": \"employerNumber\",\n          \"type\": \"string\",\n          \"description\": \"Employer's KWSP reference number.\",\n          \"legacyName\": \"epfEmployerNumber\"\n        },\n        {\n          \"name\": \"dateOfStatement\",\n          \"type\": \"string\",\n          \"description\": \"Statement issue date, normalized to ISO YYYY-MM-DD.\",\n          \"legacyName\": \"epfDateOfStatement\"\n        },\n        {\n          \"name\": \"totalContribution\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Cumulative EPF balance as at the statement date.\",\n          \"legacyName\": \"epfTotalContribution\"\n        },\n        {\n          \"name\": \"totalCurrentContribution\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Contributions made within the statement's coverage year.\",\n          \"legacyName\": \"epfTotalCurrentContribution\"\n        }\n      ],\n      \"legacyId\": \"finxtract-epf\"\n    },\n    {\n      \"id\": \"payslip\",\n      \"displayName\": \"Payslip (Document Extraction)\",\n      \"description\": \"Fields extracted from an uploaded payslip document by the host's extraction pipeline. One instance per payslip document; each payslip covers a single pay period. Field names carry the 'payslip' prefix \\u2014 the same prefix-namespaced vocabulary the host's flat read path and the eval engine already use, which also keeps canonical names globally unique across categories.\",\n      \"canonicalTable\": \"ihsPayslip\",\n      \"fields\": [\n        {\n          \"name\": \"employerName\",\n          \"type\": \"string\",\n          \"description\": \"Employer's name as printed on the payslip.\",\n          \"fact\": \"employerName\",\n          \"legacyName\": \"payslipEmployerName\"\n        },\n        {\n          \"name\": \"personName\",\n          \"type\": \"string\",\n          \"description\": \"Employee's name as printed on the payslip.\",\n          \"fact\": \"personName\",\n          \"legacyName\": \"payslipEmployeeName\"\n        },\n        {\n          \"name\": \"payPeriod\",\n          \"type\": \"string\",\n          \"description\": \"The pay period the payslip covers, as printed.\",\n          \"legacyName\": \"payslipPayPeriod\"\n        },\n        {\n          \"name\": \"payDate\",\n          \"type\": \"string\",\n          \"description\": \"Payment date, as printed.\",\n          \"legacyName\": \"payslipPayDate\"\n        },\n        {\n          \"name\": \"basicPay\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Basic salary for the period.\",\n          \"legacyName\": \"payslipBasicPay\"\n        },\n        {\n          \"name\": \"grossPay\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Gross pay for the period.\",\n          \"fact\": \"grossPay\",\n          \"legacyName\": \"payslipGrossPay\"\n        },\n        {\n          \"name\": \"fixedAllowances\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Fixed allowances for the period.\",\n          \"legacyName\": \"payslipFixedAllowances\"\n        },\n        {\n          \"name\": \"variableIncome\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Variable income (overtime, commission, bonus) for the period.\",\n          \"legacyName\": \"payslipVariableIncome\"\n        },\n        {\n          \"name\": \"deduction\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Total statutory deductions for the period.\",\n          \"legacyName\": \"payslipDeduction\"\n        },\n        {\n          \"name\": \"otherDeduction\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Other (non-statutory) deductions for the period.\",\n          \"legacyName\": \"payslipOtherDeduction\"\n        },\n        {\n          \"name\": \"employeeEpfContribution\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Employee EPF contribution for the period.\",\n          \"legacyName\": \"payslipEmployeeEpfContribution\"\n        },\n        {\n          \"name\": \"employeeSocsoContribution\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Employee SOCSO contribution for the period.\",\n          \"legacyName\": \"payslipEmployeeSocsoContribution\"\n        },\n        {\n          \"name\": \"employeeEisContribution\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Employee EIS contribution for the period.\",\n          \"legacyName\": \"payslipEmployeeEisContribution\"\n        },\n        {\n          \"name\": \"employeeTax\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Employee income-tax (PCB) deduction for the period.\",\n          \"legacyName\": \"payslipEmployeeTax\"\n        },\n        {\n          \"name\": \"netPay\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Net pay for the period.\",\n          \"fact\": \"netPay\",\n          \"legacyName\": \"payslipNetPay\"\n        }\n      ],\n      \"legacyId\": \"finxtract-payslip\"\n    },\n    {\n      \"id\": \"financial-statement\",\n      \"displayName\": \"Financial Statement (Document Extraction)\",\n      \"description\": \"Fields extracted from an uploaded audited financial-statement document by the host's extraction pipeline. One document = one audited financial statement carrying TWO declared periods per the period-axis contract: period1 is its current fiscal year, period2 is its prior comparative year. Metric names are bare in the flat vocabulary, like the bank-statement extraction category's.\",\n      \"canonicalTable\": \"ihsfinancialstatement\",\n      \"fields\": [\n        {\n          \"name\": \"localNo\",\n          \"type\": \"string\",\n          \"description\": \"Company registration (local) number as stated on the document.\"\n        },\n        {\n          \"name\": \"companyName\",\n          \"type\": \"string\",\n          \"fact\": \"companyName\",\n          \"description\": \"Company name as stated on the document. Attestation of the shared companyName fact \\u2014 the SSM Form 9 extraction category attests the same fact from its own document.\"\n        },\n        {\n          \"name\": \"financialYearEnd\",\n          \"type\": \"string\",\n          \"description\": \"Financial year end stated by the source document, normalized to ISO YYYY-MM-DD. Shared verbatim by every period the document carries \\u2014 period identity comes from declared position, never from this date.\"\n        },\n        {\n          \"name\": \"consolidated\",\n          \"type\": \"boolean\",\n          \"description\": \"Whether the statement reports consolidated (group-level) accounts.\"\n        },\n        {\n          \"name\": \"currency\",\n          \"type\": \"string\",\n          \"description\": \"Reporting currency stated on the document.\"\n        },\n        {\n          \"name\": \"year\",\n          \"type\": \"number\",\n          \"description\": \"1-based ordinal of this document within the applicant's uploaded statement sequence; document 1 covers the most recent fiscal years.\"\n        },\n        {\n          \"name\": \"nonCurrentAssetsSubsidiaryCompanies\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current assets: subsidiary companies.\"\n        },\n        {\n          \"name\": \"nonCurrentAssetsAssociatedCompanies\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current assets: associated companies.\"\n        },\n        {\n          \"name\": \"nonCurrentAssetsDevelopmentPropertiesOrExpenditure\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current assets: development properties or expenditure.\"\n        },\n        {\n          \"name\": \"nonCurrentAssetInvestmentProperties\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current assets: investment properties.\"\n        },\n        {\n          \"name\": \"nonCurrentAssetsInvestments\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current assets: investments.\"\n        },\n        {\n          \"name\": \"nonCurrentAssetInvestmentSecurities\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current assets: investment securities.\"\n        },\n        {\n          \"name\": \"nonCurrentAssetDeferredAssets\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current assets: deferred assets.\"\n        },\n        {\n          \"name\": \"nonCurrentAssetDeposits\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current assets: deposits.\"\n        },\n        {\n          \"name\": \"nonCurrentAssetOwnGoodwill\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current assets: own goodwill.\"\n        },\n        {\n          \"name\": \"nonCurrentAssetGoodwillOnConsolidation\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current assets: goodwill on consolidation.\"\n        },\n        {\n          \"name\": \"nonCurrentAssetSinkingFund\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current assets: sinking fund.\"\n        },\n        {\n          \"name\": \"nonCurrentAssetPropertyPlantEquipment\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current assets: property plant equipment.\"\n        },\n        {\n          \"name\": \"nonCurrentAssetInventories\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current assets: inventories.\"\n        },\n        {\n          \"name\": \"nonCurrentAssetRightOfUseAssets\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current assets: right of use assets.\"\n        },\n        {\n          \"name\": \"nonCurrentAssetIntangibleAssets\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current assets: intangible assets.\"\n        },\n        {\n          \"name\": \"nonCurrentAssetPrepaidLeasePayments\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current assets: prepaid lease payments.\"\n        },\n        {\n          \"name\": \"nonCurrentAssetFinancialAssetAtFairValue\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current assets: financial asset at fair value.\"\n        },\n        {\n          \"name\": \"nonCurrentAssetLandUseRight\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current assets: land use right.\"\n        },\n        {\n          \"name\": \"nonCurrentAssetTradeReceivables\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current assets: trade receivables.\"\n        },\n        {\n          \"name\": \"nonCurrentAssetOtherReceivables\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current assets: other receivables.\"\n        },\n        {\n          \"name\": \"nonCurrentAssetTradeAndOtherReceivables\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current assets: trade and other receivables.\"\n        },\n        {\n          \"name\": \"nonCurrentAssetOtherReceivablesDepositsAndPrepayments\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current assets: other receivables deposits and prepayments.\"\n        },\n        {\n          \"name\": \"totalNonCurrentAssets\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Balance-sheet total: non-current assets.\"\n        },\n        {\n          \"name\": \"currentAssetDevelopmentPropertiesOrExpenditure\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: development properties or expenditure.\"\n        },\n        {\n          \"name\": \"currentAssetShortTermInvestments\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: short term investments.\"\n        },\n        {\n          \"name\": \"currentAssetTradeDebtors\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: trade debtors.\"\n        },\n        {\n          \"name\": \"currentAssetShortTermDeposits\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: short term deposits.\"\n        },\n        {\n          \"name\": \"currentAssetAmountDueFromHoldingCompany\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: amount due from holding company.\"\n        },\n        {\n          \"name\": \"currentAssetAmountDueFromSubsidiaryCompanies\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: amount due from subsidiary companies.\"\n        },\n        {\n          \"name\": \"currentAssetAmountDueFromAssociatedCompanies\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: amount due from associated companies.\"\n        },\n        {\n          \"name\": \"currentAssetAmountDueFromDirector\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: amount due from director.\"\n        },\n        {\n          \"name\": \"currentAssetAmountDueFromCustomer\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: amount due from customer.\"\n        },\n        {\n          \"name\": \"currentAssetAmountOwingByShareholders\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: amount owing by shareholders.\"\n        },\n        {\n          \"name\": \"currentAssetInventories\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: inventories.\"\n        },\n        {\n          \"name\": \"currentAssetFinancialAssetAtFairValue\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: financial asset at fair value.\"\n        },\n        {\n          \"name\": \"currentAssetLandUseRight\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: land use right.\"\n        },\n        {\n          \"name\": \"currentAssetTaxRecoverable\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: tax recoverable.\"\n        },\n        {\n          \"name\": \"currentAssetContractAssets\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: contract assets.\"\n        },\n        {\n          \"name\": \"currentAssetCurrentTaxAssets\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: current tax assets.\"\n        },\n        {\n          \"name\": \"currentAssetPrepayments\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: prepayments.\"\n        },\n        {\n          \"name\": \"currentAssetDerivative\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: derivative.\"\n        },\n        {\n          \"name\": \"currentAssetCashAndBankBalances\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: cash and bank balances.\"\n        },\n        {\n          \"name\": \"currentAssetOtherReceivables\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: other receivables.\"\n        },\n        {\n          \"name\": \"currentAssetRestrictedCash\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: restricted cash.\"\n        },\n        {\n          \"name\": \"currentAssetCashAndCashEquivalents\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: cash and cash equivalents.\"\n        },\n        {\n          \"name\": \"currentAssetDepositsCashAndBankBalances\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: deposits cash and bank balances.\"\n        },\n        {\n          \"name\": \"currentAssetCashAtBanks\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: cash at banks.\"\n        },\n        {\n          \"name\": \"currentAssetCashOnHand\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: cash on hand.\"\n        },\n        {\n          \"name\": \"currentAssetDepositsAndPrepayments\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: deposits and prepayments.\"\n        },\n        {\n          \"name\": \"currentAssetTradeAndOtherReceivables\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: trade and other receivables.\"\n        },\n        {\n          \"name\": \"currentAssetOtherReceivablesDepositsAndPrepayments\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: other receivables deposits and prepayments.\"\n        },\n        {\n          \"name\": \"currentAssetOtherReceivablesAndDeposits\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: other receivables and deposits.\"\n        },\n        {\n          \"name\": \"currentAssetOtherReceivablesAndPrepayments\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current assets: other receivables and prepayments.\"\n        },\n        {\n          \"name\": \"totalCurrentAssets\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Balance-sheet total: current assets.\"\n        },\n        {\n          \"name\": \"totalAssets\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Balance-sheet total: assets.\"\n        },\n        {\n          \"name\": \"tangibleAssets\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Balance-sheet total: tangible assets — the statement's own total-tangible-assets line where it declares one, otherwise total assets less intangible assets. Not the complement of nonCurrentAssetIntangibleAssets by name: that field is one intangible line item, this is an assets aggregate.\"\n        },\n        {\n          \"name\": \"currentLiabilitiesTradeCreditors\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current liabilities: trade creditors.\"\n        },\n        {\n          \"name\": \"currentLiabilitiesHirePurchasePayables\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current liabilities: hire purchase payables.\"\n        },\n        {\n          \"name\": \"currentLiabilitiesBankOverdraft\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current liabilities: bank overdraft.\"\n        },\n        {\n          \"name\": \"currentLiabilitiesBankAcceptance\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current liabilities: bank acceptance.\"\n        },\n        {\n          \"name\": \"currentLiabilitiesBorrowingsOrTermLoans\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current liabilities: borrowings or term loans.\"\n        },\n        {\n          \"name\": \"currentLiabilitiesBankborrowings\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current liabilities: bank borrowings.\"\n        },\n        {\n          \"name\": \"currentLiabilitiesAmountsOwingToHoldingCompany\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current liabilities: amounts owing to holding company.\"\n        },\n        {\n          \"name\": \"currentLiabilitiesAmountsOwingToSubsidiaryCompanies\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current liabilities: amounts owing to subsidiary companies.\"\n        },\n        {\n          \"name\": \"currentLiabilitiesAmountOwingToAssociatedCompanies\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current liabilities: amount owing to associated companies.\"\n        },\n        {\n          \"name\": \"currentLiabilitiesAmountsOwingToDirector\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current liabilities: amounts owing to director.\"\n        },\n        {\n          \"name\": \"currentLiabilitiesProvisionForTaxation\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current liabilities: provision for taxation.\"\n        },\n        {\n          \"name\": \"currentLiabilitiesLeasePayables\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current liabilities: lease payables.\"\n        },\n        {\n          \"name\": \"currentLiabilitiesFinanceLeasePayables\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current liabilities: finance lease payables.\"\n        },\n        {\n          \"name\": \"currentLiabilitiesOtherPayables\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current liabilities: other payables.\"\n        },\n        {\n          \"name\": \"currentLiabilitiesDividendPayables\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current liabilities: dividend payables.\"\n        },\n        {\n          \"name\": \"currentLiabilitiesTradeAndOtherPayables\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current liabilities: trade and other payables.\"\n        },\n        {\n          \"name\": \"currentLiabilitiesDepositsFromCustomers\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current liabilities: deposits from customers.\"\n        },\n        {\n          \"name\": \"currentLiabilitiesOtherPayablesAccrualsAndDeposits\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current liabilities: other payables accruals and deposits.\"\n        },\n        {\n          \"name\": \"currentLiabilitiesOtherPayablesAndAccruals\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current liabilities: other payables and accruals.\"\n        },\n        {\n          \"name\": \"currentLiabilitiesContractLiabilities\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current liabilities: contract liabilities.\"\n        },\n        {\n          \"name\": \"currentLiabilitiesDerivative\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Current liabilities: derivative.\"\n        },\n        {\n          \"name\": \"totalCurrentLiabilities\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Balance-sheet total: current liabilities.\"\n        },\n        {\n          \"name\": \"shortTermLiabilities\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Balance-sheet total: short-term liabilities.\"\n        },\n        {\n          \"name\": \"nonCurrentLiabilitiesBorrowingsOrTermLoans\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current liabilities: borrowings or term loans.\"\n        },\n        {\n          \"name\": \"nonCurrentLiabilitiesBankBorrowings\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current liabilities: bank borrowings.\"\n        },\n        {\n          \"name\": \"nonCurrentLiabilitiesLeaseObligations\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current liabilities: lease obligations.\"\n        },\n        {\n          \"name\": \"nonCurrentLiabilitiesFinanceLeaseObligations\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current liabilities: finance lease obligations.\"\n        },\n        {\n          \"name\": \"nonCurrentLiabilitiesDeferredTaxation\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current liabilities: deferred taxation.\"\n        },\n        {\n          \"name\": \"nonCurrentLiabilitiesRetirementBenefits\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current liabilities: retirement benefits.\"\n        },\n        {\n          \"name\": \"nonCurrentLiabilitiesHirePurchasePayables\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current liabilities: hire purchase payables.\"\n        },\n        {\n          \"name\": \"nonCurrentLiabilitiesDepositsFromCustomers\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current liabilities: deposits from customers.\"\n        },\n        {\n          \"name\": \"nonCurrentLiabilitiesContractLiabilities\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Non-current liabilities: contract liabilities.\"\n        },\n        {\n          \"name\": \"totalNonCurrentLiabilities\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Balance-sheet total: non-current liabilities.\"\n        },\n        {\n          \"name\": \"totalLiabilities\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Balance-sheet total: liabilities.\"\n        },\n        {\n          \"name\": \"shareCapital\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Equity: share capital.\"\n        },\n        {\n          \"name\": \"preferenceShareCapital\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Equity: preference share capital.\"\n        },\n        {\n          \"name\": \"sharePremium\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Equity: share premium.\"\n        },\n        {\n          \"name\": \"reserves\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Equity: reserves.\"\n        },\n        {\n          \"name\": \"capitalReserves\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Equity: capital reserves.\"\n        },\n        {\n          \"name\": \"revaluationReserves\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Equity: revaluation reserves.\"\n        },\n        {\n          \"name\": \"exchangeEqualisationOrFluctuationReserves\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Equity: exchange equalisation or fluctuation reserves.\"\n        },\n        {\n          \"name\": \"retainedEarnings\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Equity: retained earnings.\"\n        },\n        {\n          \"name\": \"totalEquity\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Balance-sheet total: equity.\"\n        },\n        {\n          \"name\": \"revenue\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Income statement: revenue.\"\n        },\n        {\n          \"name\": \"costOfGoodsSold\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Income statement: cost of goods sold.\"\n        },\n        {\n          \"name\": \"grossProfit\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Income statement: gross profit.\"\n        },\n        {\n          \"name\": \"otherIncome\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Income statement: other income.\"\n        },\n        {\n          \"name\": \"profitFromOperations\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Income statement: profit from operations.\"\n        },\n        {\n          \"name\": \"financeCost\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Income statement: finance cost.\"\n        },\n        {\n          \"name\": \"ebitda\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Income statement: profit before tax (extracted from the statement's profit-before-tax line; canonical name kept verbatim from the host vocabulary).\"\n        },\n        {\n          \"name\": \"taxes\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Income statement: taxes.\"\n        },\n        {\n          \"name\": \"zakat\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Income statement: zakat.\"\n        },\n        {\n          \"name\": \"profitAfterTax\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Income statement: profit after tax.\"\n        },\n        {\n          \"name\": \"netProfit\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Income statement: total comprehensive income for the financial year.\"\n        },\n        {\n          \"name\": \"netOperatingCashFlow\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Cash-flow statement: net cash flow used in / generated from operating activities.\"\n        },\n        {\n          \"name\": \"depreciation\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Cash-flow statement: depreciation.\"\n        },\n        {\n          \"name\": \"depreciationOfPropertyPlantEquipment\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Cash-flow statement: depreciation of property plant equipment.\"\n        },\n        {\n          \"name\": \"depreciationRightOfUseAssets\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Cash-flow statement: depreciation right of use assets.\"\n        },\n        {\n          \"name\": \"depreciationOfInvestmentProperties\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Cash-flow statement: depreciation of investment properties.\"\n        },\n        {\n          \"name\": \"depreciationOfInvestmentSecurities\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Cash-flow statement: depreciation of investment securities.\"\n        },\n        {\n          \"name\": \"endOfYearCash\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Cash-flow statement: cash and cash equivalents at the end of the financial year.\"\n        }\n      ],\n      \"legacyId\": \"finxtract-financial-statement\"\n    },\n    {\n      \"id\": \"company-registration\",\n      \"displayName\": \"SSM Form 9 (Document Extraction)\",\n      \"description\": \"Fields extracted from an uploaded SSM Form 9 (Certificate of Incorporation of Private Company) document by the host's extraction pipeline. One instance per uploaded document. The company name and incorporation date are attestations of shared facts \\u2014 the company-profile and financial-statement extraction categories attest the same real-world facts from their own documents.\",\n      \"canonicalTable\": \"ihs_alt_data_form9\",\n      \"fields\": [\n        {\n          \"name\": \"companyName\",\n          \"type\": \"string\",\n          \"fact\": \"companyName\",\n          \"description\": \"Company name as printed on the certificate. Attestation of the shared companyName fact.\"\n        },\n        {\n          \"name\": \"companyRegNo\",\n          \"type\": \"string\",\n          \"description\": \"Company registration number as printed on the certificate.\",\n          \"fact\": \"companyRegNo\"\n        },\n        {\n          \"name\": \"companyIncorporationDate\",\n          \"type\": \"string\",\n          \"fact\": \"companyIncorporationDate\",\n          \"description\": \"Date of incorporation as printed on the certificate, normalized to ISO YYYY-MM-DD. Attestation of the shared companyIncorporationDate fact \\u2014 a company has exactly one incorporation date regardless of which document it was extracted from.\"\n        }\n      ],\n      \"legacyId\": \"finxtract-form9\"\n    },\n    {\n      \"id\": \"company-profile\",\n      \"displayName\": \"SSM Company Profile (Document Extraction)\",\n      \"description\": \"Fields extracted from an uploaded SSM company-profile document (company or business registration extract) by the host's extraction pipeline. One instance per uploaded document. Covers registration identity, status, key dates, registered address, capital, and the officer/shareholder registers. The incorporation date is an attestation of a shared fact \\u2014 the Form 9 extraction category attests the same real-world fact from its own document.\",\n      \"canonicalTable\": \"ihs_alt_data_ssm\",\n      \"fields\": [\n        {\n          \"name\": \"companyEntityType\",\n          \"type\": \"string\",\n          \"description\": \"Entity type stated on the profile (e.g. private limited company, enterprise).\",\n          \"legacyName\": \"ssmCompanyEntityType\"\n        },\n        {\n          \"name\": \"companyName\",\n          \"type\": \"string\",\n          \"description\": \"Business or company name as stated on the profile.\",\n          \"fact\": \"companyName\"\n        },\n        {\n          \"name\": \"companyRegNo\",\n          \"type\": \"string\",\n          \"description\": \"Business or company registration number as stated on the profile.\",\n          \"fact\": \"companyRegNo\"\n        },\n        {\n          \"name\": \"companyStatus\",\n          \"type\": \"string\",\n          \"description\": \"Registration status as stated on the profile (e.g. existing, dissolved).\"\n        },\n        {\n          \"name\": \"businessOrigin\",\n          \"type\": \"string\",\n          \"description\": \"Business origin as stated on the profile.\"\n        },\n        {\n          \"name\": \"companyIncorporationDate\",\n          \"type\": \"string\",\n          \"fact\": \"companyIncorporationDate\",\n          \"description\": \"Incorporation (or registration) date as stated on the profile, normalized to ISO YYYY-MM-DD. Attestation of the shared companyIncorporationDate fact \\u2014 a company has exactly one incorporation date regardless of which document it was extracted from.\"\n        },\n        {\n          \"name\": \"businessCommencementDate\",\n          \"type\": \"string\",\n          \"description\": \"Business commencement (or start) date as stated on the profile, normalized to ISO YYYY-MM-DD.\"\n        },\n        {\n          \"name\": \"businessNature\",\n          \"type\": \"string\",\n          \"description\": \"Nature of business as stated on the profile.\"\n        },\n        {\n          \"name\": \"registeredAddress\",\n          \"type\": \"string\",\n          \"description\": \"Registered business address as stated on the profile.\"\n        },\n        {\n          \"name\": \"totalShareIssued\",\n          \"type\": \"number\",\n          \"description\": \"Total shares issued as stated on the profile.\"\n        },\n        {\n          \"name\": \"paidUpCapital\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Paid-up capital as stated on the profile (falls back to total shares issued when the profile omits an explicit paid-up figure).\",\n          \"legacyName\": \"ssmPaidUpCapital\"\n        },\n        {\n          \"name\": \"directors\",\n          \"type\": \"string\",\n          \"description\": \"JSON-encoded list of current directors/officers (for enterprises, the business owner normalized into the same shape).\"\n        },\n        {\n          \"name\": \"shareholders\",\n          \"type\": \"string\",\n          \"description\": \"JSON-encoded list of shareholders (for enterprises, the business owner normalized into the same shape).\"\n        },\n        {\n          \"name\": \"previousDirectors\",\n          \"type\": \"string\",\n          \"description\": \"JSON-encoded list of previous directors/officers.\"\n        },\n        {\n          \"name\": \"companyLastOldName\",\n          \"type\": \"string\",\n          \"description\": \"The company's most recent former name, when the profile records a name change.\"\n        },\n        {\n          \"name\": \"companyNameDateOfChange\",\n          \"type\": \"string\",\n          \"description\": \"Date of the most recent name change, normalized to ISO YYYY-MM-DD.\"\n        }\n      ],\n      \"legacyId\": \"finxtract-ssm\"\n    },\n    {\n      \"id\": \"applicant-identity\",\n      \"displayName\": \"Applicant-Provided Identity\",\n      \"description\": \"Identity values the applicant typed into a lending application form. The first NON-DOCUMENT attestor in the registry: every other category is an extraction pipeline reading a document, while these are values a person entered about themselves. One instance per application.\",\n      \"canonicalTable\": \"ihs_alt_data_applicant_identity\",\n      \"fields\": [\n        {\n          \"name\": \"personName\",\n          \"type\": \"string\",\n          \"fact\": \"personName\",\n          \"description\": \"Full name as the applicant entered it. Attestation of the shared personName fact \\u2014 the identity-document, payslip, EPF and bank-statement categories attest the same fact from their own sources. A borrower typing their name differently from their IC is normal, not an error.\"\n        },\n        {\n          \"name\": \"personIdNumber\",\n          \"type\": \"string\",\n          \"fact\": \"personIdNumber\",\n          \"description\": \"IC or passport number as the applicant entered it. Attestation of the shared personIdNumber fact. Forms validate 12 digits with no separators, while the identity document attests it as printed and commonly hyphenated \\u2014 so comparison must normalize before concluding disagreement.\"\n        },\n        {\n          \"name\": \"personDateOfBirth\",\n          \"type\": \"string\",\n          \"fact\": \"personDateOfBirth\",\n          \"description\": \"Date of birth as the applicant entered it, normalized to ISO YYYY-MM-DD. Attestation of the shared personDateOfBirth fact.\"\n        },\n        {\n          \"name\": \"personNationality\",\n          \"type\": \"string\",\n          \"fact\": \"personNationality\",\n          \"description\": \"Nationality as the applicant entered it. Attestation of the shared personNationality fact; free text on both sides, so comparable after normalization.\"\n        }\n      ]\n    },\n    {\n      \"id\": \"applicant-demographics\",\n      \"displayName\": \"Applicant-Provided Demographics\",\n      \"canonicalTable\": \"ihs_alt_data_applicant_demographics\",\n      \"description\": \"Demographic attributes the applicant selected on a lending application form. Split out of applicant-identity (SYS-3166) rather than merged into it, and not cosmetically: every field here is uniformly sensitive, so confidentiality is decided once for the category instead of being re-argued per field a few hundred times over. applicant-identity keeps the legally-identifying facts \\u2014 name, id number, date of birth, nationality \\u2014 which are the subject key under Act 710 s.28. One instance per application.\",\n      \"fields\": [\n        {\n          \"name\": \"statedAge\",\n          \"type\": \"string\",\n          \"description\": \"Age as the applicant entered it. Deliberately NOT a shared fact with personDateOfBirth, and deliberately a string: the column is varchar(10) and forms accept free text, so a value may be a range or a non-numeric answer. An age is also true only on the day it was given \\u2014 observedAt is what makes it interpretable, and it must never be reconciled against a date of birth as though the two were the same claim.\"\n        },\n        {\n          \"name\": \"genderCode\",\n          \"type\": \"string\",\n          \"description\": \"Gender as the applicant SELECTED IT FROM A DROPDOWN \\u2014 a code, not a label. Named apart from person-identity's personGender, and carrying no shared fact, on purpose. The document attests OCR text off a MyKad while the form emits a code ('M', '01') whose meaning is per-form. Collected by 6 of the 60 live form configs, all 6 sharing one choice set today \\u2014 measured per field. Declaring them one fact would put 'M' and 'LELAKI' in the disagreement surface as a permanent false positive on one of its highest-volume fields, and the registry's kind-agreement rule refuses the shortcut anyway. Comparing the two needs a per-form code-to-label resolution that does not exist yet; when it does, the comparison belongs there and not in the field name. NOT declared kind \\\"enum\\\": that promises a CLOSED label set, and the host enforces the promise by requiring every adapter producing the field to enumerate its labels in the manifest. A form-intake adapter cannot: a form config carries its OWN choices, so one can add a value tomorrow without the manifest knowing, and the declaration would go quietly false the first time someone edits a form.\"\n        },\n        {\n          \"name\": \"raceCode\",\n          \"type\": \"string\",\n          \"description\": \"Race as the applicant selected it from a dropdown. Same reasoning as genderCode, and the same deliberate absence of a shared fact with person-identity's personRace. Collected by 12 of the 60 live form configs, all 12 sharing one choice set today \\u2014 measured per field. NOT declared kind \\\"enum\\\": that promises a CLOSED label set, and the host enforces the promise by requiring every adapter producing the field to enumerate its labels in the manifest. A form-intake adapter cannot: a form config carries its OWN choices, so one can add a value tomorrow without the manifest knowing, and the declaration would go quietly false the first time someone edits a form.\"\n        },\n        {\n          \"name\": \"maritalStatus\",\n          \"type\": \"string\",\n          \"description\": \"Marital status as selected. Uniquely declared, so it needs no fact. NOT declared kind \\\"enum\\\": that promises a CLOSED label set, and the host enforces the promise by requiring every adapter producing the field to enumerate its labels in the manifest.\"\n        },\n        {\n          \"name\": \"dependantsCount\",\n          \"type\": \"number\",\n          \"unit\": \"count\",\n          \"description\": \"Number of dependants as the applicant entered it.\"\n        },\n        {\n          \"name\": \"educationLevel\",\n          \"type\": \"string\",\n          \"description\": \"Highest education level as selected. NOT declared kind \\\"enum\\\": that promises a CLOSED label set, and the host enforces the promise by requiring every adapter producing the field to enumerate its labels in the manifest.\"\n        },\n        {\n          \"name\": \"preferredLanguage\",\n          \"type\": \"string\",\n          \"description\": \"Preferred correspondence language as selected. NOT declared kind \\\"enum\\\": that promises a CLOSED label set, and the host enforces the promise by requiring every adapter producing the field to enumerate its labels in the manifest.\"\n        },\n        {\n          \"name\": \"residenceType\",\n          \"type\": \"string\",\n          \"description\": \"Residence type (owned, rented, family-owned, \\u2026) as selected. A housing-tenure signal, which is why it sits here rather than with applicant-address: it describes the person, not a place. NOT declared kind \\\"enum\\\": that promises a CLOSED label set, and the host enforces the promise by requiring every adapter producing the field to enumerate its labels in the manifest.\"\n        }\n      ]\n    },\n    {\n      \"id\": \"applicant-contact\",\n      \"displayName\": \"Applicant-Provided Contact Point\",\n      \"canonicalTable\": \"ihs_alt_data_applicant_contact\",\n      \"description\": \"One way to reach the applicant \\u2014 a phone line, an email address, or an emergency contact. MULTI-instance, keyed by the kind of contact point, because the wide ihs table flattens five phone lines into five column families (mobile, office, international, emergency, and an unqualified phoneNumber) and therefore cannot hold a sixth. The instance key IS what the column suffix was encoding. Fields absent for a given kind are simply absent on that instance rather than being null columns for everyone.\",\n      \"fields\": [\n        {\n          \"name\": \"contactValue\",\n          \"type\": \"string\",\n          \"description\": \"The number or address itself, as the applicant entered it. One field rather than one per kind: what distinguishes a mobile from an office line is the instance, not the column.\"\n        },\n        {\n          \"name\": \"contactAreaCode\",\n          \"type\": \"string\",\n          \"description\": \"Area or country code, where the form captures it separately from the number. Modeled because the wide table carries a matching AreaCode column for four of the five phone families; NO live form config collects any of them today, so no manifest maps it yet. The category describes the domain; a manifest describes what a form actually asks.\"\n        },\n        {\n          \"name\": \"contactExtension\",\n          \"type\": \"string\",\n          \"description\": \"Phone extension. Same status as contactAreaCode \\u2014 one wide column exists (internationalExtensionPhoneNo), no live form collects it.\"\n        },\n        {\n          \"name\": \"contactName\",\n          \"type\": \"string\",\n          \"description\": \"The name of the person reached at this contact point, where that is someone other than the applicant. Populated for the emergency instance. Deliberately NOT sharing personName's fact: this is a THIRD PARTY's name, and attesting it as the subject's would be a genuine identity error, not a formatting one.\"\n        },\n        {\n          \"name\": \"contactRelationship\",\n          \"type\": \"string\",\n          \"description\": \"How the named person relates to the applicant (spouse, parent, employer, \\u2026). Meaningful only alongside contactName. NOT declared kind \\\"enum\\\": that promises a CLOSED label set, and the host enforces the promise by requiring every adapter producing the field to enumerate its labels in the manifest.\"\n        }\n      ]\n    },\n    {\n      \"id\": \"applicant-address\",\n      \"displayName\": \"Applicant-Provided Address\",\n      \"canonicalTable\": \"ihs_alt_data_applicant_address\",\n      \"description\": \"One address the applicant entered on a lending application form. MULTI-instance, keyed by which address it is (\\\"permanent\\\", \\\"residential\\\", \\\"office\\\"), because the wide ihs table spends a whole column family on each and therefore cannot hold a fourth. Declaring this single would re-encode that limit permanently, and unlike a wrong field name it is not repairable later \\u2014 the information would never have been captured. Ragged coverage across the three becomes ABSENT FIELDS on an instance rather than null columns for everyone: the permanent block has no state column of its own (its state landed in the unprefixed `state`), and only the residential block carries an occupancy duration.\",\n      \"fields\": [\n        {\n          \"name\": \"addressLine1\",\n          \"type\": \"string\",\n          \"description\": \"First line of the address, as entered.\"\n        },\n        {\n          \"name\": \"addressLine2\",\n          \"type\": \"string\",\n          \"description\": \"Second line of the address, as entered.\"\n        },\n        {\n          \"name\": \"addressLine3\",\n          \"type\": \"string\",\n          \"description\": \"Third line of the address, as entered.\"\n        },\n        {\n          \"name\": \"addressCity\",\n          \"type\": \"string\",\n          \"description\": \"City or town, as entered.\"\n        },\n        {\n          \"name\": \"addressPostcode\",\n          \"type\": \"string\",\n          \"description\": \"Postcode, as entered. A string rather than a number: Malaysian postcodes are five digits and a leading zero is significant.\"\n        },\n        {\n          \"name\": \"addressStateCode\",\n          \"type\": \"string\",\n          \"description\": \"State as the applicant SELECTED IT FROM A DROPDOWN \\u2014 a code ('A' = PERAK, 'B' = SELANGOR), not a label. Named for what it holds, and carrying no shared fact, for the same reason as applicant-demographics' genderCode: the choice set is defined per form config, so no single adapter can enumerate it and no comparison against a free-text state is meaningful without a per-form resolution that does not exist. NOT declared kind \\\"enum\\\" \\u2014 that promises a closed label set the host makes each producing adapter enumerate, which a form-intake adapter spanning 60 heterogeneous forms cannot do.\"\n        },\n        {\n          \"name\": \"addressCountry\",\n          \"type\": \"string\",\n          \"description\": \"Country, as entered. Modeled because the wide table carries an unprefixed `country` column; NO live form config collects it, so no manifest maps it. The category describes the domain, a manifest describes what a form actually asks.\"\n        },\n        {\n          \"name\": \"occupancyYears\",\n          \"type\": \"number\",\n          \"unit\": \"years\",\n          \"description\": \"How long the applicant has lived at this address, whole years. Meaningful only on the residential instance \\u2014 it is the one block the wide table gives a duration. Kept separate from occupancyMonths rather than folded into a single figure because the form collects two inputs and form intake has no transform slot by design; combining them is a consumer's job, and doing it here would invent a value the applicant never gave.\"\n        },\n        {\n          \"name\": \"occupancyMonths\",\n          \"type\": \"number\",\n          \"unit\": \"months\",\n          \"description\": \"The remainder months of the residency duration above. See occupancyYears for why the pair is not collapsed.\"\n        }\n      ]\n    },\n    {\n      \"id\": \"applicant-employment\",\n      \"displayName\": \"Applicant-Provided Employment\",\n      \"canonicalTable\": \"ihs_alt_data_applicant_employment\",\n      \"description\": \"One job the applicant described on a lending application form. MULTI-instance: a person can hold two jobs and the wide ihs table, which has exactly one unprefixed employment block, cannot say so. Today's form collects only the current one, so the sole adapter emits a single instance under the key \\\"current\\\" \\u2014 an explicit key rather than the empty one, because \\\"\\\" reads as \\\"the single instance a single-cardinality category has\\\" and this category is not that. A second job becomes another row.\",\n      \"fields\": [\n        {\n          \"name\": \"employerName\",\n          \"type\": \"string\",\n          \"fact\": \"employerName\",\n          \"description\": \"Employer name as the applicant entered it. Attestation of the shared employerName fact \\u2014 the PAYSLIP attests the same fact from the document side (SYS-3333 de-prefixed it from payslipEmployerName). This is the pairing the disagreement surface exists for: a borrower naming an employer their payslip does not, or naming it differently, is worth seeing. Free text on both sides, so comparable after normalization.\"\n        },\n        {\n          \"name\": \"employmentStatus\",\n          \"type\": \"string\",\n          \"description\": \"Employment status as selected (permanent, contract, probation, \\u2026). NOT declared kind \\\"enum\\\". Collected by 6 of the 60 live form configs, and all 6 carry an identical choice set today \\u2014 measured per field, not inferred from a sibling. The closure is still not the category's to promise: a form config carries its OWN choices, so one can add a value tomorrow without the manifest knowing, and kind \\\"enum\\\" obliges every producing adapter to enumerate the labels it emits. The declaration would go quietly false the first time someone edits a form.\"\n        },\n        {\n          \"name\": \"employmentType\",\n          \"type\": \"string\",\n          \"description\": \"Employment type as selected. NOT declared kind \\\"enum\\\". Collected by 6 of the 60 live form configs, and all 6 carry an identical choice set today \\u2014 measured per field, not inferred from a sibling. The closure is still not the category's to promise: a form config carries its OWN choices, so one can add a value tomorrow without the manifest knowing, and kind \\\"enum\\\" obliges every producing adapter to enumerate the labels it emits. The declaration would go quietly false the first time someone edits a form.\"\n        },\n        {\n          \"name\": \"occupation\",\n          \"type\": \"string\",\n          \"description\": \"Occupation as selected. NOT declared kind \\\"enum\\\". Collected by 6 of the 60 live form configs, and all 6 carry an identical choice set today \\u2014 measured per field, not inferred from a sibling. The closure is still not the category's to promise: a form config carries its OWN choices, so one can add a value tomorrow without the manifest knowing, and kind \\\"enum\\\" obliges every producing adapter to enumerate the labels it emits. The declaration would go quietly false the first time someone edits a form.\"\n        },\n        {\n          \"name\": \"employmentSector\",\n          \"type\": \"string\",\n          \"description\": \"Employment sector as selected. NOT declared kind \\\"enum\\\". Collected by 6 of the 60 live form configs, and all 6 carry an identical choice set today \\u2014 measured per field, not inferred from a sibling. The closure is still not the category's to promise: a form config carries its OWN choices, so one can add a value tomorrow without the manifest knowing, and kind \\\"enum\\\" obliges every producing adapter to enumerate the labels it emits. The declaration would go quietly false the first time someone edits a form.\"\n        },\n        {\n          \"name\": \"subEmploymentSector\",\n          \"type\": \"string\",\n          \"description\": \"Sub-sector within employmentSector, as selected. NOT declared kind \\\"enum\\\". Collected by 6 of the 60 live form configs, and all 6 carry an identical choice set today \\u2014 measured per field, not inferred from a sibling. The closure is still not the category's to promise: a form config carries its OWN choices, so one can add a value tomorrow without the manifest knowing, and kind \\\"enum\\\" obliges every producing adapter to enumerate the labels it emits. The declaration would go quietly false the first time someone edits a form.\"\n        },\n        {\n          \"name\": \"businessSector\",\n          \"type\": \"string\",\n          \"description\": \"Business sector of the employer. Modeled because the wide table carries the column; NO live form collects it, so no manifest maps it.\"\n        },\n        {\n          \"name\": \"dateJoined\",\n          \"type\": \"string\",\n          \"description\": \"Date the applicant joined this employer, as entered. A string, matching the source column's varchar(50) and the same treatment personDateOfBirth gets: forms accept a range of spellings and narrowing here would reject values the form already takes.\"\n        },\n        {\n          \"name\": \"lengthOfServiceYears\",\n          \"type\": \"number\",\n          \"unit\": \"years\",\n          \"description\": \"Length of service, whole years. Modeled because the wide table carries the column; no live form collects it. Kept separate from lengthOfServiceMonths for the same reason applicant-address keeps occupancy years and months apart \\u2014 form intake has no transform slot, so folding two figures into one would invent a value nobody gave.\"\n        },\n        {\n          \"name\": \"lengthOfServiceMonths\",\n          \"type\": \"number\",\n          \"unit\": \"months\",\n          \"description\": \"Remainder months of the length of service. See lengthOfServiceYears.\"\n        }\n      ]\n    },\n    {\n      \"id\": \"applicant-income\",\n      \"displayName\": \"Applicant-Provided Income\",\n      \"canonicalTable\": \"ihs_alt_data_applicant_income\",\n      \"description\": \"The applicant's stated income position. SINGLE-instance: unlike employment, these describe the person overall rather than one job, and the wide table's single block is not a limitation being inherited here \\u2014 it matches what is being said.\",\n      \"fields\": [\n        {\n          \"name\": \"grossPay\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"fact\": \"grossPay\",\n          \"legacyName\": \"monthlyGrossIncome\",\n          \"description\": \"Gross pay as the applicant stated it, monthly. Attestation of the shared grossPay fact, which the PAYSLIP attests from the document side. COMPARISON MUST CHECK THE PERIOD FIRST: a payslip's grossPay is the gross for ITS pay period, and the payslip category carries payPeriod for exactly that reason \\u2014 a monthly statement compared against a fortnightly payslip disagrees by construction, not because anyone was wrong. The fact is shared because the two ARE the same quantity once the period is known, which is what distinguishes this from applicant-demographics' genderCode, where no resolution between the two sides exists at all.\"\n        },\n        {\n          \"name\": \"netPay\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"fact\": \"netPay\",\n          \"legacyName\": \"monthlyNetIncome\",\n          \"description\": \"Net pay as the applicant stated it, monthly. Attestation of the shared netPay fact, also attested by the payslip. Same period caveat as grossPay. Modeled but NOT mapped by any manifest: the wide table carries monthlyNetIncome and no live form collects it.\"\n        },\n        {\n          \"name\": \"sourceOfFund\",\n          \"type\": \"string\",\n          \"description\": \"Stated source of funds. NOT declared kind \\\"enum\\\". Collected by 6 of the 60 live form configs, and all 6 carry an identical choice set today \\u2014 measured per field, not inferred from a sibling. The closure is still not the category's to promise: a form config carries its OWN choices, so one can add a value tomorrow without the manifest knowing, and kind \\\"enum\\\" obliges every producing adapter to enumerate the labels it emits. The declaration would go quietly false the first time someone edits a form.\"\n        },\n        {\n          \"name\": \"sourceOfWealth\",\n          \"type\": \"string\",\n          \"description\": \"Stated source of wealth. NOT declared kind \\\"enum\\\". Collected by 6 of the 60 live form configs, and all 6 carry an identical choice set today \\u2014 measured per field, not inferred from a sibling. The closure is still not the category's to promise: a form config carries its OWN choices, so one can add a value tomorrow without the manifest knowing, and kind \\\"enum\\\" obliges every producing adapter to enumerate the labels it emits. The declaration would go quietly false the first time someone edits a form.\"\n        },\n        {\n          \"name\": \"computationMode\",\n          \"type\": \"string\",\n          \"description\": \"How the stated income was computed. Modeled because the wide table carries the column; no live form collects it.\"\n        },\n        {\n          \"name\": \"statementType\",\n          \"type\": \"string\",\n          \"description\": \"Statement type backing the stated income. Modeled because the wide table carries the column; no live form collects it.\"\n        }\n      ]\n    },\n    {\n      \"id\": \"subject-company\",\n      \"displayName\": \"Applicant-Provided Company Profile\",\n      \"canonicalTable\": \"ihs_alt_data_subject_company\",\n      \"description\": \"The company an application is about, as the applicant describes it. SINGLE-instance: one application has one subject company. THREE fields, not the six wide columns the transition plan grouped here \\u2014 companyBackground, noOfEmployees and companyWebsite are collected by no live form in either population (0 of 4,622 ihs rows), and a field no form can feed is a promise this category cannot keep. They stay wide-table-only until something collects them. The three that ARE collected arrive from the lead-gen SPAs, not from FinHub's form_configs; a measurement over form_configs alone reports all six as uncollected, which is exactly how this category came to be dropped once already.\",\n      \"fields\": [\n        {\n          \"name\": \"entityTypeCode\",\n          \"type\": \"string\",\n          \"description\": \"Legal entity type of the subject company as the applicant SELECTED IT FROM A DROPDOWN \\u2014 a code, not a label. Named apart from company-profile's companyEntityType, and carrying no shared fact, on purpose: that one is OCR-read off the SSM document, this one is a code whose meaning is per-form. Exactly the genderCode / personGender split, for exactly the same reason \\u2014 the registry enforces it, refusing one name across two categories unless both attest the same fact. NOT declared kind \\\"enum\\\": that promises a CLOSED label set, and the only form collecting this is a lead-gen SPA whose config is compiled into a bundle shipped from a separate repo, so the choice set can change without this registry or any manifest knowing.\"\n        },\n        {\n          \"name\": \"companySizeCode\",\n          \"type\": \"string\",\n          \"description\": \"Stated size band of the subject company, as a per-form dropdown code. Same naming and enum reasoning as entityTypeCode. A band, not a count: noOfEmployees is the count, nothing collects it, so this can be neither derived from nor checked against one.\"\n        },\n        {\n          \"name\": \"businessNatureCode\",\n          \"type\": \"string\",\n          \"description\": \"Stated nature of the subject company's business, as a per-form dropdown code. Named apart from company-profile's businessNature \\u2014 which is OCR-read off the SSM document \\u2014 for the same reason entityTypeCode is named apart, even though the two spellings do not collide and the registry would not have objected. Relying on a spelling difference nobody chose deliberately is how a shared fact gets asserted by accident.\"\n        }\n      ]\n    },\n    {\n      \"id\": \"applicant-collateral\",\n      \"displayName\": \"Applicant-Provided Collateral\",\n      \"canonicalTable\": \"ihs_alt_data_applicant_collateral\",\n      \"description\": \"The asset offered as security on a lending application, as the applicant (or the lender's own Open API caller) stated it. MULTI-instance, and not speculatively: finsys-api's lender Open API already models this block as `collateral[0]` \\u2014 an ARRAY (see COLLATERAL_FIELDS in src/utils/ihsFieldDefs.ts) \\u2014 so more than one collateral item is the EXISTING published contract, while the wide `ihs` table has exactly one column per attribute and can therefore hold exactly one item. The instance key is the array index the contract already uses, so a second collateral is one more row rather than eleven more columns. Every field describes a MOTOR VEHICLE, and is named for that rather than for the generic role, because the category's whole field set is vehicle-specific (a chassis number, an engine number and a laden-weight flag say nothing about a property or a machine). Naming them collateralIdentifier / collateralAttribute would buy a generality the data cannot honour; property or equipment collateral gets its own category with its own facts, and this one stays honest about what it can describe.\",\n      \"fields\": [\n        {\n          \"name\": \"vehicleMake\",\n          \"type\": \"string\",\n          \"description\": \"Manufacturer of the vehicle offered as collateral, as stated. No live form config collects it today \\u2014 measured across BOTH form-spec populations on 2026-08-15 (0 of the 60 FinHub form_configs, 0 of the four lead-gen SPA bundles) and 0 of 4,624 rows in the sim's `ihs`. It is declared anyway, on the applicant-contact precedent (contactAreaCode / contactExtension), and on a stronger basis than that precedent had: the wide column exists AND `makeOfVehicle` is an authorable field in @finsys/core's own v2 form catalog (form-field-base-specs.json, category 12 'Vehicle Information'), so a lender can put it on a form today without any change here. A category describes the domain; a manifest describes what a form actually asks.\",\n          \"legacyName\": \"makeOfVehicle\"\n        },\n        {\n          \"name\": \"vehicleModel\",\n          \"type\": \"string\",\n          \"description\": \"Model of the vehicle offered as collateral. COLLECTED \\u2014 by the finhero-auto lead-gen SPA, whose form spec is compiled into the SPA bundle and is therefore invisible to any query over FinHub's form_configs table. That second population is why this field is mapped and vehicleMake is not: measuring form_configs alone reports `modelOfVehicle` as collected by nobody, while the sim's `ihs` carries 8 rows of it. On the finhero-auto form the field is `visible: false` \\u2014 a hidden input the page fills rather than a question the applicant answers. It is still an applicant-side statement submitted through the form save, so it is attested; the hidden-ness is a UX fact, not a provenance one.\",\n          \"legacyName\": \"modelOfVehicle\"\n        },\n        {\n          \"name\": \"vehicleYearMake\",\n          \"type\": \"number\",\n          \"unit\": \"count\",\n          \"range\": [\n            1900,\n            2100\n          ],\n          \"description\": \"Model year of the vehicle, as a four-digit year. Not collected by any live form (0/60 form_configs, 0/4 SPAs, 0/4,624 `ihs` rows) and declared for the same reason as vehicleMake \\u2014 `yearMake` is authorable in the v2 catalog, which bounds it [2014, 2100] per-form. The range here is deliberately WIDER than any one form's: a category bound must hold for every lender, and a used-vehicle programme can legitimately accept a 1998 model. The unit is `count` rather than `years` because this is a calendar year \\u2014 a position on a timeline \\u2014 not a duration; `years` on this field would read as an age and be wrong by about two thousand.\",\n          \"legacyName\": \"yearMake\"\n        },\n        {\n          \"name\": \"vehicleConditionCode\",\n          \"type\": \"string\",\n          \"description\": \"Condition of the vehicle as the applicant SELECTED IT FROM A DROPDOWN \\u2014 a code, not a label. COLLECTED: 6 of the 60 FinHub form_configs plus the finhero-auto SPA, all seven carrying the same choice set today ('N', 'U', 'UN', 'UR', 'PR'), measured 2026-08-15. Named `...Code` on the genderCode / raceCode precedent, and for the same reason: a future document attestor (a JPJ registration card, a valuation report) would attest the printed condition TEXT, and fusing a per-form code with OCR'd prose puts a permanent false positive into the disagreement surface. When the two need comparing, the comparison belongs in a per-form code-to-label resolution, not in a shared field name. NOT declared kind \\\"enum\\\": that promises a CLOSED label set and obliges every producing adapter to enumerate its labels in its manifest. A form-intake adapter cannot honour that \\u2014 the choice set lives in a form config a lender can edit, so the promise goes quietly false the first time someone adds a sixth condition. That the seven live forms agree today is precisely the kind of measurement that expires.\",\n          \"legacyName\": \"vehicleCondition\"\n        },\n        {\n          \"name\": \"vehicleChassisNo\",\n          \"type\": \"string\",\n          \"description\": \"Chassis / VIN of the vehicle. Not collected by any live form today (0/60, 0/4, 0/4,624) and authorable in the v2 catalog. Declared rather than deferred because it is the vehicle's IDENTITY: it is the field a second attestor (a registration document extraction, a JPJ lookup) would key on, and reserving the canonical name now is what lets that attestor arrive as a manifest rather than as a registry change.\",\n          \"legacyName\": \"chassisNo\"\n        },\n        {\n          \"name\": \"vehicleEngineNo\",\n          \"type\": \"string\",\n          \"description\": \"Engine number of the vehicle. Same status and same reasoning as vehicleChassisNo: uncollected today, authorable in the v2 catalog, and an identity fact a document attestor would key on.\",\n          \"legacyName\": \"engineNo\"\n        },\n        {\n          \"name\": \"vehicleRegistrationNo\",\n          \"type\": \"string\",\n          \"description\": \"Registration (plate) number of the vehicle. Uncollected today, authorable in the v2 catalog. The third identity fact, and the one a human would actually use to tell two collateral instances apart \\u2014 worth noting that it CANNOT serve as the instance key, because form intake has no transform slot and an instance key must be a literal in the manifest.\",\n          \"legacyName\": \"registrationNo\"\n        },\n        {\n          \"name\": \"vehicleRegistrationDate\",\n          \"type\": \"string\",\n          \"description\": \"Date the vehicle was first registered, as stated. Typed `string`, not a date primitive, and deliberately: the source column `ihs.registrationDate` is varchar(50), the v2 catalog authors it as a text input with inputType date, and neither constrains the format. Declaring it a narrower type here would assert a normalization that nothing performs \\u2014 the value is whatever the form sent, and observedAt is what makes it interpretable.\",\n          \"legacyName\": \"registrationDate\"\n        },\n        {\n          \"name\": \"vehicleLadenWeightOver2500kg\",\n          \"type\": \"string\",\n          \"description\": \"Whether the vehicle's BDM (berat dengan muatan \\u2014 laden weight) exceeds 2,500 kg, as stated. A commercial-vehicle discriminator that changes the applicable financing rules. Typed `string` and NOT `boolean`, which is the non-obvious call: the fact is boolean-shaped, but `ihs.bdmMoreThan2500kg` is varchar(10) and the v2 catalog authors it as a free TEXT input, so the values that actually arrive are whatever a form emits \\u2014 'Y', 'N', 'Yes', ''. Declaring `boolean` would make the contract assert a coercion nobody performs, and the coercion's failure mode is silent: a truthiness test turns the string 'N' into true. Uncollected by any live form today.\",\n          \"legacyName\": \"bdmMoreThan2500kg\"\n        },\n        {\n          \"name\": \"collateralMarketValue\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"Assessed market value of the collateral. Prefixed `collateral` rather than named bare `marketValue` because a bare one would be a name a company valuation, a property appraisal or a share price could all claim later \\u2014 and under this registry's rules a second category claiming the name would have to attest the SAME fact, which they do not. kind \\\"money\\\": the number is meaningless without a denomination, and the denomination belongs to the observation, not the field. Uncollected by any live form today; authorable in the v2 catalog.\",\n          \"legacyName\": \"marketValue\"\n        },\n        {\n          \"name\": \"collateralPurchasePriceOnTheRoad\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"On-the-road purchase price of the collateral \\u2014 the price including registration, road tax and insurance, which is the figure Malaysian motor financing is actually written against. COLLECTED, and the most widely collected field in this category: 6 of the 60 FinHub form_configs plus the finhero-auto SPA (where it is the loan calculator's primary input), 8 of 4,624 `ihs` rows, measured 2026-08-15. Spelled out rather than left as the acronym OTR so the contract is readable by a consumer who has never seen a Malaysian motor quote; the legacy flat column keeps its `purchasePriceOTR` spelling. kind \\\"money\\\" \\u2014 and note the v2 form catalog already declares this same field kind \\\"money\\\", so the two vocabularies agree on it.\",\n          \"legacyName\": \"purchasePriceOTR\"\n        }\n      ]\n    },\n    {\n      \"id\": \"applicant-obligations\",\n      \"displayName\": \"Applicant-Declared Monthly Obligations\",\n      \"canonicalTable\": \"ihs_alt_data_applicant_obligations\",\n      \"description\": \"One existing monthly debt commitment the applicant declared \\u2014 the input to a debt-service ratio. MULTI-instance, keyed by the kind of obligation, and this is the textbook case for the whole transition: the wide `ihs` table spends five columns on five FIXED kinds (housing loan, hire purchase, personal loan, credit card, other financing), so an applicant with a SIXTH commitment has nowhere to put it and the DSR is computed from an amount that is knowably incomplete. Five columns collapse to two fields; the kind moves from the column NAME into a value, and a sixth obligation becomes one more row. NO adapter maps this category today and that is deliberate rather than unfinished \\u2014 no live form collects any of the five columns (measured 2026-08-15 across both form-spec populations: 0 of 60 FinHub form_configs, 0 of the four lead-gen SPA bundles, and 0 of 4,624 rows in the sim's `ihs`), so a form-intake manifest over them would mint an APPLICANT attestation for a value no applicant ever gave. The declaration is the useful half: it reserves the vocabulary, states the shape, and lets the manifest arrive as a declaration when a lender authors the fields (all five are already authorable in @finsys/core's v2 form catalog, category 4 'Financial Information').\",\n      \"fields\": [\n        {\n          \"name\": \"obligationType\",\n          \"type\": \"string\",\n          \"description\": \"What kind of commitment this instance is \\u2014 housing loan, hire purchase, personal loan, credit card, other financing, or something none of those five named. Carries no legacyName ON PURPOSE: there is no flat column it renames, because in the flat shape this value was not stored at all \\u2014 it was encoded in WHICH of the five columns held a number. That is the specific thing this category changes. NOT declared kind \\\"enum\\\": the five wide columns look like a closed set and are exactly the set that proved too small, so promising closure here would re-create the defect in the contract that the schema change exists to remove.\"\n        },\n        {\n          \"name\": \"obligationMonthlyInstallment\",\n          \"type\": \"number\",\n          \"kind\": \"money\",\n          \"description\": \"The monthly amount payable on this commitment. Carries no legacyName, and could not: FIVE flat columns (housingLoanMonthlyInstallment, hirePurchaseMonthlyInstallment, personalLoanMonthlyInstallment, creditCardMonthlyInstallment, otherFinancingMonthlyInstallment) all collapse into this one field, so any single legacy name would be correct for one of them and a lie about the other four. The mapping back to the flat vocabulary is (obligationType, obligationMonthlyInstallment) -> column, which is a per-instance function and not a field rename. kind \\\"money\\\".\"\n        }\n      ]\n    },\n    {\n      \"id\": \"related-person\",\n      \"displayName\": \"Related Person\",\n      \"canonicalTable\": \"ihs_alt_data_related_person\",\n      \"description\": \"A person other than the applicant who stands in a declared ROLE to the application \\u2014 a company's named contact person, a director, a guarantor, a next of kin. MULTI-instance, keyed by role. Distinct from applicant-contact, which is the nearest neighbour and the one worth drawing the line against: applicant-contact models a CHANNEL (a phone line, an email address) and carries contactName / contactRelationship so an emergency contact's channel can say whose it is. It cannot carry an id number, an id type or a date of birth, and it should not \\u2014 a contact POINT that carried identity facts would be two things at once. This category models the PERSON, with identity, and lets their contact details hang off them. NO adapter maps it today, and the reason is stronger here than for applicant-obligations: the eight wide `ihs` columns behind it (contactPersonName, contactPersonEmail, contactPersonPhoneNo, contactPersonPhoneNoAreaCode, contactPersonDateOfBirth, contactPersonPosition, contactPersonIdNo, contactPersonIdType) are ABSENT FROM @finsys/core's v2 form-authoring catalog entirely \\u2014 verified 2026-08-15 against src/data/form-field-base-specs.json, where all 173 authorable fields were checked and none of the eight appears. So unlike applicant-collateral's unused fields, a lender CANNOT put these on a form today even if they wanted to: the columns are reachable only through the lender Open API's own payload, not through any form a borrower fills. 0 of 4,624 rows in the sim's `ihs` carry any of them. Declaring the category without a manifest states the shape and reserves the names; adding the fields to the authoring catalog is what would make a manifest meaningful, and that is a form-authoring change, not this one.\",\n      \"fields\": [\n        {\n          \"name\": \"relatedPersonName\",\n          \"type\": \"string\",\n          \"description\": \"The related person's name, as given. Deliberately does NOT share person-identity's personName fact \\u2014 the same call applicant-contact made for contactName, and for the same reason: this is a THIRD PARTY's name, and attesting it as the subject's would be a genuine identity error rather than a formatting disagreement. A shared fact means 'two sources describing one real-world thing'; these are two different people.\",\n          \"legacyName\": \"contactPersonName\"\n        },\n        {\n          \"name\": \"relatedPersonIdNumber\",\n          \"type\": \"string\",\n          \"description\": \"The related person's identification number (NRIC, passport, or whatever relatedPersonIdType names). Same third-party reasoning as relatedPersonName: no shared fact with personIdNumber.\",\n          \"legacyName\": \"contactPersonIdNo\"\n        },\n        {\n          \"name\": \"relatedPersonIdType\",\n          \"type\": \"string\",\n          \"description\": \"Which kind of identification relatedPersonIdNumber is. NOT declared kind \\\"enum\\\": that promises a CLOSED label set and obliges every producing adapter to enumerate its labels, and there is no adapter to consult \\u2014 the value arrives through the lender Open API from a caller whose vocabulary is its own.\",\n          \"legacyName\": \"contactPersonIdType\"\n        },\n        {\n          \"name\": \"relatedPersonDateOfBirth\",\n          \"type\": \"string\",\n          \"description\": \"The related person's date of birth, as given. Typed `string` because the source column is a DATE but the value arriving through the Open API is unnormalized text, and because no shared fact ties it to personDateOfBirth \\u2014 a different person's birthday is not a competing attestation of the applicant's.\",\n          \"legacyName\": \"contactPersonDateOfBirth\"\n        },\n        {\n          \"name\": \"relatedPersonRole\",\n          \"type\": \"string\",\n          \"description\": \"How this person relates to the application \\u2014 director, authorized contact, guarantor, next of kin. This is the instance key's meaning made explicit as a value, on the same reasoning as obligationType: a role encoded only in the key is invisible to a reader holding one row. NOT declared kind \\\"enum\\\". Renames the wide column contactPersonPosition, which named the person's job title within a company; `role` is the wider and more accurate word, since a guarantor holds no position.\",\n          \"legacyName\": \"contactPersonPosition\"\n        },\n        {\n          \"name\": \"relatedPersonEmail\",\n          \"type\": \"string\",\n          \"description\": \"Email address for the related person.\",\n          \"legacyName\": \"contactPersonEmail\"\n        },\n        {\n          \"name\": \"relatedPersonPhone\",\n          \"type\": \"string\",\n          \"description\": \"Phone number for the related person, as given.\",\n          \"legacyName\": \"contactPersonPhoneNo\"\n        },\n        {\n          \"name\": \"relatedPersonPhoneAreaCode\",\n          \"type\": \"string\",\n          \"description\": \"Area or country code, where it is captured separately from the number. Kept as its own field rather than folded into relatedPersonPhone because the wide table captures the two separately and there is no transform slot anywhere on the intake path that could join them \\u2014 joining here would invent a value nobody gave.\",\n          \"legacyName\": \"contactPersonPhoneNoAreaCode\"\n        }\n      ]\n    },\n    {\n      \"id\": \"document-intake\",\n      \"displayName\": \"Document Intake\",\n      \"description\": \"One instance per uploaded document file. This category is about the POINTER, not the document's contents — the extracted values already live in bank-statement, payslip, financial-statement and the rest, each carrying full provenance. The pointer itself had none: it is a bare string, or a JSON array of them, sitting in a wide column with no record of who put it there or when. This gives a pointer the same standing as every other fact on the canonical plane. It carries no value parsed OUT of the document, deliberately — a category mixing a file's identity with a file's contents would make it impossible to say which adapter run attested what.\",\n      \"canonicalTable\": \"ihs_alt_data_document_intake\",\n      \"fields\": [\n        {\n          \"name\": \"documentType\",\n          \"type\": \"string\",\n          \"description\": \"Which document slot this file was uploaded into — the applicant-facing kind, e.g. a payslip, a bank statement, a company registration form. Deliberately NOT declared kind: \\\"enum\\\". The closed set of slots belongs to the host, it varies by jurisdiction and by form catalog, and restating it here would create a second list that has to be kept in step with the first. A registry naming a value it does not own is how two declarations of one fact begin to disagree.\"\n        },\n        {\n          \"name\": \"pathInDms\",\n          \"type\": \"string\",\n          \"description\": \"Where the file lives in document storage. This is the value the legacy wide columns held directly, and the reason they could not be trusted: nothing recorded which write path set it, so a pointer overwritten by one caller was indistinguishable from a pointer set by another. As a canonical field it arrives attached to a run, which is the whole of the difference.\"\n        },\n        {\n          \"name\": \"uploadedAt\",\n          \"type\": \"string\",\n          \"description\": \"When the file was uploaded, as an ISO 8601 timestamp. Distinct from the adapter run's own observedAt, which records when the pointer was ATTESTED — a backfill of existing pointers observes years-old uploads, and collapsing the two would date every historical document to the day the migration ran.\"\n        },\n        {\n          \"name\": \"uploadedBy\",\n          \"type\": \"string\",\n          \"description\": \"Who uploaded the file — the acting principal, not the subject the document is about. The applicant, an agent acting for them, and a lender staging a document on their behalf are three different answers and only this field separates them. It is the one part of the stored file shape that had no home before: one upload route wrote it ad hoc into a single column's entries, so for every other document the answer was simply unrecoverable.\"\n        }\n      ]\n    }\n  ]\n}\n","/*\n * Copyright 2025 Sisters Inspire Sdn Bhd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Generic adapter category catalogue.\n *\n * Each category declares the canonical field set produced by any\n * adapter of that category — regardless of vendor. This is the\n * public, vendor-agnostic vocabulary that clients (finhub views,\n * finsys-client eval engine, CRA report renderer) read so they know\n * what data shape to expect from a given alt-data source TYPE.\n *\n * Specific vendor implementations (e.g. \"example-telco-v1\",\n * \"example-payments-v1\") live OUTSIDE this open-source package, in private\n * extension directories loaded by the host app. The category schemas\n * are the publication boundary — vendors map their raw payload to\n * these canonical fields; clients render against these canonical\n * fields. Vendor identity never crosses that boundary.\n *\n * SYS-2500 (extensible categories)\n * --------------------------------\n * The category id set used to be a hardcoded TypeScript union, kept in\n * sync by hand with the data file and the manifest JSON-schema enum\n * (three sources of truth, a drift test, and a deliberate edit in each\n * place to add a category). It is now backed by a single source of\n * truth: this package's `data/adapter-categories.json`, loaded +\n * validated into a runtime registry at module load. Adding a category\n * is a JSON-file edit plus a finsys-core minor bump — no union edit, no\n * schema enum edit. `AdapterCategory` is an open `string`; membership\n * is validated at trust boundaries via `isAdapterCategory()` /\n * `assertAdapterCategory()`.\n */\n\nimport categoriesData from \"./data/adapter-categories.json\" with { type: \"json\" };\n\nimport type {\n  AdapterCategoryId,\n  CanonicalFieldNameLiteral,\n  RetiredFieldName,\n} from \"./vocabulary.generated.js\";\n\n/**\n * Adapter category identifier.\n *\n * A LITERAL UNION, generated from the registry (SYS-3347). It was an open\n * `string` from the registry-loaded rework, on reasoning that was sound while the set only\n * GREW: growth is backwards-compatible, so a runtime check sufficed.\n *\n * That stopped holding the moment names get RETIRED. The registry's own\n * lookups fail open by design — `resolveCanonicalCategoryId` answers null and\n * every caller treats null as \"not a rename\", permissively — so a retired id\n * left in a consumer is a silent miss at runtime with nothing to observe. A\n * rename therefore had to be found by hand, which is exactly what it cost.\n *\n * Compile-time membership converts that into a build failure at the site that\n * needs editing, and tsc suggests the replacement by proximity. Boundary\n * validation with `isAdapterCategory()` / `assertAdapterCategory()` is still\n * required for values arriving from OUTSIDE the build — types are erased, so\n * they say nothing about a JSON payload or a database row.\n */\nexport type AdapterCategory = AdapterCategoryId;\n\n/**\n * Every canonical field name any category declares — a LITERAL UNION,\n * generated from the registry (SYS-3347). See `AdapterCategory` above for why\n * this is no longer `string`.\n *\n * Adapter `produces` lists are typed `ReadonlyArray<CanonicalFieldName>`, so a\n * manifest naming a retired field now fails to compile. The host still\n * validates membership against the adapter's CATEGORY at registration — the\n * union says the name exists somewhere, not that it belongs to this category,\n * and only the runtime check can say the latter.\n */\nexport type CanonicalFieldName = CanonicalFieldNameLiteral;\n\n/**\n * Per-field metadata for a canonical field declared by a category.\n * Frozen at module load — the data file is authoritative.\n */\nexport interface CanonicalFieldSpec {\n  readonly name: CanonicalFieldName;\n  readonly type: \"number\" | \"boolean\" | \"string\";\n  readonly unit?: string;\n  readonly range?: readonly [number, number];\n  readonly description: string;\n  /**\n   * Global fact identifier marking this field as an ATTESTATION of a\n   * shared real-world fact (e.g. a company has exactly one\n   * incorporation date, no matter which document it was extracted\n   * from). Multiple categories may declare the SAME field name iff\n   * every declaring category carries the same `fact` id — each\n   * category's value is then an independent attestation of one fact,\n   * comparable across sources (the future disagreement-comparison\n   * feature's unit of comparison). A `fact` id is bound to exactly one\n   * field name registry-wide; by convention the field name IS the fact\n   * id. Uniquely-declared fields need no `fact` (but may carry one).\n   */\n  readonly fact?: string;\n  /**\n   * SYS-3333: the name this field had in the LEGACY flat vocabulary, when\n   * the canonical rename moved it.\n   *\n   * It exists because the two vocabularies were identical until the rename,\n   * and code quietly relied on that. `isMonetaryField` in ihs-processing.ts\n   * is the worked example: it is handed a FLAT column name and matches it\n   * against the set of CANONICAL names declared `kind: \"money\"`. That worked\n   * only while `payslipGrossPay` was both. Rename the canonical side alone\n   * and the lookup silently misses — a money value renders as a bare number\n   * beside its denominated neighbours, which is the precise failure\n   * SYS-3249's denomination work exists to prevent. No exception, no log\n   * line, just a wrong-looking table.\n   *\n   * So the alias lives ON the field it renames rather than in a side map: a\n   * side map can drift, and this one is load-bearing for as long as the flat\n   * columns exist (Phase 6 drops them, and this goes with them).\n   *\n   * A legacyName is NOT a second canonical name. It never widens what an\n   * adapter may `produce`, it is not addressable in an eval model, and it\n   * carries no fact — it is a one-way lookup for code bridging the two\n   * vocabularies during the transition.\n   */\n  readonly legacyName?: string;\n  /**\n   * Field kind — a semantic refinement of `type`.\n   *\n   * `\"enum\"`: the field's value is one label out of a closed set. The\n   * category declares ONLY that the field is enumerated — never the\n   * values, never an ordering. Value sets are vendor territory: each\n   * adapter declares the exact labels it emits in its manifest's\n   * `enumValues` (host-validated), because two vendors implementing the\n   * same category may bucket differently. Ordering and scoring\n   * interpretation live even further out, in the consumer (an eval\n   * model's per-value mapping) — an enum label is data, what it is\n   * worth is opinion, and opinions don't belong in the data contract.\n   * An enum field MUST be `type: \"string\"` (labels are\n   * string-normalized) and MUST NOT declare a `range` (labels are\n   * unordered).\n   *\n   * `\"money\"` (SYS-3249): the field's value is a monetary amount, and is\n   * therefore INCOMPLETE ON ITS OWN. The primitive is still a number —\n   * which is why this is a refinement of `type` rather than a member of\n   * it — but the number means nothing without a denomination, and the\n   * denomination belongs to the observation, not to the field. One\n   * source can report several currencies in a single document, so a\n   * field-level currency could never be right for more than one of them.\n   * The denomination travels with the value on its provenance envelope\n   * (`IhsFieldProvenance.currency`).\n   *\n   * A money field MUST be `type: \"number\"`, MUST NOT declare a `unit`\n   * (there is no unit that is true of the quantity — see\n   * `VALID_FIELD_UNITS`), and MUST NOT declare a `range`: a numeric\n   * bound on money is denominated by definition, so it can only ever be\n   * correct in one currency. `telcoArpuMyr [0, 10000]` was a sane\n   * Malaysian bound and is roughly twenty times too small in VND, where\n   * ARPU runs about 200,000 — every non-MY row would have failed a\n   * constraint the data contract asserted about all of them.\n   */\n  readonly kind?: \"enum\" | \"money\";\n  /**\n   * SYS-3164: the field's confidentiality class. The ONLY way to declare\n   * one is to opt OUT.\n   *\n   * ABSENT MEANS SENSITIVE. There is deliberately no `\"sensitive\"`\n   * spelling: a field is sensitive unless someone has looked at it and\n   * said otherwise, so the failure mode of forgetting is a field that is\n   * over-protected, never one that is silently exposed. That polarity is\n   * not a preference — it is the lesson already recorded in finhub's\n   * SYS-2806 audit-redaction allowlist, where \"a newly added IHS column\n   * that's never classified here defaults to sensitive, not safe\" is the\n   * property that makes the list safe to add columns around. An opt-in\n   * `sensitive: true` flag inverts exactly that: every field anyone\n   * forgot to mark ships in the clear, and neither the data nor the\n   * types surface it.\n   *\n   * What consumes it: canonical storage encrypts sensitive fields at\n   * rest. Access-time gating (`fieldAuthorizations`) is its sibling —\n   * that says who may read a field, this says how it is held when\n   * nobody is reading it.\n   *\n   * TWO LIMITS, so this is not read as more coverage than it is:\n   *\n   * It reaches CANONICAL data only. `confidentiality` lives on a\n   * category's field spec, and no category is canonical over the legacy\n   * wide `ihs` table — the categories cover the `ihs_alt_data_*` tables\n   * and the promoted document tables. A field still living in an `ihs`\n   * column is untouched by this until the adapter transition relocates\n   * it.\n   *\n   * And the raw payload is a sibling hole. The same values are stored\n   * again, unencrypted, in the host's raw-payload table (see\n   * docs/security-model.md: \"Assume the raw payload is durably stored\"),\n   * under its own retention window. Encrypting the canonical column\n   * while the identical value sits in the clear next to it makes the\n   * guarantee \"at rest, in one of two places\" — so the consumer that\n   * honours this must cover both, or say plainly that it does not.\n   *\n   * Shared-fact attestations must AGREE on this (enforced at load): one\n   * real-world fact cannot be sensitive when a document attests it and\n   * non-sensitive when a form does.\n   *\n   * SYS-3171: ALWAYS PRESENT on a built spec, even though authoring stays\n   * opt-out-only (see RawCategoryField, where it remains optional and\n   * `\"sensitive\"` is still unspellable). The asymmetry is the point.\n   *\n   * The registry is serialised verbatim to finhub and finsys-client, and\n   * on that wire \"absent means sensitive\" is carried by NOTHING — a\n   * consumer writing `if (field.confidentiality) protect()` reads exactly\n   * backwards and compiles clean. Emitting the value explicitly makes the\n   * invariant structural rather than documented: every read surface,\n   * including the JSON, states the class outright.\n   */\n  readonly confidentiality: \"sensitive\" | \"non-sensitive\";\n}\n\n/**\n * Per-category schema bundle. Used by:\n *   - host app: validate adapter `produces` lists at registration\n *   - clients (finhub, finsys-client): render UI conditionally on\n *     category activation\n *   - CRA report: render provenance metadata\n */\nexport interface CategorySchema {\n  readonly id: AdapterCategory;\n  readonly displayName: string;\n  readonly description: string;\n  readonly canonicalTable: string;\n  /**\n   * SYS-3333: the id this category had before it was renamed.\n   *\n   * The transition has to be COMPATIBLE: a manifest that registered yesterday\n   * must register today. So a legacy id is not decoration — the host resolves\n   * it, warns, and proceeds, rather than refusing a manifest at boot for a\n   * name the operator never chose to change.\n   *\n   * A legacy id may never collide with a LIVE id (enforced below). That rule\n   * is why the two bank categories kept their names in this release: reusing\n   * `bank-statement` for the document category would have made a pre-sweep\n   * manifest saying `bank-statement` genuinely ambiguous — the partner feed\n   * before, the document after — with no correct resolution. Renaming them\n   * waits for the deprecation window to close.\n   */\n  readonly legacyId?: string;\n  readonly fields: ReadonlyArray<CanonicalFieldSpec>;\n}\n\n// ── Raw data shape (as it appears in the JSON file) ──────────────────\n\ninterface RawCategoryField {\n  name: string;\n  type: \"number\" | \"boolean\" | \"string\";\n  unit?: string;\n  range?: [number, number];\n  description: string;\n  fact?: string;\n  legacyName?: string;\n  kind?: \"enum\" | \"money\";\n  confidentiality?: \"non-sensitive\";\n}\n\ninterface RawCategory {\n  id: string;\n  legacyId?: string;\n  displayName: string;\n  description: string;\n  canonicalTable: string;\n  fields: RawCategoryField[];\n}\n\ninterface RawCategoryData {\n  schemaVersion: string;\n  categories: RawCategory[];\n}\n\n// ── Registry: load-time validation + indexing ────────────────────────\n\n/*\n * SYS-3347 — the two narrowing points, and why a cast is correct here rather\n * than a smell.\n *\n * `AdapterCategory` and `CanonicalFieldName` are literal unions GENERATED FROM\n * this very JSON file. So inside the loader, a name read out of it is a member\n * of the union by construction — the union cannot disagree with its own\n * source, and the `--check` drift guard is what keeps that true.\n *\n * The parameters stay `string` on purpose. `buildCategoryRegistry` is the\n * extension point for host-side categories, so it must accept names the\n * shipped union has never heard of; it validates them and then narrows. That\n * is exactly the boundary/interior split the union exists to draw, and these\n * two functions are the boundary.\n *\n * Named rather than inlined `as` so the narrowing is greppable: a reviewer can\n * find every place a string becomes vocabulary in one search, which is not\n * true of a bare cast.\n */\nconst asCategoryId = (id: string): AdapterCategoryId => id as AdapterCategoryId;\nconst asFieldName = (name: string): CanonicalFieldNameLiteral =>\n  name as CanonicalFieldNameLiteral;\n\nconst VALID_FIELD_TYPES: ReadonlyArray<CanonicalFieldSpec[\"type\"]> = [\n  \"number\",\n  \"boolean\",\n  \"string\",\n];\n\nconst VALID_FIELD_KINDS: ReadonlyArray<NonNullable<CanonicalFieldSpec[\"kind\"]>> = [\n  \"enum\",\n  \"money\",\n];\n\n/**\n * SYS-3249: the closed set of units a field may declare, and — more to\n * the point — the set a currency can never join.\n *\n * Every member is an INTRINSIC unit of measure: a property of the\n * quantity itself, true wherever it is observed. A currency is not that.\n * It is a property of the OBSERVATION, it varies between two values of\n * the same field, and one source can report several in a single document\n * (an FX transaction on a bank statement, cross-border settlement on a\n * payment network). Declaring `unit: \"MYR\"` on a field said something\n * about the field that was only ever true of Malaysian data, and 143\n * fields said it.\n *\n * Money is expressed as `kind: \"money\"` instead, and the denomination\n * travels with the value on its provenance envelope.\n *\n * The list is closed and validated at load precisely so re-declaring a\n * currency here — or helpfully adding \"VND\" alongside — is a load error\n * rather than something review has to catch. That is the whole control:\n * `unit` is otherwise documentation-only (its sole consumer is the spec\n * builder passing it through), so nothing else would ever notice.\n */\nconst VALID_FIELD_UNITS: ReadonlyArray<string> = [\n  \"ratio\",\n  // SYS-3336: a residency duration is collected as YEARS and MONTHS in two\n  // separate inputs, and form intake has no transform slot to fold them into\n  // one figure — so both have to be expressible. The numeric-unit guard asking\n  // for this is the guard working: a bare number of years beside a number of\n  // months is exactly the ambiguity it exists to refuse.\n  \"years\",\n  \"months\",\n  \"days\",\n  \"hours\",\n  \"count\",\n  \"meters\",\n  \"deg\",\n  \"rating\",\n  \"score\",\n];\n\n/**\n * SYS-3164. One entry, and that is the point — see `confidentiality` on\n * `CanonicalFieldSpec`. \"sensitive\" is unspellable because it is the\n * default; the only declarable value is the opt-out.\n */\n/**\n * SYS-3333: a canonical field name must not encode its denomination.\n * ISO-4217-shaped suffix, matched title-case because that is how these names\n * were formed (`telcoArpuMyr`, `arTotalOutstandingMyr`).\n */\nconst CURRENCY_SUFFIXED = /(Myr|Usd|Eur|Gbp|Sgd|Vnd|Thb|Idr|Php|Jpy|Cny|Aud)$/;\n\n/**\n * SYS-3333: the retired window convention. `T3`/`T12` said the same thing as\n * `3m`/`12m` in a second dialect, and the T-form additionally collides with\n * the legacy flat T-suffix (`revenueT1`), which means a period position, not a\n * window length — two different ideas wearing one spelling.\n */\nconst T_WINDOW_SUFFIXED = /T\\d+$/;\n\nconst VALID_FIELD_CONFIDENTIALITY: ReadonlyArray<\n  NonNullable<CanonicalFieldSpec[\"confidentiality\"]>\n> = [\"non-sensitive\"];\n\n/**\n * The validated, indexed, immutable category registry. Built once at\n * module load from the bundled data file (and rebuildable from any\n * conforming data object in tests via `buildCategoryRegistry`).\n */\n/*\n * SYS-3347 — the lookup maps are keyed by `string`, deliberately.\n *\n * Their whole job is to answer \"is this arbitrary value one of ours?\", so a\n * union key would reject the untrusted input they exist to test —\n * `byId.has(someUserString)` would not compile, which inverts the purpose. The\n * NARROWING happens on the way out: the public accessors return the union\n * after the membership check has proved it.\n */\nexport interface CategoryRegistry {\n  /** All category schemas, in data-file order. */\n  readonly all: ReadonlyArray<CategorySchema>;\n  /** Category ids, in data-file order. */\n  readonly ids: ReadonlyArray<AdapterCategory>;\n  /** id → schema, O(1) lookup. */\n  readonly byId: ReadonlyMap<string, CategorySchema>;\n  /**\n   * canonical field name → owning category id, O(1) reverse lookup.\n   * Only UNIQUELY-declared names appear here — a shared-fact name\n   * (declared by more than one category) is deliberately absent, so\n   * `categoryForField` answers null for it (explicit ambiguity).\n   */\n  readonly fieldToCategory: ReadonlyMap<string, AdapterCategory>;\n  /** canonical field name → fact id, for every field declaring one. */\n  readonly fieldToFact: ReadonlyMap<string, string>;\n  /** fact id → every category attesting it, in data-file order. */\n  readonly factToCategories: ReadonlyMap<string, ReadonlyArray<AdapterCategory>>;\n  /**\n   * SYS-3333: legacy flat name → the canonical name that replaced it.\n   *\n   * One-way and transitional. It exists so code that is handed a FLAT\n   * column name can reach the canonical field's declarations (is it money?\n   * what kind? what fact?) without every such call site growing its own\n   * hardcoded rename table. Empty for a field that was never renamed.\n   */\n  readonly legacyToCanonical: ReadonlyMap<string, CanonicalFieldName>;\n}\n\n/**\n * Validate + index raw category data into an immutable registry.\n *\n * Pure function — exported so the loader can be exercised against\n * fixture data in tests (SYS-2500: prove the registry is genuinely\n * data-driven, not hardcoded). Throws on ANY structural violation so a\n * malformed JSON edit fails loudly at module load rather than producing\n * silent gaps at read time. The invariants enforced here are the ones\n * the old test suite asserted after the fact; making them load-time\n * guarantees is what lets the data file be the single source of truth.\n */\nexport function buildCategoryRegistry(raw: RawCategoryData): CategoryRegistry {\n  if (!raw || typeof raw !== \"object\") {\n    throw new Error(\"adapter category data: expected an object\");\n  }\n  if (typeof raw.schemaVersion !== \"string\" || raw.schemaVersion.length === 0) {\n    throw new Error(\"adapter category data: missing schemaVersion\");\n  }\n  if (!Array.isArray(raw.categories) || raw.categories.length === 0) {\n    throw new Error(\"adapter category data: categories must be a non-empty array\");\n  }\n\n  const byId = new Map<string, CategorySchema>();\n  const fieldToCategory = new Map<string, AdapterCategory>();\n  const fieldToFact = new Map<string, string>();\n  const factToCategories = new Map<string, AdapterCategory[]>();\n  // SYS-3333: legacy flat name -> canonical name. Validated below against\n  // BOTH namespaces: a legacy name may not shadow a live canonical name\n  // (the lookup would be ambiguous), and two fields may not claim the same\n  // legacy name (the lookup would be wrong for one of them).\n  const legacyToCanonical = new Map<string, CanonicalFieldName>();\n  // Every declaration of a field name seen so far — the shared-fact\n  // uniqueness rule needs the full picture, not just the first declarer.\n  // Keyed by `string`: this is a working index built from RAW input, so it\n  // must accept a name the shipped union has never seen — that is precisely\n  // what buildCategoryRegistry exists to validate.\n  const declarations = new Map<\n    string,\n    {\n      fact: string | undefined;\n      kind: RawCategoryField[\"kind\"];\n      // SYS-3350: carried so shared-fact attestations can be checked for\n      // agreement on them, not just on fact/kind/confidentiality.\n      type: RawCategoryField[\"type\"];\n      unit: RawCategoryField[\"unit\"];\n      confidentiality: \"non-sensitive\" | undefined;\n      categories: AdapterCategory[];\n    }\n  >();\n  const tables = new Set<string>();\n  const all: CategorySchema[] = [];\n\n  for (const cat of raw.categories) {\n    const where = `category \"${cat?.id ?? \"<unknown>\"}\"`;\n\n    if (typeof cat.id !== \"string\" || cat.id.length === 0) {\n      throw new Error(\"adapter category data: every category needs a non-empty id\");\n    }\n    if (byId.has(cat.id)) {\n      throw new Error(`adapter category data: duplicate category id \"${cat.id}\"`);\n    }\n    if (typeof cat.displayName !== \"string\" || cat.displayName.length === 0) {\n      throw new Error(`adapter category data: ${where} needs a non-empty displayName`);\n    }\n    if (typeof cat.description !== \"string\" || cat.description.length === 0) {\n      throw new Error(`adapter category data: ${where} needs a non-empty description`);\n    }\n    // Canonical tables live in the host's IHS namespace. Originally every\n    // category stored into a dedicated `ihs_alt_data_*` table; since the\n    // document-extraction categories (SYS-2998), a category may instead be\n    // canonical over a promoted legacy sibling table (`ihsbankstatement`,\n    // `ihsepfstatement`, ...) — so the invariant is the namespace prefix,\n    // not the alt-data naming scheme.\n    //\n    // SYS-3327: the physical schema has ONE camel-cased table, `ihsPayslip`,\n    // and the database runs lower_case_table_names=0, so case is part of the\n    // name. This rule used to be lowercase-only — which meant the payslip\n    // declaration COULD NOT be written correctly and was written wrong, and\n    // its own test restated the wrong literal. The namespace prefix is the\n    // invariant; the case is the schema's to dictate. (SYS-3341 derives the\n    // table from the category id and retires the question.)\n    if (typeof cat.canonicalTable !== \"string\" || !/^ihs[A-Za-z0-9_]*$/.test(cat.canonicalTable)) {\n      throw new Error(\n        `adapter category data: ${where} canonicalTable must be an \"ihs\"-prefixed table identifier (got \"${cat.canonicalTable}\")`,\n      );\n    }\n    // Case-insensitive on purpose: on a lower_case_table_names=1 host two\n    // names differing only by case ARE one table, and on =0 a registry\n    // declaring both would be declaring a trap. Refuse either way.\n    if (tables.has(cat.canonicalTable.toLowerCase())) {\n      throw new Error(\n        `adapter category data: duplicate canonicalTable \"${cat.canonicalTable}\" (${where})`,\n      );\n    }\n    if (!Array.isArray(cat.fields) || cat.fields.length === 0) {\n      throw new Error(`adapter category data: ${where} must declare at least one field`);\n    }\n\n    const fields: CanonicalFieldSpec[] = [];\n    for (const f of cat.fields) {\n      if (typeof f.name !== \"string\" || f.name.length === 0) {\n        throw new Error(`adapter category data: ${where} has a field with no name`);\n      }\n      if (f.fact !== undefined && (typeof f.fact !== \"string\" || f.fact.length === 0)) {\n        throw new Error(\n          `adapter category data: field \"${f.name}\" (${where}) has an invalid fact — expected a non-empty string`,\n        );\n      }\n      if (\n        f.legacyName !== undefined &&\n        (typeof f.legacyName !== \"string\" || f.legacyName.length === 0)\n      ) {\n        throw new Error(\n          `adapter category data: field \"${f.name}\" (${where}) has an invalid legacyName — expected a non-empty string`,\n        );\n      }\n      if (f.legacyName !== undefined && f.legacyName === f.name) {\n        throw new Error(\n          `adapter category data: field \"${f.name}\" (${where}) declares a legacyName identical to its ` +\n            `canonical name — a legacyName records a rename, so an unchanged name must not declare one`,\n        );\n      }\n      // SYS-3333 — the naming conventions, ENFORCED rather than merely applied.\n      //\n      // The sweep that produced this vocabulary found 5 currency-suffixed\n      // names, 15 window-suffixed names in TWO conventions, and ~50 names\n      // repeating their own source. None of that was anyone's decision; it\n      // accumulated because nothing refused it. A one-time cleanup with no\n      // guard is a cleanup that happens again in a year, and this vocabulary\n      // is about to be read by a regulated credit bureau.\n      //\n      // Only mechanically-decidable rules live here. \"A name should not repeat\n      // its source\" needs judgement (`statementDate` in a bank-statement\n      // category is fine) and is asserted in the tests instead — a load-time\n      // throw that misfires is worse than no rule, because the next person\n      // works around it.\n      if (CURRENCY_SUFFIXED.test(f.name)) {\n        throw new Error(\n          `adapter category data: field \"${f.name}\" (${where}) bakes a currency into its name. A ` +\n            `denomination belongs to the OBSERVATION, not the field (SYS-3249) — one source can report ` +\n            `several currencies in one document, so a field-level currency can only ever be right for ` +\n            `one of them. Declare kind: \"money\" and carry the currency on the provenance envelope.`,\n        );\n      }\n      if (T_WINDOW_SUFFIXED.test(f.name)) {\n        throw new Error(\n          `adapter category data: field \"${f.name}\" (${where}) uses the T<n> window convention. The ` +\n            `registry has one convention for a time window and it is the unit-suffixed form — 3m, 12m, ` +\n            `24m, 90d. Two conventions for one idea is how a reader stops trusting either.`,\n        );\n      }\n      // Hoisted ABOVE the shared-fact block deliberately. When an invalid\n      // value arrives on a SECOND declarer, the agreement check would fire\n      // first and report `declared sensitive (default) by a but \"sensitive\"\n      // by b — must agree on confidentiality`, which reads as though\n      // \"sensitive\" were a legal value that merely disagrees. That is the\n      // exact opposite of the rule, and would cost the next reader an hour.\n      // The value check has no dependency on `prior`, so it belongs first.\n      if (f.confidentiality !== undefined && !VALID_FIELD_CONFIDENTIALITY.includes(f.confidentiality)) {\n        throw new Error(\n          `adapter category data: field \"${f.name}\" (${where}) has invalid confidentiality ` +\n            `\"${String(f.confidentiality)}\" — the only declarable value is \"non-sensitive\"; ` +\n            `sensitive is the default and is expressed by omitting the property`,\n        );\n      }\n      // Shared-fact uniqueness rule: a field name may be declared by\n      // more than one category iff EVERY declaration carries the SAME\n      // `fact` id — the declarations are then independent attestations\n      // of one shared real-world fact. A name declared with a fact in\n      // one place and without (or with a different fact) elsewhere is\n      // the SYS-2722 drift pattern and is refused at load time.\n      const prior = declarations.get(f.name);\n      if (prior) {\n        if (prior.categories.includes(asCategoryId(cat.id))) {\n          throw new Error(\n            `adapter category data: ${where} declares field \"${f.name}\" more than once`,\n          );\n        }\n        if (prior.fact === undefined || f.fact === undefined || prior.fact !== f.fact) {\n          const describeFact = (fact: string | undefined): string =>\n            fact === undefined ? \"no fact\" : `fact \"${fact}\"`;\n          throw new Error(\n            `adapter category data: canonical field \"${f.name}\" declared by more than one category ` +\n              `(${prior.categories.join(\" + \")} with ${describeFact(prior.fact)} + ${cat.id} with ` +\n              `${describeFact(f.fact)}) — field names must be globally unique unless every ` +\n              `declaring category attests the same fact`,\n          );\n        }\n        // Same drift class as the fact rule: attestations of one fact\n        // must agree on kind — an enum label in one category and a free\n        // string in another are not comparable values of \"the same\n        // fact\", and the disagreement-comparison feature would be\n        // comparing apples to labels.\n        if (prior.kind !== f.kind) {\n          const describeKind = (kind: string | undefined): string =>\n            kind === undefined ? \"no kind\" : `kind \"${kind}\"`;\n          throw new Error(\n            `adapter category data: canonical field \"${f.name}\" declared with ${describeKind(prior.kind)} ` +\n              `by ${prior.categories.join(\" + \")} but ${describeKind(f.kind)} by ${cat.id} — ` +\n              `shared-fact attestations must agree on kind`,\n          );\n        }\n        // SYS-3350: `type` and `unit` were the last unpoliced properties of a\n        // shared fact, and `type` is the one the `kind` clause above only\n        // APPEARS to cover.\n        //\n        // kind implies type for money and enum, so that subset was already\n        // caught. The six kind-less shared facts — personName, personIdNumber,\n        // personAddress, companyName, companyRegNo, companyIncorporationDate —\n        // had nothing checking them at all. A review demonstrated it by\n        // mutation: setting epf-statement's personName to `type: \"number\"`\n        // LOADED CLEAN, after which allCategories() served one fact as a string\n        // from three categories and a number from a fourth.\n        //\n        // Cross-source comparability is the entire reason a fact id exists. Two\n        // attestations that cannot be compared as the same primitive are not\n        // attestations of the same fact.\n        if (prior.type !== f.type) {\n          throw new Error(\n            `adapter category data: canonical field \"${f.name}\" declared type \"${prior.type}\" ` +\n              `by ${prior.categories.join(\" + \")} but \"${f.type}\" by ${cat.id} — ` +\n              `shared-fact attestations must agree on type`,\n          );\n        }\n        if (prior.unit !== f.unit) {\n          const describeUnit = (u: string | undefined): string =>\n            u === undefined ? \"no unit\" : `unit \"${u}\"`;\n          throw new Error(\n            `adapter category data: canonical field \"${f.name}\" declared with ` +\n              `${describeUnit(prior.unit)} by ${prior.categories.join(\" + \")} but ` +\n              `${describeUnit(f.unit)} by ${cat.id} — shared-fact attestations must agree on ` +\n              `unit, or one number means two different quantities`,\n          );\n        }\n        // SYS-3164: same drift class again. One real-world fact cannot be\n        // sensitive when a document attests it and non-sensitive when a\n        // form does — storage would then hold the two attestations of one\n        // fact under different protection, and which one you got would\n        // depend on which source happened to write last.\n        if (prior.confidentiality !== f.confidentiality) {\n          const describeConf = (c: string | undefined): string =>\n            c === undefined ? \"sensitive (default)\" : `\"${c}\"`;\n          throw new Error(\n            `adapter category data: canonical field \"${f.name}\" declared ${describeConf(prior.confidentiality)} ` +\n              `by ${prior.categories.join(\" + \")} but ${describeConf(f.confidentiality)} by ${cat.id} — ` +\n              `shared-fact attestations must agree on confidentiality`,\n          );\n        }\n      }\n      if (f.fact !== undefined) {\n        // A fact id is bound to exactly one field name registry-wide —\n        // two different names attesting \"the same fact\" is drift by\n        // another name (a fact must be comparable across its attesters\n        // via one canonical field name).\n        for (const [otherName, otherFact] of fieldToFact) {\n          if (otherFact === f.fact && otherName !== f.name) {\n            throw new Error(\n              `adapter category data: fact \"${f.fact}\" is carried by two different field names ` +\n                `(\"${otherName}\" + \"${f.name}\") — a fact id must map to exactly one canonical field name`,\n            );\n          }\n        }\n      }\n      if (!VALID_FIELD_TYPES.includes(f.type)) {\n        throw new Error(\n          `adapter category data: field \"${f.name}\" (${where}) has invalid type \"${f.type}\"`,\n        );\n      }\n      // SYS-3249: `unit` is checked for EVERY field, kind or not. It was\n      // free-form until now and read by nothing but the spec builder, so\n      // an unusable value could sit in the contract indefinitely without\n      // anything noticing — which is exactly what 143 fields declaring\n      // `unit: \"MYR\"` did. Closing the set is the control.\n      if (f.unit !== undefined && !VALID_FIELD_UNITS.includes(f.unit)) {\n        const looksLikeCurrency = /^[A-Z]{3}$/.test(f.unit);\n        throw new Error(\n          `adapter category data: field \"${f.name}\" (${where}) has invalid unit \"${String(f.unit)}\" — ` +\n            (looksLikeCurrency\n              ? `a currency is not a unit of measure. It is a property of the OBSERVATION, not of the field: ` +\n                `one source can report several currencies in one document, so no field-level currency can be ` +\n                `right for more than one of them. Declare kind \"money\" instead and let the denomination travel ` +\n                `with the value on its provenance envelope.`\n              : `expected one of ${VALID_FIELD_UNITS.join(\", \")}`),\n        );\n      }\n      if (f.kind !== undefined) {\n        if (!VALID_FIELD_KINDS.includes(f.kind)) {\n          throw new Error(\n            `adapter category data: field \"${f.name}\" (${where}) has invalid kind \"${String(f.kind)}\"`,\n          );\n        }\n        // Per-kind constraints. Split by kind rather than sharing a\n        // block: the two kinds refine `type` in opposite directions\n        // (enum narrows a string, money annotates a number), so a shared\n        // check would have to be written as a disjunction that is true\n        // for neither reason.\n        if (f.kind === \"enum\") {\n          if (f.type !== \"string\") {\n            throw new Error(\n              `adapter category data: field \"${f.name}\" (${where}) is kind \"enum\" but type \"${f.type}\" — enum labels are string-normalized, so an enum field must be type \"string\"`,\n            );\n          }\n          if (f.range !== undefined) {\n            throw new Error(\n              `adapter category data: field \"${f.name}\" (${where}) is kind \"enum\" but declares a range — enum labels are unordered; ordering belongs to the consumer, never the data contract`,\n            );\n          }\n        }\n        if (f.kind === \"money\") {\n          if (f.type !== \"number\") {\n            throw new Error(\n              `adapter category data: field \"${f.name}\" (${where}) is kind \"money\" but type \"${f.type}\" — a monetary amount's primitive is a number; the denomination is carried separately, on the value's provenance`,\n            );\n          }\n          if (f.unit !== undefined) {\n            throw new Error(\n              `adapter category data: field \"${f.name}\" (${where}) is kind \"money\" and declares unit \"${String(f.unit)}\" — money has no intrinsic unit. The denomination belongs to the observation and travels on its provenance envelope`,\n            );\n          }\n          if (f.range !== undefined) {\n            throw new Error(\n              `adapter category data: field \"${f.name}\" (${where}) is kind \"money\" and declares a range — a numeric bound on money is denominated by definition, so it can only ever be correct in one currency`,\n            );\n          }\n        }\n      }\n      if (typeof f.description !== \"string\" || f.description.length === 0) {\n        throw new Error(\n          `adapter category data: field \"${f.name}\" (${where}) needs a non-empty description`,\n        );\n      }\n      if (f.range !== undefined) {\n        // Number.isFinite rejects non-numbers, NaN, and ±Infinity — a\n        // typeof check alone would let [NaN, NaN] through (typeof NaN ===\n        // \"number\" and NaN > NaN is false), silently corrupting any\n        // downstream clamp that reads the range.\n        if (\n          !Array.isArray(f.range) ||\n          f.range.length !== 2 ||\n          !Number.isFinite(f.range[0]) ||\n          !Number.isFinite(f.range[1]) ||\n          f.range[0] > f.range[1]\n        ) {\n          throw new Error(\n            `adapter category data: field \"${f.name}\" (${where}) has an invalid range — expected [lo, hi] with finite lo <= hi`,\n          );\n        }\n      }\n\n      const spec: CanonicalFieldSpec = Object.freeze({\n        name: asFieldName(f.name),\n        type: f.type,\n        ...(f.unit !== undefined ? { unit: f.unit } : {}),\n        ...(f.range !== undefined ? { range: Object.freeze([f.range[0], f.range[1]]) as readonly [number, number] } : {}),\n        description: f.description,\n        ...(f.fact !== undefined ? { fact: f.fact } : {}),\n        ...(f.legacyName !== undefined ? { legacyName: f.legacyName } : {}),\n        ...(f.kind !== undefined ? { kind: f.kind } : {}),\n        // SYS-3171: resolved, never conditional — absence in the data file\n        // means sensitive, and the built spec says so out loud.\n        confidentiality: f.confidentiality ?? \"sensitive\",\n      });\n      fields.push(spec);\n      if (prior) {\n        prior.categories.push(asCategoryId(cat.id));\n        // The name is now shared — drop it from the unique-owner index\n        // so categoryForField answers null (explicit ambiguity) rather\n        // than silently privileging the first declarer.\n        fieldToCategory.delete(f.name);\n      } else {\n        declarations.set(f.name, {\n          fact: f.fact,\n          kind: f.kind,\n          type: f.type,\n          unit: f.unit,\n          confidentiality: f.confidentiality,\n          categories: [asCategoryId(cat.id)],\n        });\n        fieldToCategory.set(f.name, asCategoryId(cat.id));\n      }\n      if (f.legacyName !== undefined) {\n        const claimed = legacyToCanonical.get(f.legacyName);\n        if (claimed !== undefined && claimed !== f.name) {\n          throw new Error(\n            `adapter category data: legacyName \"${f.legacyName}\" is claimed by two different canonical ` +\n              `fields (\"${claimed}\" + \"${f.name}\") — a legacy name must resolve to exactly one canonical field`,\n          );\n        }\n        legacyToCanonical.set(f.legacyName, asFieldName(f.name));\n      }\n      if (f.fact !== undefined) {\n        fieldToFact.set(f.name, f.fact);\n        const attesters = factToCategories.get(f.fact);\n        if (attesters) {\n          attesters.push(asCategoryId(cat.id));\n        } else {\n          factToCategories.set(f.fact, [asCategoryId(cat.id)]);\n        }\n      }\n    }\n\n    const schema: CategorySchema = Object.freeze({\n      id: asCategoryId(cat.id),\n      displayName: cat.displayName,\n      description: cat.description,\n      canonicalTable: cat.canonicalTable,\n      ...(cat.legacyId !== undefined ? { legacyId: cat.legacyId } : {}),\n      fields: Object.freeze(fields) as ReadonlyArray<CanonicalFieldSpec>,\n    });\n    byId.set(cat.id, schema);\n    tables.add(cat.canonicalTable.toLowerCase());\n    all.push(schema);\n  }\n\n  // SYS-3333 — a legacy category id must resolve to exactly one live category,\n  // and must not shadow one. Checked before the field-level pass so a\n  // structurally impossible alias fails on its own terms.\n  for (const cat of raw.categories) {\n    if (cat.legacyId === undefined) continue;\n    if (typeof cat.legacyId !== \"string\" || cat.legacyId.length === 0) {\n      throw new Error(`adapter category data: category \"${cat.id}\" has an invalid legacyId`);\n    }\n    if (cat.legacyId === cat.id) {\n      throw new Error(\n        `adapter category data: category \"${cat.id}\" declares a legacyId identical to its id — ` +\n          `a legacyId records a rename, so an unchanged id must not declare one`,\n      );\n    }\n    if (raw.categories.some((o) => o.id === cat.legacyId)) {\n      throw new Error(\n        `adapter category data: legacyId \"${cat.legacyId}\" (on \"${cat.id}\") is also a LIVE category ` +\n          `id — an alias that collides with a live id cannot be resolved, because a manifest naming ` +\n          `it could mean either category`,\n      );\n    }\n    const twin = raw.categories.find((o) => o !== cat && o.legacyId === cat.legacyId);\n    if (twin) {\n      throw new Error(\n        `adapter category data: legacyId \"${cat.legacyId}\" is claimed by two categories ` +\n          `(\"${twin.id}\" + \"${cat.id}\")`,\n      );\n    }\n  }\n\n  // SYS-3333 — deferred to here on purpose. A legacy alias may legally be\n  // declared BEFORE the canonical field that would shadow it appears later in\n  // the file, so the check is only sound once every category is indexed.\n  for (const [legacy, canonical] of legacyToCanonical) {\n    if (declarations.has(legacy)) {\n      throw new Error(\n        `adapter category data: legacyName \"${legacy}\" (on \"${canonical}\") is also a LIVE canonical ` +\n          `field name — a legacy alias must not shadow a name still in the vocabulary, or a lookup ` +\n          `cannot say which one it meant`,\n      );\n    }\n  }\n\n  return Object.freeze({\n    all: Object.freeze(all) as ReadonlyArray<CategorySchema>,\n    ids: Object.freeze(all.map((c) => c.id)) as ReadonlyArray<AdapterCategory>,\n    byId,\n    fieldToCategory,\n    fieldToFact,\n    factToCategories: new Map(\n      [...factToCategories].map(([fact, cats]) => [\n        fact,\n        Object.freeze(cats) as ReadonlyArray<AdapterCategory>,\n      ]),\n    ),\n    legacyToCanonical,\n  });\n}\n\n/**\n * The package's category registry — built + validated once at module\n * load from `data/adapter-categories.json`. A malformed data file\n * throws here, failing the import (and the build/test) loudly.\n */\nconst registry = buildCategoryRegistry(categoriesData as RawCategoryData);\n\n/**\n * Every category id declared by this version of finsys-core, in\n * data-file order. The runtime equivalent of the old hardcoded union —\n * derived from the single source of truth rather than maintained by\n * hand. Treat order as unstable across versions.\n */\nexport const ADAPTER_CATEGORY_IDS: ReadonlyArray<AdapterCategory> = registry.ids;\n\n/**\n * Look up a category schema by id. Throws if the id is unknown.\n */\nexport function categorySchemaOf(id: AdapterCategory): CategorySchema {\n  const found = registry.byId.get(id);\n  if (!found) {\n    throw new Error(\n      `Unknown adapter category: ${id}. Available: ${registry.ids.join(\", \")}`,\n    );\n  }\n  return found;\n}\n\n/**\n * The canonical field names a given category produces. Convenience\n * for callers that don't need the full schema — common case in the\n * eval engine (\"does this policy reference any fields from a category\n * that isn't loaded?\").\n */\nexport function categoryFieldsOf(id: AdapterCategory): ReadonlyArray<CanonicalFieldName> {\n  return categorySchemaOf(id).fields.map((f) => f.name);\n}\n\n/**\n * SYS-3164: is this field of this category sensitive?\n *\n * Answers TRUE for anything not explicitly declared `\"non-sensitive\"` —\n * including a field name the category does not declare at all. That last\n * part is deliberate: a caller asking about an unknown field is either\n * mid-rename or wrong, and the safe answer to \"should I protect this?\"\n * when you do not recognize it is yes. `categorySchemaOf` still throws\n * for an unknown CATEGORY, because that is a wiring error rather than a\n * data question.\n */\nexport function isFieldSensitive(id: AdapterCategory, field: CanonicalFieldName): boolean {\n  const spec = categorySchemaOf(id).fields.find((f) => f.name === field);\n  return spec?.confidentiality !== \"non-sensitive\";\n}\n\n/**\n * SYS-3164: every field of this category that is sensitive — i.e. every\n * field that did not opt out. The complement of the declared\n * `\"non-sensitive\"` set, so a newly added field appears here until\n * someone classifies it.\n */\nexport function sensitiveFieldsOf(id: AdapterCategory): ReadonlyArray<CanonicalFieldName> {\n  return categorySchemaOf(id)\n    .fields.filter((f) => f.confidentiality !== \"non-sensitive\")\n    .map((f) => f.name);\n}\n\n/**\n * Every category currently declared. Order is data-file order; treat\n * as unstable across versions.\n */\nexport function allCategories(): ReadonlyArray<CategorySchema> {\n  return registry.all;\n}\n\n/**\n * Reverse lookup: which category declares a given canonical field?\n * Returns null if the field name isn't declared by any category in\n * this version of finsys-core — AND for shared-fact names (declared by\n * more than one category), where \"the\" category is genuinely ambiguous.\n * The null is deliberate: a caller holding a shared-fact name must\n * decide per-attestation, via `categoriesAttestingFact(factOf(name))`,\n * rather than being handed one arbitrary declarer. Useful when the\n * host app is reading canonical field values back from storage + wants\n * to identify the producing category for rendering. O(1).\n */\nexport function categoryForField(field: CanonicalFieldName): AdapterCategory | null {\n  return registry.fieldToCategory.get(field) ?? null;\n}\n\n/**\n * The fact id a canonical field attests, or null when the field\n * declares no fact (or isn't declared at all). By convention the fact\n * id equals the field name, but callers must not assume it — read it\n * from here. O(1).\n */\nexport function factOf(field: CanonicalFieldName): string | null {\n  return registry.fieldToFact.get(field) ?? null;\n}\n\n/**\n * SYS-3333: resolve a category id from EITHER vocabulary to the canonical one.\n *\n * Returns `id` unchanged when it is already a live category id, the canonical\n * id when `id` is a recorded `legacyId`, and null when it is neither. The\n * identity case is deliberate: a caller bridging the two vocabularies is handed\n * a mix, and forcing each one to try live-first-then-alias is how a call site\n * ends up with its own private rename table.\n *\n * The main callers are boundaries where a FOREIGN id arrives and its vintage is\n * not ours to choose — an adapter manifest submitted by a partner, an adapter\n * registry read back from another service.\n *\n * TRANSITIONAL, and it goes when the legacy ids do. Use `isLegacyCategoryId` to\n * decide whether the resolution deserves a deprecation warning.\n */\nexport function resolveCanonicalCategoryId(id: string): AdapterCategory | null {\n  if (registry.byId.has(id)) return asCategoryId(id);\n  for (const c of registry.all) {\n    if (c.legacyId === id) return c.id;\n  }\n  return null;\n}\n\n/**\n * SYS-3333: true when `id` is a RETIRED category id rather than a live one.\n *\n * Callers use this to decide whether to emit a deprecation warning — the\n * resolution itself is the same either way, and a caller that cannot tell the\n * two apart either warns on every call or on none.\n */\nexport function isLegacyCategoryId(id: string): boolean {\n  return !registry.byId.has(id) && registry.all.some((c) => c.legacyId === id);\n}\n\n/**\n * SYS-3333: resolve a field name from EITHER vocabulary to the canonical one.\n *\n * Returns `name` unchanged when it is already canonical, the canonical name\n * when `name` is a recorded `legacyName`, and null when it is neither — so a\n * caller can tell a rename it must honour from a typo it must refuse.\n *\n * TRANSITIONAL. It exists because artifacts written under the old vocabulary\n * are still in circulation — partner manifests, pushed assertions, eval models\n * held by lenders — and none of them move on our schedule. Do not build new\n * addressing on it: a legacy name carries no fact, is not `produce`-able by an\n * adapter, and is not addressable in an eval model.\n */\nexport function resolveCanonicalFieldName(name: string): CanonicalFieldName | null {\n  if (registry.fieldToCategory.has(name) || registry.fieldToFact.has(name)) return asFieldName(name);\n  const viaLegacy = registry.legacyToCanonical.get(name);\n  if (viaLegacy !== undefined) return viaLegacy;\n  // A name can be canonical, shared-fact, AND absent from both indexes only\n  // if it is uniquely declared with no fact — fieldToCategory covers that —\n  // so reaching here means genuinely unknown.\n  return null;\n}\n\n/**\n * Every category attesting a given shared fact, in data-file order.\n * Empty for an unknown fact id. This is the lookup the disagreement-\n * comparison feature keys on: each attesting category's value for the\n * fact's field is an independent observation of the same real-world\n * fact, so cross-category mismatches are surfaceable.\n */\nexport function categoriesAttestingFact(factId: string): ReadonlyArray<AdapterCategory> {\n  return registry.factToCategories.get(factId) ?? [];\n}\n\n/**\n * Runtime membership check — is `id` a category declared by this\n * version of finsys-core? Use this at trust boundaries (parsing a\n * manifest, validating an API parameter) now that `AdapterCategory` is\n * an open `string` and the compiler can no longer reject unknown ids.\n */\nexport function isAdapterCategory(id: string): boolean {\n  return registry.byId.has(id);\n}\n\n/**\n * Assert membership: returns `id` if it names a declared category,\n * throws otherwise. Note this is a RUNTIME guard only — `AdapterCategory`\n * is an open `string`, so there is no type-level narrowing to apply.\n * The companion to `isAdapterCategory` for call sites that want a hard\n * failure (e.g. the host rejecting a manifest whose category isn't in\n * this finsys-core version's catalogue).\n */\nexport function assertAdapterCategory(id: string): AdapterCategory {\n  if (!registry.byId.has(id)) {\n    throw new Error(\n      `Unknown adapter category: ${id}. Available: ${registry.ids.join(\", \")}`,\n    );\n  }\n  return asCategoryId(id);\n}\n","{\n  \"entries\": {\n    \"accountFlags24m\": {\n      \"address\": {\n        \"category\": \"social-media\",\n        \"field\": \"accountFlags24m\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"accountHolderNameT1\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"personName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"accountHolderNameT2\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"personName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"accountHolderNameT3\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"personName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"accountHolderNameT4\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"personName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"accountHolderNameT5\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"personName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"accountHolderNameT6\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"personName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"accountNumberT1\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"accountNumber\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"accountNumberT2\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"accountNumber\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"accountNumberT3\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"accountNumber\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"accountNumberT4\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"accountNumber\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"accountNumberT5\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"accountNumber\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"accountNumberT6\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"accountNumber\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"accountTenureMonths\": {\n      \"address\": {\n        \"category\": \"social-media\",\n        \"field\": \"accountTenureMonths\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"accountingRevenue12m\": {\n      \"address\": {\n        \"category\": \"trade-credit\",\n        \"field\": \"accountingRevenue12m\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"activeTenureMonths\": {\n      \"address\": {\n        \"category\": \"payment-network\",\n        \"field\": \"activeTenureMonths\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"addressLine1\": {\n      \"address\": {\n        \"category\": \"applicant-address\",\n        \"field\": \"addressLine1\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"addressLine2\": {\n      \"address\": {\n        \"category\": \"applicant-address\",\n        \"field\": \"addressLine2\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"addressLine3\": {\n      \"address\": {\n        \"category\": \"applicant-address\",\n        \"field\": \"addressLine3\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"addressType\": {\n      \"disposition\": \"retired\",\n      \"note\": \"superseded BY THE INSTANCE KEY, not dropped \\u2014 an applicant-address row is already keyed by which address it is. Collected by no live form; 0 of 8,475 rows populated.\",\n      \"via\": \"hand-authored\"\n    },\n    \"age\": {\n      \"address\": {\n        \"category\": \"applicant-demographics\",\n        \"field\": \"statedAge\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"apDaysPayableOutstanding\": {\n      \"address\": {\n        \"category\": \"trade-credit\",\n        \"field\": \"apDaysPayableOutstanding\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"arCurrentRatio\": {\n      \"address\": {\n        \"category\": \"trade-credit\",\n        \"field\": \"arCurrentRatio\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"arDaysSalesOutstanding\": {\n      \"address\": {\n        \"category\": \"trade-credit\",\n        \"field\": \"arDaysSalesOutstanding\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"arOverdue90PlusRatio\": {\n      \"address\": {\n        \"category\": \"trade-credit\",\n        \"field\": \"arOverdue90PlusRatio\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"arTotalOutstanding\": {\n      \"address\": {\n        \"category\": \"trade-credit\",\n        \"field\": \"arTotalOutstanding\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"arpu\": {\n      \"address\": {\n        \"category\": \"telco-carrier\",\n        \"field\": \"arpu\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"arpuStability12m\": {\n      \"address\": {\n        \"category\": \"payment-network\",\n        \"field\": \"arpuStability12m\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"assignedFromUserId\": {\n      \"disposition\": \"withheld\",\n      \"reason\": \"NOT served by GET /lender/applications/:ihsId, deliberately: applicationRecordService removed it in review before publication, because publication is what makes an API permanent. v1 still serves it. There is no v2 destination \\u2014 the honest answer to \\\"where do I get this\\\" is \\\"nowhere, by design\\\", which `relocated` obscured.\",\n      \"via\": \"column-audit\"\n    },\n    \"assignedToUserId\": {\n      \"disposition\": \"withheld\",\n      \"reason\": \"NOT served by GET /lender/applications/:ihsId, deliberately: applicationRecordService removed it in review before publication, because publication is what makes an API permanent. v1 still serves it. There is no v2 destination \\u2014 the honest answer to \\\"where do I get this\\\" is \\\"nowhere, by design\\\", which `relocated` obscured.\",\n      \"via\": \"column-audit\"\n    },\n    \"avgMaximumDemand\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"bankBalanceT1\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"closingBalance\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"bankBalanceT2\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"closingBalance\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"bankBalanceT3\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"closingBalance\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"bankBalanceT4\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"closingBalance\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"bankBalanceT5\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"closingBalance\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"bankBalanceT6\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"closingBalance\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"bankNameT1\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"issuingBankName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"bankNameT2\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"issuingBankName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"bankNameT3\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"issuingBankName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"bankNameT4\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"issuingBankName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"bankNameT5\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"issuingBankName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"bankNameT6\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"issuingBankName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"bankStatementInstances\": {\n      \"disposition\": \"structural\",\n      \"note\": \"v2 exposes these as finxtract-bank-statement instances\"\n    },\n    \"bankStatementOrSavingPassbook\": {\n      \"address\": {\n        \"category\": \"document-intake\",\n        \"field\": \"pathInDms\",\n        \"instanceKeyPrefix\": \"bankStatementOrSavingPassbook\"\n      },\n      \"disposition\": \"mapped\",\n      \"note\": \"SHAPE CHANGE, not a rename. The v1 column held a JSON array of paths; document-intake keys one instance per file as <docType>#<sha256>, so this column becomes N instances.\",\n      \"via\": \"hand-authored\"\n    },\n    \"bankStatements\": {\n      \"address\": {\n        \"category\": \"document-intake\",\n        \"field\": \"pathInDms\",\n        \"instanceKeyPrefix\": \"bankStatements\"\n      },\n      \"disposition\": \"mapped\",\n      \"note\": \"SHAPE CHANGE, not a rename. The v1 column held a JSON array of paths; document-intake keys one instance per file as <docType>#<sha256>, so this column becomes N instances.\",\n      \"via\": \"hand-authored\"\n    },\n    \"bankType\": {\n      \"disposition\": \"retired\",\n      \"note\": \"varchar(20), and 0 of 8,475 rows. Long mistaken for a document-pointer column (the SYS-2499 audit files it under \\\"document file path\\\"), but it cannot be one: the 16 real pointer columns hold [{\\\"month\\\":1,\\\"path\\\":\\\"https://...\\\"}] JSON and are text/varchar(1000+). appHelper.ts's bankTypeList is a lookup table, not a writer.\",\n      \"via\": \"hand-authored\"\n    },\n    \"bdmMoreThan2500kg\": {\n      \"address\": {\n        \"category\": \"applicant-collateral\",\n        \"field\": \"vehicleLadenWeightOver2500kg\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"buildingType\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"businessCommencementDate\": {\n      \"address\": {\n        \"category\": \"company-profile\",\n        \"field\": \"businessCommencementDate\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"businessNature\": {\n      \"address\": {\n        \"category\": \"company-profile\",\n        \"field\": \"businessNature\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"businessOrigin\": {\n      \"address\": {\n        \"category\": \"company-profile\",\n        \"field\": \"businessOrigin\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"businessSector\": {\n      \"address\": {\n        \"category\": \"applicant-employment\",\n        \"field\": \"businessSector\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"capitalReservesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"capitalReserves\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"capitalReservesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"capitalReserves\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"capitalReservesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"capitalReserves\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"cashConversionCycleDays\": {\n      \"address\": {\n        \"category\": \"trade-credit\",\n        \"field\": \"cashConversionCycleDays\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"chassisNo\": {\n      \"address\": {\n        \"category\": \"applicant-collateral\",\n        \"field\": \"vehicleChassisNo\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"city\": {\n      \"disposition\": \"retired\",\n      \"reason\": \"the bare key is unused, but the DATA is live: WooCommerce collects it at checkout and submits it as permanentcity. Retired key is not retired data.\",\n      \"via\": \"consumer-sweep\"\n    },\n    \"clientUserId\": {\n      \"disposition\": \"relocated\",\n      \"reason\": \"SURFACE: GET /lender/applications/:ihsId, as customerUserId (PARTY_FIELDS). NOT retired: FinHub names it at Show.tsx:2039 as the rollout fallback (customerUserId ?? clientUserId) building the Customer Profile link. Dropping the finsys-api shim and leaving that fallback silently removes the button \\u2014 the two changes are coupled.\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"consumer-sweep\"\n    },\n    \"companyBackground\": {\n      \"disposition\": \"vocabulary-gap\",\n      \"note\": \"subject-company-form-v1 names it as one of three columns \\\"collected by nothing at all\\\", and DELIBERATELY does not declare it \\u2014 mapping it would mint an applicant attestation for a value no applicant gave. 0 of 8,475 rows; the only reference in six repos is a lead-gen test submit script. SITS EXACTLY WHERE noOfEmployees DID, which Kain kept as an SME signal, so this is a want-it-or-not call rather than an evidence question.\",\n      \"via\": \"hand-authored\"\n    },\n    \"companyEntityType\": {\n      \"address\": {\n        \"category\": \"subject-company\",\n        \"field\": \"entityTypeCode\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"companyLastOldName\": {\n      \"address\": {\n        \"category\": \"company-profile\",\n        \"field\": \"companyLastOldName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"companyName\": {\n      \"address\": {\n        \"category\": \"company-registration\",\n        \"field\": \"companyName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"companyNameDateOfChange\": {\n      \"address\": {\n        \"category\": \"company-profile\",\n        \"field\": \"companyNameDateOfChange\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"companyRegNo\": {\n      \"address\": {\n        \"category\": \"company-registration\",\n        \"field\": \"companyRegNo\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"companySize\": {\n      \"address\": {\n        \"category\": \"subject-company\",\n        \"field\": \"companySizeCode\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"companyStatus\": {\n      \"address\": {\n        \"category\": \"company-profile\",\n        \"field\": \"companyStatus\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"companyWebsite\": {\n      \"disposition\": \"retired\",\n      \"reason\": \"no consumer in six repos; absent from the core catalog entirely. The only hits are Mudah's DEALER account profile, a different context.\",\n      \"via\": \"consumer-sweep\"\n    },\n    \"computationMode\": {\n      \"address\": {\n        \"category\": \"applicant-income\",\n        \"field\": \"computationMode\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"consentCrossSelling\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"the consent engine\",\n      \"via\": \"column-audit\"\n    },\n    \"consentForm\": {\n      \"address\": {\n        \"category\": \"document-intake\",\n        \"field\": \"pathInDms\",\n        \"instanceKeyPrefix\": \"consentForm\"\n      },\n      \"disposition\": \"mapped\",\n      \"note\": \"SHAPE CHANGE, not a rename. The v1 column held a JSON array of paths; document-intake keys one instance per file as <docType>#<sha256>, so this column becomes N instances.\",\n      \"via\": \"hand-authored\"\n    },\n    \"consentObtainInfoFromCtos\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"the consent engine\",\n      \"via\": \"column-audit\"\n    },\n    \"consents\": {\n      \"disposition\": \"relocated\",\n      \"note\": \"SURFACE: GET /lender/applications/:ihsId. NOT the flat booleans \\u2014 v1 emits the raw consent EVENT ROWS (id, consentDefinitionId, consentDefinitionVersionId, ipAddress, method, bindingMessage, createdAt); the application record carries ConsentReference[] pointing into the consent engine instead, because copying versioned, snapshotted events into a second envelope creates a source of truth that drifts. A SHAPE CHANGE, not a move: a consumer reading consent state must follow the reference.\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"hand-authored\"\n    },\n    \"contactPersonDateOfBirth\": {\n      \"address\": {\n        \"category\": \"related-person\",\n        \"field\": \"relatedPersonDateOfBirth\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"contactPersonEmail\": {\n      \"address\": {\n        \"category\": \"related-person\",\n        \"field\": \"relatedPersonEmail\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"contactPersonIdNo\": {\n      \"address\": {\n        \"category\": \"related-person\",\n        \"field\": \"relatedPersonIdNumber\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"contactPersonIdType\": {\n      \"address\": {\n        \"category\": \"related-person\",\n        \"field\": \"relatedPersonIdType\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"contactPersonName\": {\n      \"address\": {\n        \"category\": \"related-person\",\n        \"field\": \"relatedPersonName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"contactPersonPhoneNo\": {\n      \"address\": {\n        \"category\": \"related-person\",\n        \"field\": \"relatedPersonPhone\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"contactPersonPhoneNoAreaCode\": {\n      \"address\": {\n        \"category\": \"related-person\",\n        \"field\": \"relatedPersonPhoneAreaCode\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"contactPersonPosition\": {\n      \"address\": {\n        \"category\": \"related-person\",\n        \"field\": \"relatedPersonRole\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"coreIncomeDoc\": {\n      \"address\": {\n        \"category\": \"document-intake\",\n        \"field\": \"pathInDms\",\n        \"instanceKeyPrefix\": \"coreIncomeDoc\"\n      },\n      \"disposition\": \"mapped\",\n      \"note\": \"SHAPE CHANGE, not a rename. The v1 column held a JSON array of paths; document-intake keys one instance per file as <docType>#<sha256>, so this column becomes N instances.\",\n      \"via\": \"hand-authored\"\n    },\n    \"costOfGoodsSoldT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"costOfGoodsSold\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"costOfGoodsSoldT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"costOfGoodsSold\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"costOfGoodsSoldT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"costOfGoodsSold\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"country\": {\n      \"disposition\": \"retired\",\n      \"note\": \"collected by no live form and 0 of 8,475 rows populated. applicant-address declares addressCountry for the day a form asks; the prefixed variants (permanentcity, permanentpostcode) are what real submissions carry.\",\n      \"via\": \"hand-authored\"\n    },\n    \"countryOfPermanentResident\": {\n      \"disposition\": \"retired\",\n      \"reason\": \"Mudah collects it and forwards it as nationality; the bare key is not what reaches finsys.\",\n      \"via\": \"consumer-sweep\"\n    },\n    \"createdAt\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"createdBy\": {\n      \"disposition\": \"withheld\",\n      \"reason\": \"NOT served by GET /lender/applications/:ihsId, deliberately: applicationRecordService removed it in review before publication, because publication is what makes an API permanent. v1 still serves it. There is no v2 destination \\u2014 the honest answer to \\\"where do I get this\\\" is \\\"nowhere, by design\\\", which `relocated` obscured.\",\n      \"via\": \"column-audit\"\n    },\n    \"createdByEmpCompanyID\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"creditCardMonthlyInstallment\": {\n      \"address\": {\n        \"category\": \"applicant-obligations\",\n        \"field\": \"obligationMonthlyInstallment\",\n        \"instanceKey\": \"creditCard\"\n      },\n      \"disposition\": \"mapped-pending-build\",\n      \"note\": \"CCRIS-sourced, named in the CitaGlobal Angkasa spec and feeding DSR/NDI. WooCommerce submits it today from installs we cannot update. The destination category has NO TABLE \\u2014 this is an address, not a live one. Multi-attestor: the same obligation may arrive from CTOS, Experian, manual entry or FHD.\",\n      \"via\": \"hand-authored\"\n    },\n    \"ctRatio\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"currentAssetAmountDueFromAssociatedCompaniesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetAmountDueFromAssociatedCompanies\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetAmountDueFromAssociatedCompaniesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetAmountDueFromAssociatedCompanies\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetAmountDueFromAssociatedCompaniesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetAmountDueFromAssociatedCompanies\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetAmountDueFromCustomerT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetAmountDueFromCustomer\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetAmountDueFromCustomerT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetAmountDueFromCustomer\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetAmountDueFromCustomerT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetAmountDueFromCustomer\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetAmountDueFromDirectorT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetAmountDueFromDirector\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetAmountDueFromDirectorT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetAmountDueFromDirector\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetAmountDueFromDirectorT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetAmountDueFromDirector\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetAmountDueFromHoldingCompanyT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetAmountDueFromHoldingCompany\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetAmountDueFromHoldingCompanyT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetAmountDueFromHoldingCompany\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetAmountDueFromHoldingCompanyT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetAmountDueFromHoldingCompany\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetAmountDueFromSubsidiaryCompaniesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetAmountDueFromSubsidiaryCompanies\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetAmountDueFromSubsidiaryCompaniesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetAmountDueFromSubsidiaryCompanies\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetAmountDueFromSubsidiaryCompaniesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetAmountDueFromSubsidiaryCompanies\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetAmountOwingByShareholdersT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetAmountOwingByShareholders\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetAmountOwingByShareholdersT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetAmountOwingByShareholders\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetAmountOwingByShareholdersT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetAmountOwingByShareholders\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetCashAndBankBalancesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetCashAndBankBalances\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetCashAndBankBalancesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetCashAndBankBalances\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetCashAndBankBalancesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetCashAndBankBalances\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetCashAndCashEquivalentsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetCashAndCashEquivalents\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetCashAndCashEquivalentsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetCashAndCashEquivalents\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetCashAndCashEquivalentsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetCashAndCashEquivalents\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetCashAtBanksT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetCashAtBanks\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetCashAtBanksT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetCashAtBanks\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetCashAtBanksT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetCashAtBanks\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetCashOnHandT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetCashOnHand\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetCashOnHandT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetCashOnHand\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetCashOnHandT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetCashOnHand\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetCashT1\": {\n      \"disposition\": \"needs-decision\",\n      \"reason\": \"eight plausible financial-statement targets (CashAndBankBalances, CashAtBanks, CashOnHand, CashAndCashEquivalents, ...) and no exact match. Which the extractor populates is a question for the financial-statement owner, not a name lookup.\",\n      \"via\": \"consumer-sweep\"\n    },\n    \"currentAssetCashT2\": {\n      \"disposition\": \"needs-decision\",\n      \"reason\": \"eight plausible financial-statement targets (CashAndBankBalances, CashAtBanks, CashOnHand, CashAndCashEquivalents, ...) and no exact match. Which the extractor populates is a question for the financial-statement owner, not a name lookup.\",\n      \"via\": \"consumer-sweep\"\n    },\n    \"currentAssetCashT3\": {\n      \"disposition\": \"needs-decision\",\n      \"reason\": \"eight plausible financial-statement targets (CashAndBankBalances, CashAtBanks, CashOnHand, CashAndCashEquivalents, ...) and no exact match. Which the extractor populates is a question for the financial-statement owner, not a name lookup.\",\n      \"via\": \"consumer-sweep\"\n    },\n    \"currentAssetContractAssetsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetContractAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetContractAssetsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetContractAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetContractAssetsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetContractAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetCurrentTaxAssetsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetCurrentTaxAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetCurrentTaxAssetsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetCurrentTaxAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetCurrentTaxAssetsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetCurrentTaxAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetDepositsAndPrepaymentsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetDepositsAndPrepayments\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetDepositsAndPrepaymentsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetDepositsAndPrepayments\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetDepositsAndPrepaymentsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetDepositsAndPrepayments\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetDepositsCashAndBankBalancesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetDepositsCashAndBankBalances\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetDepositsCashAndBankBalancesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetDepositsCashAndBankBalances\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetDepositsCashAndBankBalancesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetDepositsCashAndBankBalances\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetDerivativeT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetDerivative\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetDerivativeT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetDerivative\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetDerivativeT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetDerivative\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetDevelopmentPropertiesOrExpenditureT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetDevelopmentPropertiesOrExpenditure\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetDevelopmentPropertiesOrExpenditureT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetDevelopmentPropertiesOrExpenditure\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetDevelopmentPropertiesOrExpenditureT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetDevelopmentPropertiesOrExpenditure\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetFinancialAssetAtFairValueT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetFinancialAssetAtFairValue\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetFinancialAssetAtFairValueT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetFinancialAssetAtFairValue\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetFinancialAssetAtFairValueT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetFinancialAssetAtFairValue\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetInventoriesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetInventories\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetInventoriesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetInventories\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetInventoriesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetInventories\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetLandUseRightT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetLandUseRight\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetLandUseRightT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetLandUseRight\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetLandUseRightT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetLandUseRight\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetOtherReceivablesAndDepositsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetOtherReceivablesAndDeposits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetOtherReceivablesAndDepositsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetOtherReceivablesAndDeposits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetOtherReceivablesAndDepositsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetOtherReceivablesAndDeposits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetOtherReceivablesAndPrepaymentsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetOtherReceivablesAndPrepayments\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetOtherReceivablesAndPrepaymentsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetOtherReceivablesAndPrepayments\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetOtherReceivablesAndPrepaymentsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetOtherReceivablesAndPrepayments\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetOtherReceivablesDepositsAndPrepaymentsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetOtherReceivablesDepositsAndPrepayments\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetOtherReceivablesDepositsAndPrepaymentsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetOtherReceivablesDepositsAndPrepayments\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetOtherReceivablesDepositsAndPrepaymentsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetOtherReceivablesDepositsAndPrepayments\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetOtherReceivablesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetOtherReceivables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetOtherReceivablesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetOtherReceivables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetOtherReceivablesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetOtherReceivables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetPrepaymentsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetPrepayments\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetPrepaymentsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetPrepayments\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetPrepaymentsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetPrepayments\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetRestrictedCashT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetRestrictedCash\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetRestrictedCashT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetRestrictedCash\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetRestrictedCashT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetRestrictedCash\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetShortTermDepositsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetShortTermDeposits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetShortTermDepositsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetShortTermDeposits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetShortTermDepositsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetShortTermDeposits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetShortTermInvestmentsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetShortTermInvestments\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetShortTermInvestmentsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetShortTermInvestments\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetShortTermInvestmentsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetShortTermInvestments\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetTaxRecoverableT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetTaxRecoverable\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetTaxRecoverableT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetTaxRecoverable\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetTaxRecoverableT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetTaxRecoverable\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetTradeAndOtherReceivablesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetTradeAndOtherReceivables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetTradeAndOtherReceivablesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetTradeAndOtherReceivables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetTradeAndOtherReceivablesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetTradeAndOtherReceivables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetTradeDebtorsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetTradeDebtors\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetTradeDebtorsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetTradeDebtors\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentAssetTradeDebtorsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentAssetTradeDebtors\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesAmountOwingToAssociatedCompaniesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesAmountOwingToAssociatedCompanies\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesAmountOwingToAssociatedCompaniesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesAmountOwingToAssociatedCompanies\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesAmountOwingToAssociatedCompaniesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesAmountOwingToAssociatedCompanies\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesAmountsOwingToDirectorT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesAmountsOwingToDirector\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesAmountsOwingToDirectorT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesAmountsOwingToDirector\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesAmountsOwingToDirectorT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesAmountsOwingToDirector\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesAmountsOwingToHoldingCompanyT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesAmountsOwingToHoldingCompany\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesAmountsOwingToHoldingCompanyT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesAmountsOwingToHoldingCompany\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesAmountsOwingToHoldingCompanyT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesAmountsOwingToHoldingCompany\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesAmountsOwingToSubsidiaryCompaniesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesAmountsOwingToSubsidiaryCompanies\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesAmountsOwingToSubsidiaryCompaniesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesAmountsOwingToSubsidiaryCompanies\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesAmountsOwingToSubsidiaryCompaniesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesAmountsOwingToSubsidiaryCompanies\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesBankAcceptanceT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesBankAcceptance\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesBankAcceptanceT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesBankAcceptance\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesBankAcceptanceT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesBankAcceptance\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesBankOverdraftT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesBankOverdraft\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesBankOverdraftT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesBankOverdraft\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesBankOverdraftT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesBankOverdraft\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesBankborrowingsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesBankborrowings\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesBankborrowingsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesBankborrowings\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesBankborrowingsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesBankborrowings\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesBorrowingsOrTermLoansT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesBorrowingsOrTermLoans\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesBorrowingsOrTermLoansT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesBorrowingsOrTermLoans\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesBorrowingsOrTermLoansT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesBorrowingsOrTermLoans\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesContractLiabilitiesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesContractLiabilities\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesContractLiabilitiesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesContractLiabilities\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesContractLiabilitiesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesContractLiabilities\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesDepositsFromCustomersT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesDepositsFromCustomers\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesDepositsFromCustomersT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesDepositsFromCustomers\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesDepositsFromCustomersT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesDepositsFromCustomers\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesDerivativeT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesDerivative\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesDerivativeT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesDerivative\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesDerivativeT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesDerivative\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesDividendPayablesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesDividendPayables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesDividendPayablesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesDividendPayables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesDividendPayablesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesDividendPayables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesFinanceLeasePayablesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesFinanceLeasePayables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesFinanceLeasePayablesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesFinanceLeasePayables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesFinanceLeasePayablesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesFinanceLeasePayables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesHirePurchasePayablesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesHirePurchasePayables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesHirePurchasePayablesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesHirePurchasePayables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesHirePurchasePayablesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesHirePurchasePayables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesLeasePayablesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesLeasePayables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesLeasePayablesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesLeasePayables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesLeasePayablesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesLeasePayables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesOtherPayablesAccrualsAndDepositsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesOtherPayablesAccrualsAndDeposits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesOtherPayablesAccrualsAndDepositsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesOtherPayablesAccrualsAndDeposits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesOtherPayablesAccrualsAndDepositsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesOtherPayablesAccrualsAndDeposits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesOtherPayablesAndAccrualsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesOtherPayablesAndAccruals\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesOtherPayablesAndAccrualsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesOtherPayablesAndAccruals\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesOtherPayablesAndAccrualsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesOtherPayablesAndAccruals\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesOtherPayablesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesOtherPayables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesOtherPayablesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesOtherPayables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesOtherPayablesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesOtherPayables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesProvisionForTaxationT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesProvisionForTaxation\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesProvisionForTaxationT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesProvisionForTaxation\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesProvisionForTaxationT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesProvisionForTaxation\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesTradeAndOtherPayablesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesTradeAndOtherPayables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesTradeAndOtherPayablesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesTradeAndOtherPayables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesTradeAndOtherPayablesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesTradeAndOtherPayables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesTradeCreditorsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesTradeCreditors\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesTradeCreditorsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesTradeCreditors\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"currentLiabilitiesTradeCreditorsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"currentLiabilitiesTradeCreditors\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"customerConcentrationTop5Pct\": {\n      \"address\": {\n        \"category\": \"payment-network\",\n        \"field\": \"customerConcentrationTop5Pct\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"customerRatingAvg\": {\n      \"address\": {\n        \"category\": \"social-media\",\n        \"field\": \"customerRatingAvg\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"customerUserId\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"dateApplied\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"dateJoined\": {\n      \"address\": {\n        \"category\": \"applicant-employment\",\n        \"field\": \"dateJoined\",\n        \"instanceKey\": \"current\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"dateOfBirth\": {\n      \"address\": {\n        \"category\": \"applicant-identity\",\n        \"field\": \"personDateOfBirth\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"dealerName\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"debtorConcentrationTop5Ratio\": {\n      \"address\": {\n        \"category\": \"trade-credit\",\n        \"field\": \"debtorConcentrationTop5Ratio\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"depreciationOfInvestmentPropertiesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"depreciationOfInvestmentProperties\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"depreciationOfInvestmentPropertiesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"depreciationOfInvestmentProperties\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"depreciationOfInvestmentPropertiesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"depreciationOfInvestmentProperties\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"depreciationOfInvestmentSecuritiesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"depreciationOfInvestmentSecurities\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"depreciationOfInvestmentSecuritiesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"depreciationOfInvestmentSecurities\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"depreciationOfInvestmentSecuritiesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"depreciationOfInvestmentSecurities\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"depreciationOfPropertyPlantEquipmentT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"depreciationOfPropertyPlantEquipment\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"depreciationOfPropertyPlantEquipmentT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"depreciationOfPropertyPlantEquipment\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"depreciationOfPropertyPlantEquipmentT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"depreciationOfPropertyPlantEquipment\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"depreciationRightOfUseAssetsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"depreciationRightOfUseAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"depreciationRightOfUseAssetsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"depreciationRightOfUseAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"depreciationRightOfUseAssetsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"depreciationRightOfUseAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"depreciationT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"depreciation\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"depreciationT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"depreciation\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"depreciationT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"depreciation\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"directors\": {\n      \"address\": {\n        \"category\": \"company-profile\",\n        \"field\": \"directors\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"disclosureOfInformation\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"the consent engine\",\n      \"via\": \"column-audit\"\n    },\n    \"disputeRate12m\": {\n      \"address\": {\n        \"category\": \"payment-network\",\n        \"field\": \"disputeRate12m\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"distressTier\": {\n      \"address\": {\n        \"category\": \"telco-carrier\",\n        \"field\": \"distressTier\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"documentMetadata\": {\n      \"disposition\": \"structural\",\n      \"note\": \"document-intake carries pointer metadata as canonical fields\"\n    },\n    \"downpayment\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"durationInCurrentResidenceMth\": {\n      \"address\": {\n        \"category\": \"applicant-address\",\n        \"field\": \"occupancyMonths\",\n        \"instanceKey\": \"residential\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"durationInCurrentResidenceYr\": {\n      \"address\": {\n        \"category\": \"applicant-address\",\n        \"field\": \"occupancyYears\",\n        \"instanceKey\": \"residential\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"ebitda\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"ebitda\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"ebitdaT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"ebitda\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"ebitdaT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"ebitda\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"ebitdaT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"ebitda\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"educationLevel\": {\n      \"address\": {\n        \"category\": \"applicant-demographics\",\n        \"field\": \"educationLevel\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"email\": {\n      \"address\": {\n        \"category\": \"applicant-contact\",\n        \"field\": \"contactValue\",\n        \"instanceKey\": \"email\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"emerContactTelNo1\": {\n      \"address\": {\n        \"category\": \"applicant-contact\",\n        \"field\": \"contactValue\",\n        \"instanceKey\": \"emergency\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"emerContactTelNo1AreaCode\": {\n      \"address\": {\n        \"category\": \"applicant-contact\",\n        \"field\": \"contactAreaCode\",\n        \"instanceKey\": \"emergency\"\n      },\n      \"disposition\": \"mapped-pending-build\",\n      \"note\": \"as mobilePhoneNoAreaCode \\u2014 the emergency instance exists and carries a name and relationship; the area code is uncollected.\",\n      \"via\": \"hand-authored\"\n    },\n    \"emergencyContactName\": {\n      \"address\": {\n        \"category\": \"applicant-contact\",\n        \"field\": \"contactName\",\n        \"instanceKey\": \"emergency\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"employerName\": {\n      \"address\": {\n        \"category\": \"applicant-employment\",\n        \"field\": \"employerName\",\n        \"instanceKey\": \"current\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"employmentSector\": {\n      \"address\": {\n        \"category\": \"applicant-employment\",\n        \"field\": \"employmentSector\",\n        \"instanceKey\": \"current\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"employmentStatus\": {\n      \"address\": {\n        \"category\": \"applicant-employment\",\n        \"field\": \"employmentStatus\",\n        \"instanceKey\": \"current\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"employmentType\": {\n      \"address\": {\n        \"category\": \"applicant-employment\",\n        \"field\": \"employmentType\",\n        \"instanceKey\": \"current\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"endOfYearCash\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"endOfYearCash\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"endOfYearCashT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"endOfYearCash\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"endOfYearCashT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"endOfYearCash\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"endOfYearCashT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"endOfYearCash\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"engagementRate90d\": {\n      \"address\": {\n        \"category\": \"social-media\",\n        \"field\": \"engagementRate90d\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"engineNo\": {\n      \"address\": {\n        \"category\": \"applicant-collateral\",\n        \"field\": \"vehicleEngineNo\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"entity\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"epfAccountHolderAddressT1\": {\n      \"address\": {\n        \"category\": \"epf-statement\",\n        \"field\": \"personAddress\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"epfAccountHolderAddressT2\": {\n      \"address\": {\n        \"category\": \"epf-statement\",\n        \"field\": \"personAddress\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"epfAccountHolderNameT1\": {\n      \"address\": {\n        \"category\": \"epf-statement\",\n        \"field\": \"personName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"epfAccountHolderNameT2\": {\n      \"address\": {\n        \"category\": \"epf-statement\",\n        \"field\": \"personName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"epfDateOfStatementT1\": {\n      \"address\": {\n        \"category\": \"epf-statement\",\n        \"field\": \"dateOfStatement\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"epfDateOfStatementT2\": {\n      \"address\": {\n        \"category\": \"epf-statement\",\n        \"field\": \"dateOfStatement\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"epfEmployerNumberT1\": {\n      \"address\": {\n        \"category\": \"epf-statement\",\n        \"field\": \"employerNumber\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"epfEmployerNumberT2\": {\n      \"address\": {\n        \"category\": \"epf-statement\",\n        \"field\": \"employerNumber\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"epfIcNumberT1\": {\n      \"address\": {\n        \"category\": \"epf-statement\",\n        \"field\": \"personIdNumber\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"epfIcNumberT2\": {\n      \"address\": {\n        \"category\": \"epf-statement\",\n        \"field\": \"personIdNumber\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"epfKwspMemberNumberT1\": {\n      \"address\": {\n        \"category\": \"epf-statement\",\n        \"field\": \"kwspMemberNumber\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"epfKwspMemberNumberT2\": {\n      \"address\": {\n        \"category\": \"epf-statement\",\n        \"field\": \"kwspMemberNumber\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"epfStatementInstances\": {\n      \"disposition\": \"structural\",\n      \"note\": \"v2 exposes these as epf-statement instances\"\n    },\n    \"epfStatementYearT1\": {\n      \"address\": {\n        \"category\": \"epf-statement\",\n        \"field\": \"statementYear\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"epfStatementYearT2\": {\n      \"address\": {\n        \"category\": \"epf-statement\",\n        \"field\": \"statementYear\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"epfStatements\": {\n      \"address\": {\n        \"category\": \"document-intake\",\n        \"field\": \"pathInDms\",\n        \"instanceKeyPrefix\": \"epfStatements\"\n      },\n      \"disposition\": \"mapped\",\n      \"note\": \"SHAPE CHANGE, not a rename. The v1 column held a JSON array of paths; document-intake keys one instance per file as <docType>#<sha256>, so this column becomes N instances.\",\n      \"via\": \"hand-authored\"\n    },\n    \"epfTotalContributionT1\": {\n      \"address\": {\n        \"category\": \"epf-statement\",\n        \"field\": \"totalContribution\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"epfTotalContributionT2\": {\n      \"address\": {\n        \"category\": \"epf-statement\",\n        \"field\": \"totalContribution\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"epfTotalCurrentContributionT1\": {\n      \"address\": {\n        \"category\": \"epf-statement\",\n        \"field\": \"totalCurrentContribution\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"epfTotalCurrentContributionT2\": {\n      \"address\": {\n        \"category\": \"epf-statement\",\n        \"field\": \"totalCurrentContribution\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"eppNoOfPax\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"eppPrice\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"eppProduct\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"exchangeEqualisationOrFluctuationReservesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"exchangeEqualisationOrFluctuationReserves\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"exchangeEqualisationOrFluctuationReservesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"exchangeEqualisationOrFluctuationReserves\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"exchangeEqualisationOrFluctuationReservesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"exchangeEqualisationOrFluctuationReserves\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"facilityAddress\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"facilityInterestRate\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"facilityPackage\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"facilityPurpose\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"facilityTenureYears\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"facilityType\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"fieldProvenance\": {\n      \"disposition\": \"structural\",\n      \"note\": \"provenance is a per-value envelope in v2; the sidecar map is redundant\"\n    },\n    \"financeCostT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"financeCost\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"financeCostT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"financeCost\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"financeCostT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"financeCost\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"financialStatementInstances\": {\n      \"disposition\": \"structural\",\n      \"note\": \"v2 exposes these as financial-statement instances\"\n    },\n    \"financialStatements\": {\n      \"address\": {\n        \"category\": \"document-intake\",\n        \"field\": \"pathInDms\",\n        \"instanceKeyPrefix\": \"financialStatements\"\n      },\n      \"disposition\": \"mapped\",\n      \"note\": \"SHAPE CHANGE, not a rename. The v1 column held a JSON array of paths; document-intake keys one instance per file as <docType>#<sha256>, so this column becomes N instances.\",\n      \"via\": \"hand-authored\"\n    },\n    \"financingSelection\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"financingTenure\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"finxtractConfigId\": {\n      \"disposition\": \"withheld\",\n      \"reason\": \"NOT served by GET /lender/applications/:ihsId, deliberately: applicationRecordService removed it in review before publication, because publication is what makes an API permanent. v1 still serves it. There is no v2 destination \\u2014 the honest answer to \\\"where do I get this\\\" is \\\"nowhere, by design\\\", which `relocated` obscured.\",\n      \"via\": \"column-audit\"\n    },\n    \"flexiRedrawOptIn\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"followerCount\": {\n      \"address\": {\n        \"category\": \"social-media\",\n        \"field\": \"followerCount\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"foreignPR\": {\n      \"disposition\": \"vocabulary-gap\",\n      \"note\": \"audit targets applicant-identity, which declares no permanent-residency field. Zero on every signal: no form, no consumer in six repos, 0 of 8,475 rows. Retire it only if nobody wants the FACT \\u2014 the fact itself is real and a CRA subject model may want it.\",\n      \"via\": \"hand-authored\"\n    },\n    \"form9\": {\n      \"address\": {\n        \"category\": \"document-intake\",\n        \"field\": \"pathInDms\",\n        \"instanceKeyPrefix\": \"form9\"\n      },\n      \"disposition\": \"mapped\",\n      \"note\": \"SHAPE CHANGE, not a rename. The v1 column held a JSON array of paths; document-intake keys one instance per file as <docType>#<sha256>, so this column becomes N instances.\",\n      \"via\": \"hand-authored\"\n    },\n    \"fullName\": {\n      \"address\": {\n        \"category\": \"applicant-identity\",\n        \"field\": \"personName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"gender\": {\n      \"address\": {\n        \"category\": \"applicant-demographics\",\n        \"field\": \"genderCode\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"grossMarginPct\": {\n      \"address\": {\n        \"category\": \"trade-credit\",\n        \"field\": \"grossMarginPct\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"grossProfitT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"grossProfit\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"grossProfitT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"grossProfit\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"grossProfitT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"grossProfit\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"handsetFinancingActive\": {\n      \"address\": {\n        \"category\": \"telco-carrier\",\n        \"field\": \"handsetFinancingActive\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"handsetFinancingDelinquent\": {\n      \"address\": {\n        \"category\": \"telco-carrier\",\n        \"field\": \"handsetFinancingDelinquent\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"handsetRiskTier\": {\n      \"address\": {\n        \"category\": \"telco-carrier\",\n        \"field\": \"handsetRiskTier\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"hirePurchaseMonthlyInstallment\": {\n      \"address\": {\n        \"category\": \"applicant-obligations\",\n        \"field\": \"obligationMonthlyInstallment\",\n        \"instanceKey\": \"hirePurchase\"\n      },\n      \"disposition\": \"mapped-pending-build\",\n      \"note\": \"CCRIS-sourced, named in the CitaGlobal Angkasa spec and feeding DSR/NDI. WooCommerce submits it today from installs we cannot update. The destination category has NO TABLE \\u2014 this is an address, not a live one. Multi-attestor: the same obligation may arrive from CTOS, Experian, manual entry or FHD.\",\n      \"via\": \"hand-authored\"\n    },\n    \"housingLoanMonthlyInstallment\": {\n      \"address\": {\n        \"category\": \"applicant-obligations\",\n        \"field\": \"obligationMonthlyInstallment\",\n        \"instanceKey\": \"housingLoan\"\n      },\n      \"disposition\": \"mapped-pending-build\",\n      \"note\": \"CCRIS-sourced, named in the CitaGlobal Angkasa spec and feeding DSR/NDI. WooCommerce submits it today from installs we cannot update. The destination category has NO TABLE \\u2014 this is an address, not a live one. Multi-attestor: the same obligation may arrive from CTOS, Experian, manual entry or FHD.\",\n      \"via\": \"hand-authored\"\n    },\n    \"ic\": {\n      \"address\": {\n        \"category\": \"document-intake\",\n        \"field\": \"pathInDms\",\n        \"instanceKeyPrefix\": \"ic\"\n      },\n      \"disposition\": \"mapped\",\n      \"note\": \"SHAPE CHANGE, not a rename. The v1 column held a JSON array of paths; document-intake keys one instance per file as <docType>#<sha256>, so this column becomes N instances.\",\n      \"via\": \"hand-authored\"\n    },\n    \"icAddress\": {\n      \"address\": {\n        \"category\": \"person-identity\",\n        \"field\": \"personAddress\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"icDateOfBirth\": {\n      \"address\": {\n        \"category\": \"person-identity\",\n        \"field\": \"personDateOfBirth\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"icGender\": {\n      \"address\": {\n        \"category\": \"person-identity\",\n        \"field\": \"personGender\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"icInstances\": {\n      \"disposition\": \"structural\",\n      \"note\": \"v2 exposes these as person-identity instances (the IC / passport extraction; the v1 sidecar already carries the canonical person* names, SYS-3163)\"\n    },\n    \"icName\": {\n      \"address\": {\n        \"category\": \"person-identity\",\n        \"field\": \"personName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"icNationality\": {\n      \"address\": {\n        \"category\": \"person-identity\",\n        \"field\": \"personNationality\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"icNumber\": {\n      \"address\": {\n        \"category\": \"person-identity\",\n        \"field\": \"personIdNumber\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"icPlaceOfBirth\": {\n      \"address\": {\n        \"category\": \"person-identity\",\n        \"field\": \"personPlaceOfBirth\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"icRace\": {\n      \"address\": {\n        \"category\": \"person-identity\",\n        \"field\": \"personRace\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"icReligion\": {\n      \"address\": {\n        \"category\": \"person-identity\",\n        \"field\": \"personReligion\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"idNumber\": {\n      \"address\": {\n        \"category\": \"applicant-identity\",\n        \"field\": \"personIdNumber\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"idType\": {\n      \"disposition\": \"vocabulary-gap\",\n      \"reason\": \"FIVE consumers \\u2014 Mudah and WooCommerce submit it, finhero-auto collects it as a typed dropdown driving idNumber consolidation, FinHub renders it, finsys-client renders it. Its only canonical match is related-person.relatedPersonIdType, which is the WRONG PERSON. No correct destination exists.\",\n      \"via\": \"consumer-sweep\"\n    },\n    \"ihsId\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"ihsType\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"incomeEPF_iakaun\": {\n      \"address\": {\n        \"category\": \"document-intake\",\n        \"field\": \"pathInDms\",\n        \"instanceKeyPrefix\": \"incomeEPF_iakaun\"\n      },\n      \"disposition\": \"mapped\",\n      \"note\": \"SHAPE CHANGE, not a rename. The v1 column held a JSON array of paths; document-intake keys one instance per file as <docType>#<sha256>, so this column becomes N instances.\",\n      \"via\": \"hand-authored\"\n    },\n    \"incomeSupportingDoc\": {\n      \"address\": {\n        \"category\": \"document-intake\",\n        \"field\": \"pathInDms\",\n        \"instanceKeyPrefix\": \"incomeSupportingDoc\"\n      },\n      \"disposition\": \"mapped\",\n      \"note\": \"SHAPE CHANGE, not a rename. The v1 column held a JSON array of paths; document-intake keys one instance per file as <docType>#<sha256>, so this column becomes N instances.\",\n      \"via\": \"hand-authored\"\n    },\n    \"incorporatedDate\": {\n      \"addresses\": [\n        {\n          \"category\": \"company-profile\",\n          \"field\": \"companyIncorporationDate\"\n        },\n        {\n          \"category\": \"company-registration\",\n          \"field\": \"companyIncorporationDate\"\n        }\n      ],\n      \"disposition\": \"mapped-fanout\",\n      \"note\": \"ONE v1 column, TWO attestors. The wide table could hold one value, so the second writer overwrote the first; v2 keeps both instances and the disagreement is the signal. A consumer reading one address gets one attestor's answer, not \\\"the\\\" answer.\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"internationalExtensionPhoneNo\": {\n      \"address\": {\n        \"category\": \"applicant-contact\",\n        \"field\": \"contactExtension\",\n        \"instanceKey\": \"international\"\n      },\n      \"disposition\": \"mapped-pending-build\",\n      \"note\": \"as internationalPhoneNo \\u2014 instance not minted by any manifest.\",\n      \"via\": \"hand-authored\"\n    },\n    \"internationalPhoneNo\": {\n      \"address\": {\n        \"category\": \"applicant-contact\",\n        \"field\": \"contactValue\",\n        \"instanceKey\": \"international\"\n      },\n      \"disposition\": \"mapped-pending-build\",\n      \"note\": \"NO manifest mints an \\\"international\\\" instance \\u2014 the four are email, mobile, office, emergency. The field resolves; the instance has to be created before anything can write it. 0 of 8,475 rows populated.\",\n      \"via\": \"hand-authored\"\n    },\n    \"internationalPhoneNoAreaCode\": {\n      \"address\": {\n        \"category\": \"applicant-contact\",\n        \"field\": \"contactAreaCode\",\n        \"instanceKey\": \"international\"\n      },\n      \"disposition\": \"mapped-pending-build\",\n      \"note\": \"as internationalPhoneNo \\u2014 instance not minted by any manifest.\",\n      \"via\": \"hand-authored\"\n    },\n    \"invoiceInstances\": {\n      \"disposition\": \"structural\",\n      \"note\": \"no invoice category is declared \\u2014 SYS-3376\"\n    },\n    \"invoices\": {\n      \"address\": {\n        \"category\": \"document-intake\",\n        \"field\": \"pathInDms\",\n        \"instanceKeyPrefix\": \"invoices\"\n      },\n      \"disposition\": \"mapped\",\n      \"note\": \"SHAPE CHANGE, not a rename. The v1 column held a JSON array of paths; document-intake keys one instance per file as <docType>#<sha256>, so this column becomes N instances.\",\n      \"via\": \"hand-authored\"\n    },\n    \"isApplication\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"isReview\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"jurisdiction\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"lateDays24m\": {\n      \"address\": {\n        \"category\": \"telco-carrier\",\n        \"field\": \"lateDays24m\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"lenderId\": {\n      \"disposition\": \"withheld\",\n      \"reason\": \"NOT served by GET /lender/applications/:ihsId, deliberately: applicationRecordService removed it in review before publication, because publication is what makes an API permanent. v1 still serves it. There is no v2 destination \\u2014 the honest answer to \\\"where do I get this\\\" is \\\"nowhere, by design\\\", which `relocated` obscured.\",\n      \"via\": \"column-audit\"\n    },\n    \"lengthOfServiceMonth\": {\n      \"disposition\": \"retired\",\n      \"reason\": \"as lengthOfServiceYear \\u2014 recomputed locally before display.\",\n      \"via\": \"consumer-sweep\"\n    },\n    \"lengthOfServiceYear\": {\n      \"disposition\": \"retired\",\n      \"reason\": \"already dead for display: finsys-client recomputes it from dateJoined (ihs_detail.ts:230-247) before rendering, so the API value is never shown.\",\n      \"via\": \"consumer-sweep\"\n    },\n    \"mailingBillingAddressInd\": {\n      \"disposition\": \"needs-decision\",\n      \"note\": \"NOT an address property. Its choices are Office / Residence, so it names WHICH address is preferred for mail \\u2014 a statement about the application, and putting it on an address instance would make that row claim something about its siblings. applicant-address-form-v1 declined it for exactly that reason. It IS collected (personal_loan.json; 30 of 8,475 rows). Candidate home: the application record (GET /lender/applications/:ihsId), which already carries application-level facts \\u2014 but nothing there owns applicant PREFERENCES yet.\",\n      \"via\": \"hand-authored\"\n    },\n    \"makeOfVehicle\": {\n      \"address\": {\n        \"category\": \"applicant-collateral\",\n        \"field\": \"vehicleMake\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"maritalStatus\": {\n      \"address\": {\n        \"category\": \"applicant-demographics\",\n        \"field\": \"maritalStatus\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"marketValue\": {\n      \"address\": {\n        \"category\": \"applicant-collateral\",\n        \"field\": \"collateralMarketValue\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"mobilePhoneNo\": {\n      \"address\": {\n        \"category\": \"applicant-contact\",\n        \"field\": \"contactValue\",\n        \"instanceKey\": \"mobile\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"mobilePhoneNoAreaCode\": {\n      \"address\": {\n        \"category\": \"applicant-contact\",\n        \"field\": \"contactAreaCode\",\n        \"instanceKey\": \"mobile\"\n      },\n      \"disposition\": \"mapped-pending-build\",\n      \"note\": \"the instance exists (mobilePhoneNo mints it); no form collects the area code, so the field is addressable and permanently empty until one does.\",\n      \"via\": \"hand-authored\"\n    },\n    \"modelOfVehicle\": {\n      \"address\": {\n        \"category\": \"applicant-collateral\",\n        \"field\": \"vehicleModel\",\n        \"instanceKey\": \"0\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"monthlyGrossIncome\": {\n      \"address\": {\n        \"category\": \"applicant-income\",\n        \"field\": \"grossPay\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"monthlyNetIncome\": {\n      \"address\": {\n        \"category\": \"applicant-income\",\n        \"field\": \"netPay\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"monthlyRepayment\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"monthlyVolume12m\": {\n      \"address\": {\n        \"category\": \"payment-network\",\n        \"field\": \"monthlyVolume12m\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"monthlyVolume3m\": {\n      \"address\": {\n        \"category\": \"payment-network\",\n        \"field\": \"monthlyVolume3m\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"myKadOrPassport\": {\n      \"address\": {\n        \"category\": \"document-intake\",\n        \"field\": \"pathInDms\",\n        \"instanceKeyPrefix\": \"myKadOrPassport\"\n      },\n      \"disposition\": \"mapped\",\n      \"note\": \"SHAPE CHANGE, not a rename. The v1 column held a JSON array of paths; document-intake keys one instance per file as <docType>#<sha256>, so this column becomes N instances.\",\n      \"via\": \"hand-authored\"\n    },\n    \"nationality\": {\n      \"address\": {\n        \"category\": \"applicant-identity\",\n        \"field\": \"personNationality\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"natureOfBusiness\": {\n      \"address\": {\n        \"category\": \"subject-company\",\n        \"field\": \"businessNatureCode\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"negativeSentimentRatio90d\": {\n      \"address\": {\n        \"category\": \"social-media\",\n        \"field\": \"negativeSentimentRatio90d\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"netOperatingCashFlow\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"netOperatingCashFlow\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"netOperatingCashFlowT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"netOperatingCashFlow\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"netOperatingCashFlowT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"netOperatingCashFlow\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"netOperatingCashFlowT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"netOperatingCashFlow\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"netProfitPriorYearT1\": {\n      \"disposition\": \"needs-decision\",\n      \"note\": \"the Vietnam financial-statement spec writes this PRIOR-YEAR comparative on the SAME row as netProfitT1 (financialStatementSpecVN.ts, the total-comprehensive-income \\\"-(t-2)\\\" column) -- not a second document, a second column on the first one. The registry declares no PriorYear field for netProfit and the VN spec is not period-aware, so there is no address to resolve to yet. TWO candidate resolutions, an owner decides: (1) make the VN spec period-aware, so the comparative becomes period 2 of the SAME document and resolves like any other T-slot; or (2) declare a netProfitPriorYear registry field. Until one ships, do not resolve this through the feeder branch that netProfitT1 uses -- that silently returns the CURRENT-year value under this PRIOR-year name, which is what this override exists to stop.\",\n      \"via\": \"hand-authored\"\n    },\n    \"netProfitPriorYearT2\": {\n      \"disposition\": \"needs-decision\",\n      \"note\": \"as netProfitPriorYearT1 -- the same SAME-row VN comparative, one T-slot over. See that entry for the full finding; the two candidate resolutions are identical: make the VN spec period-aware, or declare netProfitPriorYear as its own registry field.\",\n      \"via\": \"hand-authored\"\n    },\n    \"netProfitPriorYearT3\": {\n      \"disposition\": \"needs-decision\",\n      \"note\": \"as netProfitPriorYearT1 -- the same SAME-row VN comparative, one T-slot over. See that entry for the full finding; the two candidate resolutions are identical: make the VN spec period-aware, or declare netProfitPriorYear as its own registry field.\",\n      \"via\": \"hand-authored\"\n    },\n    \"netProfitT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"netProfit\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"netProfitT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"netProfit\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"netProfitT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"netProfit\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"noOfDependants\": {\n      \"address\": {\n        \"category\": \"applicant-demographics\",\n        \"field\": \"dependantsCount\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"noOfEmployees\": {\n      \"disposition\": \"vocabulary-gap\",\n      \"reason\": \"wanted as an SME signal (Kain) but 0 of 8,474 rows populated and no canonical field of the right kind \\u2014 subject-company.companySizeCode is a coded BAND, this is a raw COUNT. Needs a new employeeCount:number on subject-company.\",\n      \"via\": \"consumer-sweep\"\n    },\n    \"nonCurrentAssetDeferredAssetsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetDeferredAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetDeferredAssetsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetDeferredAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetDeferredAssetsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetDeferredAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetDepositsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetDeposits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetDepositsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetDeposits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetDepositsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetDeposits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetFinancialAssetAtFairValueT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetFinancialAssetAtFairValue\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetFinancialAssetAtFairValueT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetFinancialAssetAtFairValue\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetFinancialAssetAtFairValueT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetFinancialAssetAtFairValue\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetGoodwillOnConsolidationT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetGoodwillOnConsolidation\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetGoodwillOnConsolidationT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetGoodwillOnConsolidation\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetGoodwillOnConsolidationT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetGoodwillOnConsolidation\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetIntangibleAssetsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetIntangibleAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetIntangibleAssetsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetIntangibleAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetIntangibleAssetsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetIntangibleAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetInventoriesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetInventories\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetInventoriesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetInventories\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetInventoriesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetInventories\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetInvestmentPropertiesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetInvestmentProperties\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetInvestmentPropertiesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetInvestmentProperties\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetInvestmentPropertiesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetInvestmentProperties\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetInvestmentSecuritiesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetInvestmentSecurities\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetInvestmentSecuritiesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetInvestmentSecurities\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetInvestmentSecuritiesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetInvestmentSecurities\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetLandUseRightT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetLandUseRight\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetLandUseRightT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetLandUseRight\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetLandUseRightT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetLandUseRight\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetOtherReceivablesDepositsAndPrepaymentsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetOtherReceivablesDepositsAndPrepayments\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetOtherReceivablesDepositsAndPrepaymentsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetOtherReceivablesDepositsAndPrepayments\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetOtherReceivablesDepositsAndPrepaymentsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetOtherReceivablesDepositsAndPrepayments\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetOtherReceivablesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetOtherReceivables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetOtherReceivablesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetOtherReceivables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetOtherReceivablesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetOtherReceivables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetOwnGoodwillT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetOwnGoodwill\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetOwnGoodwillT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetOwnGoodwill\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetOwnGoodwillT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetOwnGoodwill\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetPrepaidLeasePaymentsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetPrepaidLeasePayments\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetPrepaidLeasePaymentsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetPrepaidLeasePayments\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetPrepaidLeasePaymentsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetPrepaidLeasePayments\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetPropertyPlantEquipmentT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetPropertyPlantEquipment\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetPropertyPlantEquipmentT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetPropertyPlantEquipment\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetPropertyPlantEquipmentT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetPropertyPlantEquipment\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetRightOfUseAssetsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetRightOfUseAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetRightOfUseAssetsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetRightOfUseAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetRightOfUseAssetsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetRightOfUseAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetSinkingFundT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetSinkingFund\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetSinkingFundT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetSinkingFund\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetSinkingFundT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetSinkingFund\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetTradeAndOtherReceivablesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetTradeAndOtherReceivables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetTradeAndOtherReceivablesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetTradeAndOtherReceivables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetTradeAndOtherReceivablesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetTradeAndOtherReceivables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetTradeReceivablesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetTradeReceivables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetTradeReceivablesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetTradeReceivables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetTradeReceivablesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetTradeReceivables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetsAssociatedCompaniesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetsAssociatedCompanies\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetsAssociatedCompaniesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetsAssociatedCompanies\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetsAssociatedCompaniesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetsAssociatedCompanies\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetsDevelopmentPropertiesOrExpenditureT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetsDevelopmentPropertiesOrExpenditure\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetsDevelopmentPropertiesOrExpenditureT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetsDevelopmentPropertiesOrExpenditure\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetsDevelopmentPropertiesOrExpenditureT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetsDevelopmentPropertiesOrExpenditure\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetsInvestmentsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetsInvestments\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetsInvestmentsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetsInvestments\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetsInvestmentsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetsInvestments\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetsSubsidiaryCompaniesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetsSubsidiaryCompanies\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetsSubsidiaryCompaniesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetsSubsidiaryCompanies\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentAssetsSubsidiaryCompaniesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentAssetsSubsidiaryCompanies\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesBankBorrowingsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesBankBorrowings\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesBankBorrowingsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesBankBorrowings\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesBankBorrowingsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesBankBorrowings\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesBorrowingsOrTermLoansT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesBorrowingsOrTermLoans\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesBorrowingsOrTermLoansT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesBorrowingsOrTermLoans\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesBorrowingsOrTermLoansT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesBorrowingsOrTermLoans\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesContractLiabilitiesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesContractLiabilities\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesContractLiabilitiesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesContractLiabilities\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesContractLiabilitiesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesContractLiabilities\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesDeferredTaxationT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesDeferredTaxation\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesDeferredTaxationT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesDeferredTaxation\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesDeferredTaxationT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesDeferredTaxation\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesDepositsFromCustomersT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesDepositsFromCustomers\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesDepositsFromCustomersT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesDepositsFromCustomers\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesDepositsFromCustomersT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesDepositsFromCustomers\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesFinanceLeaseObligationsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesFinanceLeaseObligations\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesFinanceLeaseObligationsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesFinanceLeaseObligations\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesFinanceLeaseObligationsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesFinanceLeaseObligations\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesHirePurchasePayablesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesHirePurchasePayables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesHirePurchasePayablesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesHirePurchasePayables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesHirePurchasePayablesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesHirePurchasePayables\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesLeaseObligationsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesLeaseObligations\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesLeaseObligationsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesLeaseObligations\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesLeaseObligationsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesLeaseObligations\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesRetirementBenefitsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesRetirementBenefits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesRetirementBenefitsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesRetirementBenefits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"nonCurrentLiabilitiesRetirementBenefitsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"nonCurrentLiabilitiesRetirementBenefits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"occupation\": {\n      \"address\": {\n        \"category\": \"applicant-employment\",\n        \"field\": \"occupation\",\n        \"instanceKey\": \"current\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"officeFacilityType\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"officePhoneNo\": {\n      \"address\": {\n        \"category\": \"applicant-contact\",\n        \"field\": \"contactValue\",\n        \"instanceKey\": \"office\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"officePhoneNoAreaCode\": {\n      \"address\": {\n        \"category\": \"applicant-contact\",\n        \"field\": \"contactAreaCode\",\n        \"instanceKey\": \"office\"\n      },\n      \"disposition\": \"mapped-pending-build\",\n      \"note\": \"as mobilePhoneNoAreaCode \\u2014 the office instance exists, the area code is uncollected.\",\n      \"via\": \"hand-authored\"\n    },\n    \"officeaddressLine1\": {\n      \"address\": {\n        \"category\": \"applicant-address\",\n        \"field\": \"addressLine1\",\n        \"instanceKey\": \"office\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"officeaddressLine2\": {\n      \"address\": {\n        \"category\": \"applicant-address\",\n        \"field\": \"addressLine2\",\n        \"instanceKey\": \"office\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"officeaddressLine3\": {\n      \"address\": {\n        \"category\": \"applicant-address\",\n        \"field\": \"addressLine3\",\n        \"instanceKey\": \"office\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"officeaddressType\": {\n      \"disposition\": \"retired\",\n      \"note\": \"as addressType \\u2014 the instance key carries the discriminator.\",\n      \"via\": \"hand-authored\"\n    },\n    \"officecity\": {\n      \"address\": {\n        \"category\": \"applicant-address\",\n        \"field\": \"addressCity\",\n        \"instanceKey\": \"office\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"officepostcode\": {\n      \"address\": {\n        \"category\": \"applicant-address\",\n        \"field\": \"addressPostcode\",\n        \"instanceKey\": \"office\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"officestate\": {\n      \"address\": {\n        \"category\": \"applicant-address\",\n        \"field\": \"addressStateCode\",\n        \"instanceKey\": \"office\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"onTimePaymentRatio24m\": {\n      \"address\": {\n        \"category\": \"telco-carrier\",\n        \"field\": \"onTimePaymentRatio24m\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"openingBalanceT1\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"openingBalance\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"openingBalanceT2\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"openingBalance\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"openingBalanceT3\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"openingBalance\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"openingBalanceT4\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"openingBalance\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"openingBalanceT5\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"openingBalance\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"openingBalanceT6\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"openingBalance\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"originatorCode\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"otherFinancingMonthlyInstallment\": {\n      \"address\": {\n        \"category\": \"applicant-obligations\",\n        \"field\": \"obligationMonthlyInstallment\",\n        \"instanceKey\": \"otherFinancing\"\n      },\n      \"disposition\": \"mapped-pending-build\",\n      \"note\": \"CCRIS-sourced, named in the CitaGlobal Angkasa spec and feeding DSR/NDI. WooCommerce submits it today from installs we cannot update. The destination category has NO TABLE \\u2014 this is an address, not a live one. Multi-attestor: the same obligation may arrive from CTOS, Experian, manual entry or FHD.\",\n      \"via\": \"hand-authored\"\n    },\n    \"otherIncomeT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"otherIncome\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"otherIncomeT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"otherIncome\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"otherIncomeT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"otherIncome\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"pRIDNo\": {\n      \"disposition\": \"vocabulary-gap\",\n      \"note\": \"as foreignPR \\u2014 the PR identity number. applicant-identity.personIdNumber attests the primary ID; a second, differently-issued number needs its own field or an idType-qualified instance, which is the same gap idType has.\",\n      \"via\": \"hand-authored\"\n    },\n    \"paymentReliabilityTier\": {\n      \"address\": {\n        \"category\": \"telco-carrier\",\n        \"field\": \"paymentReliabilityTier\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"payslipBasicPayT1\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"basicPay\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipBasicPayT2\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"basicPay\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipBasicPayT3\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"basicPay\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipBasicPayT4\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"basicPay\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipBasicPayT5\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"basicPay\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipBasicPayT6\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"basicPay\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipDeductionT1\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"deduction\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipDeductionT2\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"deduction\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipDeductionT3\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"deduction\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipDeductionT4\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"deduction\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipDeductionT5\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"deduction\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipDeductionT6\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"deduction\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeEisContributionT1\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employeeEisContribution\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeEisContributionT2\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employeeEisContribution\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeEisContributionT3\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employeeEisContribution\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeEisContributionT4\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employeeEisContribution\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeEisContributionT5\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employeeEisContribution\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeEisContributionT6\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employeeEisContribution\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeEpfContributionT1\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employeeEpfContribution\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeEpfContributionT2\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employeeEpfContribution\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeEpfContributionT3\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employeeEpfContribution\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeEpfContributionT4\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employeeEpfContribution\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeEpfContributionT5\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employeeEpfContribution\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeEpfContributionT6\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employeeEpfContribution\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeNameT1\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"personName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeNameT2\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"personName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeNameT3\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"personName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeNameT4\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"personName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeNameT5\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"personName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeNameT6\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"personName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeSocsoContributionT1\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employeeSocsoContribution\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeSocsoContributionT2\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employeeSocsoContribution\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeSocsoContributionT3\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employeeSocsoContribution\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeSocsoContributionT4\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employeeSocsoContribution\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeSocsoContributionT5\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employeeSocsoContribution\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeSocsoContributionT6\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employeeSocsoContribution\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeTaxT1\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employeeTax\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeTaxT2\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employeeTax\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeTaxT3\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employeeTax\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeTaxT4\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employeeTax\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeTaxT5\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employeeTax\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployeeTaxT6\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employeeTax\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployerNameT1\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employerName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployerNameT2\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employerName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployerNameT3\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employerName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployerNameT4\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employerName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployerNameT5\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employerName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipEmployerNameT6\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"employerName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipFixedAllowancesT1\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"fixedAllowances\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipFixedAllowancesT2\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"fixedAllowances\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipFixedAllowancesT3\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"fixedAllowances\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipFixedAllowancesT4\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"fixedAllowances\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipFixedAllowancesT5\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"fixedAllowances\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipFixedAllowancesT6\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"fixedAllowances\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipGrossPayT1\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"grossPay\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipGrossPayT2\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"grossPay\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipGrossPayT3\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"grossPay\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipGrossPayT4\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"grossPay\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipGrossPayT5\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"grossPay\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipGrossPayT6\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"grossPay\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipInstances\": {\n      \"disposition\": \"structural\",\n      \"note\": \"v2 exposes these as payslip instances\"\n    },\n    \"payslipNetPayT1\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"netPay\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipNetPayT2\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"netPay\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipNetPayT3\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"netPay\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipNetPayT4\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"netPay\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipNetPayT5\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"netPay\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipNetPayT6\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"netPay\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipOtherDeductionT1\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"otherDeduction\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipOtherDeductionT2\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"otherDeduction\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipOtherDeductionT3\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"otherDeduction\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipOtherDeductionT4\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"otherDeduction\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipOtherDeductionT5\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"otherDeduction\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipOtherDeductionT6\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"otherDeduction\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipPayDateT1\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"payDate\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipPayDateT2\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"payDate\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipPayDateT3\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"payDate\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipPayDateT4\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"payDate\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipPayDateT5\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"payDate\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipPayDateT6\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"payDate\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipPayPeriodT1\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"payPeriod\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipPayPeriodT2\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"payPeriod\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipPayPeriodT3\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"payPeriod\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipPayPeriodT4\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"payPeriod\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipPayPeriodT5\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"payPeriod\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipPayPeriodT6\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"payPeriod\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipVariableIncomeT1\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"variableIncome\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipVariableIncomeT2\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"variableIncome\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipVariableIncomeT3\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"variableIncome\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipVariableIncomeT4\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"variableIncome\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipVariableIncomeT5\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"variableIncome\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslipVariableIncomeT6\": {\n      \"address\": {\n        \"category\": \"payslip\",\n        \"field\": \"variableIncome\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"payslips\": {\n      \"address\": {\n        \"category\": \"document-intake\",\n        \"field\": \"pathInDms\",\n        \"instanceKeyPrefix\": \"payslips\"\n      },\n      \"disposition\": \"mapped\",\n      \"note\": \"SHAPE CHANGE, not a rename. The v1 column held a JSON array of paths; document-intake keys one instance per file as <docType>#<sha256>, so this column becomes N instances.\",\n      \"via\": \"hand-authored\"\n    },\n    \"permanentaddressLine1\": {\n      \"address\": {\n        \"category\": \"applicant-address\",\n        \"field\": \"addressLine1\",\n        \"instanceKey\": \"permanent\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"permanentaddressLine2\": {\n      \"address\": {\n        \"category\": \"applicant-address\",\n        \"field\": \"addressLine2\",\n        \"instanceKey\": \"permanent\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"permanentaddressLine3\": {\n      \"address\": {\n        \"category\": \"applicant-address\",\n        \"field\": \"addressLine3\",\n        \"instanceKey\": \"permanent\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"permanentaddressType\": {\n      \"disposition\": \"retired\",\n      \"note\": \"as addressType \\u2014 the instance key carries the discriminator.\",\n      \"via\": \"hand-authored\"\n    },\n    \"permanentcity\": {\n      \"address\": {\n        \"category\": \"applicant-address\",\n        \"field\": \"addressCity\",\n        \"instanceKey\": \"permanent\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"permanentpostcode\": {\n      \"address\": {\n        \"category\": \"applicant-address\",\n        \"field\": \"addressPostcode\",\n        \"instanceKey\": \"permanent\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"personalLoanMonthlyInstallment\": {\n      \"address\": {\n        \"category\": \"applicant-obligations\",\n        \"field\": \"obligationMonthlyInstallment\",\n        \"instanceKey\": \"personalLoan\"\n      },\n      \"disposition\": \"mapped-pending-build\",\n      \"note\": \"CCRIS-sourced, named in the CitaGlobal Angkasa spec and feeding DSR/NDI. WooCommerce submits it today from installs we cannot update. The destination category has NO TABLE \\u2014 this is an address, not a live one. Multi-attestor: the same obligation may arrive from CTOS, Experian, manual entry or FHD.\",\n      \"via\": \"hand-authored\"\n    },\n    \"phoneNumber\": {\n      \"disposition\": \"needs-decision\",\n      \"note\": \"THE FIELD IS KNOWN AND THE INSTANCE IS NOT. applicant-contact.contactValue is the home, but this column is unqualified: it is one of the founding columns (InitialMigration, alongside fullName/email/idNumber), predating the mobile/office/emergency split, so nothing in the schema says which kind of contact point it holds. Assigning an instance key guesses, and a wrong guess attests a mobile number as an office one. No live form collects it; finsys-client renders it through the GENERIC catalog path (ui.ts:33), which degrades silently rather than breaking. Needs a data-shape read against production before an instance key is chosen.\",\n      \"via\": \"hand-authored\"\n    },\n    \"photocopyRegistrationCard\": {\n      \"address\": {\n        \"category\": \"document-intake\",\n        \"field\": \"pathInDms\",\n        \"instanceKeyPrefix\": \"photocopyRegistrationCard\"\n      },\n      \"disposition\": \"mapped\",\n      \"note\": \"SHAPE CHANGE, not a rename. The v1 column held a JSON array of paths; document-intake keys one instance per file as <docType>#<sha256>, so this column becomes N instances.\",\n      \"via\": \"hand-authored\"\n    },\n    \"postcode\": {\n      \"disposition\": \"retired\",\n      \"reason\": \"as city \\u2014 collected and submitted as permanentpostcode.\",\n      \"via\": \"consumer-sweep\"\n    },\n    \"postingConsistency12m\": {\n      \"address\": {\n        \"category\": \"social-media\",\n        \"field\": \"postingConsistency12m\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"preferenceShareCapitalT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"preferenceShareCapital\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"preferenceShareCapitalT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"preferenceShareCapital\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"preferenceShareCapitalT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"preferenceShareCapital\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"preferredBranch\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"preferredLanguage\": {\n      \"address\": {\n        \"category\": \"applicant-demographics\",\n        \"field\": \"preferredLanguage\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"previousDirectors\": {\n      \"address\": {\n        \"category\": \"company-profile\",\n        \"field\": \"previousDirectors\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"product\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"profitAfterTaxT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"profitAfterTax\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"profitAfterTaxT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"profitAfterTax\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"profitAfterTaxT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"profitAfterTax\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"profitFromOperationsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"profitFromOperations\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"profitFromOperationsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"profitFromOperations\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"profitFromOperationsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"profitFromOperations\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"programId\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"purchasePriceOTR\": {\n      \"address\": {\n        \"category\": \"applicant-collateral\",\n        \"field\": \"collateralPurchasePriceOnTheRoad\",\n        \"instanceKey\": \"0\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"purposeOfAcctOpen\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"purposeOfAcquisition\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"race\": {\n      \"address\": {\n        \"category\": \"applicant-demographics\",\n        \"field\": \"raceCode\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"registeredAddress\": {\n      \"address\": {\n        \"category\": \"company-profile\",\n        \"field\": \"registeredAddress\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"registrationDate\": {\n      \"address\": {\n        \"category\": \"applicant-collateral\",\n        \"field\": \"vehicleRegistrationDate\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"registrationNo\": {\n      \"address\": {\n        \"category\": \"applicant-collateral\",\n        \"field\": \"vehicleRegistrationNo\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"relationshiptoContactName\": {\n      \"address\": {\n        \"category\": \"applicant-contact\",\n        \"field\": \"contactRelationship\",\n        \"instanceKey\": \"emergency\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"reservesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"reserves\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"reservesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"reserves\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"reservesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"reserves\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"residenceType\": {\n      \"address\": {\n        \"category\": \"applicant-demographics\",\n        \"field\": \"residenceType\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"residentialaddressLine1\": {\n      \"address\": {\n        \"category\": \"applicant-address\",\n        \"field\": \"addressLine1\",\n        \"instanceKey\": \"residential\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"residentialaddressLine2\": {\n      \"address\": {\n        \"category\": \"applicant-address\",\n        \"field\": \"addressLine2\",\n        \"instanceKey\": \"residential\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"residentialaddressLine3\": {\n      \"address\": {\n        \"category\": \"applicant-address\",\n        \"field\": \"addressLine3\",\n        \"instanceKey\": \"residential\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"residentialaddressType\": {\n      \"disposition\": \"retired\",\n      \"note\": \"as addressType \\u2014 the instance key carries the discriminator.\",\n      \"via\": \"hand-authored\"\n    },\n    \"residentialcity\": {\n      \"address\": {\n        \"category\": \"applicant-address\",\n        \"field\": \"addressCity\",\n        \"instanceKey\": \"residential\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"residentialpostcode\": {\n      \"address\": {\n        \"category\": \"applicant-address\",\n        \"field\": \"addressPostcode\",\n        \"instanceKey\": \"residential\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"residentialstate\": {\n      \"address\": {\n        \"category\": \"applicant-address\",\n        \"field\": \"addressStateCode\",\n        \"instanceKey\": \"residential\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"retainedEarningsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"retainedEarnings\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"retainedEarningsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"retainedEarnings\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"retainedEarningsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"retainedEarnings\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"revaluationReservesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"revaluationReserves\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"revaluationReservesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"revaluationReserves\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"revaluationReservesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"revaluationReserves\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"revenueT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"revenue\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"revenueT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"revenue\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"revenueT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"revenue\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"salutation\": {\n      \"disposition\": \"vocabulary-gap\",\n      \"note\": \"the SYS-2499 audit targets applicant-identity, which declares no salutation field \\u2014 and a title is not an identity ATTESTATION, it is a form of address. Collected ONLY by personal_loan.json (retired product, which Kain has said could be resurrected) and one lead-gen submit script; 0 of 8,475 rows. Needs a declared field before it has an address.\",\n      \"via\": \"hand-authored\"\n    },\n    \"shareCapital\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"shareCapital\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"shareCapitalT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"shareCapital\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"shareCapitalT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"shareCapital\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"shareCapitalT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"shareCapital\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"sharePremiumT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"sharePremium\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"sharePremiumT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"sharePremium\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"sharePremiumT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"sharePremium\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"shareholders\": {\n      \"address\": {\n        \"category\": \"company-profile\",\n        \"field\": \"shareholders\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"shortTermLiabilities\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"shortTermLiabilities\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"shortTermLiabilitiesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"shortTermLiabilities\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"shortTermLiabilitiesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"shortTermLiabilities\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"shortTermLiabilitiesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"shortTermLiabilities\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"sourceOfFund\": {\n      \"address\": {\n        \"category\": \"applicant-income\",\n        \"field\": \"sourceOfFund\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"sourceOfWealth\": {\n      \"address\": {\n        \"category\": \"applicant-income\",\n        \"field\": \"sourceOfWealth\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"ssm\": {\n      \"address\": {\n        \"category\": \"document-intake\",\n        \"field\": \"pathInDms\",\n        \"instanceKeyPrefix\": \"ssm\"\n      },\n      \"disposition\": \"mapped\",\n      \"note\": \"SHAPE CHANGE, not a rename. The v1 column held a JSON array of paths; document-intake keys one instance per file as <docType>#<sha256>, so this column becomes N instances.\",\n      \"via\": \"hand-authored\"\n    },\n    \"ssmCompanyEntityType\": {\n      \"address\": {\n        \"category\": \"company-profile\",\n        \"field\": \"companyEntityType\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"ssmCompanyName\": {\n      \"address\": {\n        \"category\": \"company-profile\",\n        \"field\": \"companyName\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"ssmCompanyRegNo\": {\n      \"address\": {\n        \"category\": \"company-profile\",\n        \"field\": \"companyRegNo\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"ssmIncorporatedDate\": {\n      \"disposition\": \"retired\",\n      \"note\": \"SUPERSEDED BY THE SHARED COLUMN and already dead. SYS-2722 (finsys-api 884b9078, 2026-07-09) consolidated company incorporation date onto the canonical incorporatedDate for BOTH extractors and backfilled history; processSSM has not written this column since. SYS-3163 (2026-08-04) later formalised the binding (WIDE_COLUMN_BINDINGS.companyIncorporationDate, owners [form9, ssm], no columnBySource override) but changed no behavior here. MEASURED on finsim: 839 of 8,475 rows carry ssmCompanyName (the same extractor's sibling, and the positive control that makes this zero meaningful) and 839 carry incorporatedDate, while ZERO carry ssmIncorporatedDate. The backfill COPIED rather than cleared, so rows predating 2026-07-09 still hold both \\u2014 the symptom is a field correct on older records and blank on newer ones, not a uniformly broken one. SEE SYS-3419: SYS-2722 scoped the reader half too and it never shipped.\",\n      \"via\": \"hand-authored\"\n    },\n    \"ssmPaidUpCapital\": {\n      \"address\": {\n        \"category\": \"company-profile\",\n        \"field\": \"paidUpCapital\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"state\": {\n      \"address\": {\n        \"category\": \"applicant-address\",\n        \"field\": \"addressStateCode\",\n        \"instanceKey\": \"permanent\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"statementDateT1\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"statementDate\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"statementDateT2\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"statementDate\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"statementDateT3\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"statementDate\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"statementDateT4\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"statementDate\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"statementDateT5\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"statementDate\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"statementDateT6\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"statementDate\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"statementType\": {\n      \"address\": {\n        \"category\": \"applicant-income\",\n        \"field\": \"statementType\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"status\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"statusDescription\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"subEmploymentSector\": {\n      \"address\": {\n        \"category\": \"applicant-employment\",\n        \"field\": \"subEmploymentSector\",\n        \"instanceKey\": \"current\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"supplementaryDoc\": {\n      \"address\": {\n        \"category\": \"document-intake\",\n        \"field\": \"pathInDms\",\n        \"instanceKeyPrefix\": \"supplementaryDoc\"\n      },\n      \"disposition\": \"mapped\",\n      \"note\": \"SHAPE CHANGE, not a rename. The v1 column held a JSON array of paths; document-intake keys one instance per file as <docType>#<sha256>, so this column becomes N instances.\",\n      \"via\": \"hand-authored\"\n    },\n    \"suspensionsCount24m\": {\n      \"address\": {\n        \"category\": \"telco-carrier\",\n        \"field\": \"suspensionsCount24m\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"tangibleAssets\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"tangibleAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"tangibleAssetsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"tangibleAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"tangibleAssetsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"tangibleAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"tangibleAssetsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"tangibleAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"taxesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"taxes\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"taxesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"taxes\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"taxesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"taxes\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"tenureMonths\": {\n      \"address\": {\n        \"category\": \"telco-carrier\",\n        \"field\": \"tenureMonths\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"tenureTier\": {\n      \"address\": {\n        \"category\": \"telco-carrier\",\n        \"field\": \"tenureTier\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"tnbBills\": {\n      \"address\": {\n        \"category\": \"document-intake\",\n        \"field\": \"pathInDms\",\n        \"instanceKeyPrefix\": \"tnbBills\"\n      },\n      \"disposition\": \"mapped\",\n      \"note\": \"SHAPE CHANGE, not a rename. The v1 column held a JSON array of paths; document-intake keys one instance per file as <docType>#<sha256>, so this column becomes N instances.\",\n      \"via\": \"hand-authored\"\n    },\n    \"tnbTariff\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"totalAssets\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"totalAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalAssetsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"totalAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalAssetsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"totalAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalAssetsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"totalAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalCreditsT1\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"totalCredits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalCreditsT2\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"totalCredits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalCreditsT3\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"totalCredits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalCreditsT4\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"totalCredits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalCreditsT5\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"totalCredits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalCreditsT6\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"totalCredits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalCurrentAssets\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"totalCurrentAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalCurrentAssetsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"totalCurrentAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalCurrentAssetsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"totalCurrentAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalCurrentAssetsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"totalCurrentAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalCurrentLiabilities\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"totalCurrentLiabilities\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalCurrentLiabilitiesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"totalCurrentLiabilities\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalCurrentLiabilitiesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"totalCurrentLiabilities\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalCurrentLiabilitiesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"totalCurrentLiabilities\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalDebitsT1\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"totalDebits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalDebitsT2\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"totalDebits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalDebitsT3\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"totalDebits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalDebitsT4\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"totalDebits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalDebitsT5\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"totalDebits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalDebitsT6\": {\n      \"address\": {\n        \"category\": \"finxtract-bank-statement\",\n        \"field\": \"totalDebits\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalEquityPriorYearT1\": {\n      \"disposition\": \"needs-decision\",\n      \"note\": \"the Vietnam financial-statement spec writes this PRIOR-YEAR comparative on the SAME row as totalEquityT1 (financialStatementSpecVN.ts, the same \\\"-(t-2)\\\" comparative-column pattern as netProfitPriorYear) -- not a second document, a second column on the first one. The registry declares no PriorYear field for totalEquity and the VN spec is not period-aware, so there is no address to resolve to yet. TWO candidate resolutions, an owner decides: (1) make the VN spec period-aware, so the comparative becomes period 2 of the SAME document and resolves like any other T-slot; or (2) declare a totalEquityPriorYear registry field. Until one ships, do not resolve this through the feeder branch that totalEquityT1 uses -- that silently returns the CURRENT-year value under this PRIOR-year name, which is what this override exists to stop.\",\n      \"via\": \"hand-authored\"\n    },\n    \"totalEquityPriorYearT2\": {\n      \"disposition\": \"needs-decision\",\n      \"note\": \"as totalEquityPriorYearT1 -- the same SAME-row VN comparative, one T-slot over. See that entry for the full finding; the two candidate resolutions are identical: make the VN spec period-aware, or declare totalEquityPriorYear as its own registry field.\",\n      \"via\": \"hand-authored\"\n    },\n    \"totalEquityPriorYearT3\": {\n      \"disposition\": \"needs-decision\",\n      \"note\": \"as totalEquityPriorYearT1 -- the same SAME-row VN comparative, one T-slot over. See that entry for the full finding; the two candidate resolutions are identical: make the VN spec period-aware, or declare totalEquityPriorYear as its own registry field.\",\n      \"via\": \"hand-authored\"\n    },\n    \"totalEquityT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"totalEquity\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalEquityT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"totalEquity\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalEquityT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"totalEquity\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalFinancing\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"totalLiabilitiesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"totalLiabilities\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalLiabilitiesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"totalLiabilities\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalLiabilitiesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"totalLiabilities\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalNonCurrentAssetsT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"totalNonCurrentAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalNonCurrentAssetsT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"totalNonCurrentAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalNonCurrentAssetsT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"totalNonCurrentAssets\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalNonCurrentLiabilitiesT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"totalNonCurrentLiabilities\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalNonCurrentLiabilitiesT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"totalNonCurrentLiabilities\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalNonCurrentLiabilitiesT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"totalNonCurrentLiabilities\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"totalShareIssued\": {\n      \"address\": {\n        \"category\": \"company-profile\",\n        \"field\": \"totalShareIssued\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"tradeReferenceDefaults12m\": {\n      \"address\": {\n        \"category\": \"trade-credit\",\n        \"field\": \"tradeReferenceDefaults12m\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"updatedAt\": {\n      \"disposition\": \"relocated\",\n      \"surface\": \"GET /lender/applications/:ihsId\",\n      \"via\": \"column-audit\"\n    },\n    \"updatedBy\": {\n      \"disposition\": \"withheld\",\n      \"reason\": \"NOT served by GET /lender/applications/:ihsId, deliberately: applicationRecordService removed it in review before publication, because publication is what makes an API permanent. v1 still serves it. There is no v2 destination \\u2014 the honest answer to \\\"where do I get this\\\" is \\\"nowhere, by design\\\", which `relocated` obscured.\",\n      \"via\": \"column-audit\"\n    },\n    \"vehicleCondition\": {\n      \"address\": {\n        \"category\": \"applicant-collateral\",\n        \"field\": \"vehicleConditionCode\",\n        \"instanceKey\": \"0\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"form-intake-fieldmap\"\n    },\n    \"verifiedBusinessAccount\": {\n      \"address\": {\n        \"category\": \"social-media\",\n        \"field\": \"verifiedBusinessAccount\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"name-equality\"\n    },\n    \"yearMake\": {\n      \"address\": {\n        \"category\": \"applicant-collateral\",\n        \"field\": \"vehicleYearMake\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"legacy-name\"\n    },\n    \"zakatT1\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"zakat\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"zakatT2\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"zakat\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    },\n    \"zakatT3\": {\n      \"address\": {\n        \"category\": \"financial-statement\",\n        \"field\": \"zakat\"\n      },\n      \"disposition\": \"mapped\",\n      \"via\": \"wide-column-feeder\"\n    }\n  },\n  \"schemaVersion\": \"0.3.0-draft\"\n}","/*\n * Copyright 2025 Sisters Inspire Sdn Bhd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * SYS-3414 — where every key of the v1 flat IHS response goes in v2.\n *\n * A consumer migrating off `GET /lender/ihs/:ihsId` has one question per key:\n * what do I read instead? This answers it for all 662, and it answers\n * \"nothing, and here is why\" for the ones with no destination — which is the\n * half a rename table would leave out and the half that loses data.\n *\n * WHAT THIS IS NOT. It is not a runtime shim and nothing reads it at request\n * time. It is a migration instrument: consumers read it once, while porting.\n * It goes away with the v1 surface.\n *\n * ─────────────────────────────────────────────────────────────────────────\n * THE FAILURE MODE IT WAS BUILT AGAINST, because it bit twice while it was\n * being built and both times the output looked finished.\n *\n * 1. An address that does not resolve. The first draft emitted 20 addresses\n *    naming fields the category does not declare — 18 invented outright, and\n *    2 from substring matching, one of which sent `tangibleAssets` to\n *    `nonCurrentAssetIntangibleAssets`: the opposite fact, spelled almost the\n *    same. All 20 were confidently formatted.\n *\n * 2. An address that resolves and is still wrong. Resolving proves a field\n *    EXISTS somewhere; it does not prove it is the RIGHT somewhere. 38 keys\n *    carried a field name declared by more than one category, and matching on\n *    name alone silently took whichever category came first in the JSON — it\n *    put `companyName` on `financial-statement`, and split one bank statement\n *    across two categories while its own siblings went to a third.\n *\n * So this map records HOW each address was derived, in `via`, and the test\n * beside it re-proves closure against the live registry on every run. The two\n * `via` values that mean \"somebody wrote this down\" are `wide-column-feeder`\n * and `form-intake-fieldmap`; `name-equality` means \"the names matched and\n * only one category declares it\", which is weaker and is why an ambiguous\n * name is refused rather than guessed.\n *\n * ─────────────────────────────────────────────────────────────────────────\n * A `mapped` entry is not a promise that data is there today. It is the\n * address. `mapped-pending-build` says the address is real and nothing writes\n * it yet — the field is declared, the table or the instance is not. Read\n * `retired` as \"this key has no v2 destination\", never as \"this data is\n * gone\": several retired keys are live data arriving under a different name\n * (`city` is submitted as `permanentcity`), and one, `ssmIncorporatedDate`,\n * is a dead column with live readers (SYS-3419).\n */\n\nimport raw from './data/v1-migration-map.json' with { type: 'json' };\n\n/** What happens to a v1 key in v2. */\nexport type V1Disposition =\n  /** One v2 address. Read it there. */\n  | 'mapped'\n  /** TWO attestors, one legacy column. v2 keeps both; the disagreement is the signal. */\n  | 'mapped-fanout'\n  /** The address is well-formed and nothing writes it yet. */\n  | 'mapped-pending-build'\n  /** Not adapter data — it moved to another surface, named in `surface`. */\n  | 'relocated'\n  /** v1 envelope machinery the v2 shape supersedes. */\n  | 'structural'\n  /** No v2 destination. NOT the same as \"the data is gone\" — read `note`. */\n  | 'retired'\n  /** A destination is wanted and no canonical field exists to be the destination. */\n  | 'vocabulary-gap'\n  /** More than one defensible destination; picking one needs an owner, not a lookup. */\n  | 'needs-decision'\n  /**\n   * SYS-3604 — v1 serves it, the v2 successor deliberately refuses it, and\n   * there is no other destination. Distinct from `relocated`, which promises\n   * a surface: six keys carried that promise naming an endpoint that had\n   * removed them in review, and `flatRecordFromView` quoted it back to the\n   * caller. The honest answer here is \"nowhere, by design\".\n   */\n  | 'withheld';\n\n/** How the address was derived. The first two are authored; the rest are weaker. */\nexport type V1ResolutionSource =\n  /** finsys-api's wideColumnFeeders.ts — which document category feeds the column. */\n  | 'wide-column-feeder'\n  /** A form-intake manifest's fieldMap — which form field produces the canonical one. */\n  | 'form-intake-fieldmap'\n  /** The category registry's own `legacyName` bridge. */\n  | 'legacy-name'\n  /** Names matched and exactly one category declares it. Refused when ambiguous. */\n  | 'name-equality'\n  /** The SYS-2499 column audit's NOT-ADAPTER classes. */\n  | 'column-audit'\n  /** The six-consumer sweep — a verdict no rule can derive. */\n  | 'consumer-sweep'\n  /** Authored against evidence cited in `note`. */\n  | 'hand-authored';\n\n/**\n * Where a value lives in v2.\n *\n * `instanceKey` names ONE instance. `instanceKeyPrefix` means the v1 key became\n * N instances and the reader must collect all of them — a shape change, not a\n * rename (a document-pointer column held a JSON array of paths; document-intake\n * keys one instance per file). AT MOST ONE OF THE TWO IS EVER PRESENT, and a\n * test asserts it, because an address carrying both would leave a consumer to\n * pick — and picking `instanceKey` on a fan-out silently reads one file of N.\n */\nexport interface V1Address {\n  readonly category: string;\n  readonly field: string;\n  readonly instanceKey?: string;\n  readonly instanceKeyPrefix?: string;\n}\n\nexport interface V1MigrationEntry {\n  readonly disposition: V1Disposition;\n  readonly via?: V1ResolutionSource;\n  /** Present on `mapped`, `mapped-pending-build`. */\n  readonly address?: V1Address;\n  /** Present on `mapped-fanout`, always length >= 2. */\n  readonly addresses?: ReadonlyArray<V1Address>;\n  /** Present on `relocated` — the surface that now serves this key. */\n  readonly surface?: string;\n  readonly note?: string;\n  readonly reason?: string;\n}\n\ninterface RawMap {\n  readonly schemaVersion: string;\n  readonly entries: Readonly<Record<string, V1MigrationEntry>>;\n}\n\nconst map = raw as unknown as RawMap;\n\nconst DISPOSITIONS: ReadonlySet<string> = new Set<V1Disposition>([\n  'mapped',\n  'mapped-fanout',\n  'mapped-pending-build',\n  'relocated',\n  'withheld',\n  'structural',\n  'retired',\n  'vocabulary-gap',\n  'needs-decision',\n]);\n\nlet validated = false;\n\n/**\n * The cast above is a claim, not a check — TypeScript verifies nothing about\n * imported JSON at runtime, so a map carrying a disposition outside the union\n * would type-check as exhaustive and then fall through every consumer's\n * `switch` as `undefined`. A key silently treated as having no destination is\n * the precise shape of loss this map exists to prevent.\n *\n * So it is checked, and checked LAZILY rather than at module load. Every\n * production consumer of this package imports it for the category registry and\n * never touches the migration map; an import-time throw would turn a bad data\n * file into a total outage for code that does not read the data. Validating on\n * first access puts the failure where the data is actually used, and costs one\n * pass over 662 entries the first time somebody asks.\n */\nfunction assertValidated(): void {\n  if (validated) return;\n  const bad: string[] = [];\n  for (const [key, entry] of Object.entries(map.entries)) {\n    if (!DISPOSITIONS.has(entry.disposition)) bad.push(`${key}: \"${entry.disposition}\"`);\n  }\n  if (bad.length > 0) {\n    throw new Error(\n      `v1-migration-map.json declares ${bad.length} unknown disposition(s), so this map cannot ` +\n        `be read safely: ${bad.slice(0, 5).join(', ')}${bad.length > 5 ? ', …' : ''}. ` +\n        `Regenerate it with scripts/build-v1-migration-map.py.`,\n    );\n  }\n  validated = true;\n}\n\n/** Draft until the v1 surface retires; the shape may still move. */\nexport const V1_MIGRATION_MAP_VERSION: string = map.schemaVersion;\n\n/** Every v1 response key this map accounts for. */\nexport function v1MigrationKeys(): ReadonlyArray<string> {\n  assertValidated();\n  return Object.keys(map.entries);\n}\n\n/** The disposition of one v1 key, or null if the map does not know it. */\nexport function v1MigrationEntry(key: string): V1MigrationEntry | null {\n  assertValidated();\n  return Object.prototype.hasOwnProperty.call(map.entries, key) ? map.entries[key]! : null;\n}\n\n/**\n * Every address a key resolves to — 0, 1, or (fanout) 2+.\n *\n * Returning an array rather than an optional single address is deliberate:\n * a caller that handles only the single case silently drops the second\n * attestor of a fanout key and reports one source's answer as \"the\" answer.\n */\nexport function v1Addresses(key: string): ReadonlyArray<V1Address> {\n  const e = v1MigrationEntry(key);\n  if (!e) return [];\n  if (e.addresses) return e.addresses;\n  return e.address ? [e.address] : [];\n}\n\n/** Keys sharing a disposition — for a consumer auditing its own reads. */\nexport function v1KeysByDisposition(d: V1Disposition): ReadonlyArray<string> {\n  assertValidated();\n  return Object.keys(map.entries).filter((k) => map.entries[k]!.disposition === d);\n}\n\n// ── Reverse lookup (SYS-3334) ────────────────────────────────────────\n\n/**\n * SYS-3334 F1 (round 2). The dispositions BOTH reverse bridges — `reverseIndex`\n * (backing `v1KeyForAddress`) and `legacyBaseNameIndex` (backing\n * `v1LegacyBaseNameOf`) — admit as carrying a real destination. Before this\n * constant existed the two were two independently-typed disposition checks\n * that happened to agree; they silently stopped agreeing the moment\n * `legacyBaseNameIndex` was written admitting only `'mapped'` while\n * `reverseIndex` already admitted `mapped-fanout` and `mapped-pending-build`\n * too. The gap was `incorporatedDate` (`mapped-fanout`, SYS-2722's two\n * attestors, `company-profile`/`company-registration`): `reverseIndex`\n * answered it, `legacyBaseNameIndex` answered null, and every SSM / Form 9\n * view-path row silently lost the \"Incorporated Date\" column despite the\n * value being right there in the view. One constant now backs both bridges\n * so they cannot disagree again — see `legacyBaseNameIndex`'s own comment\n * for why `mapped-pending-build` belongs here too (a label is right whether\n * or not the address is written yet).\n */\nconst REVERSIBLE_DISPOSITIONS: ReadonlySet<V1Disposition> = new Set<V1Disposition>([\n  'mapped',\n  'mapped-fanout',\n  'mapped-pending-build',\n]);\n\n/**\n * The reverse of `v1Addresses`: given a place on the canonical plane, the v1\n * key that used to hold it — or null.\n *\n * WHY IT EXISTS. The instance-shaped detail processor has to render a v2 view\n * with the labels and groupings the v1 panel had, or the flag flip on the\n * consumer is a redesign rather than a migration. Both label and grouping are\n * keyed by the LEGACY column name (the display-name catalogue and the form\n * spec), so the processor needs canonical → legacy. This map is the only\n * complete statement of that relationship: 771 keys, generated and proven.\n *\n * WHEN IT ANSWERS NULL, AND WHY THAT IS THE RIGHT ANSWER.\n *   - No v1 key ever held this address: a canonical-only field (the alt-data\n *     categories, or a registry field newer than the wide table). The caller\n *     falls back to the registry's own names.\n *   - More than one v1 key maps here with no instanceKey to tell them apart:\n *     the T-slot families (bankBalanceT1..T6 → closingBalance). Those are\n *     document-extraction fields, rendered by the file-field tables and never\n *     by the detail panel, so the ambiguity never reaches a caller that needs\n *     it resolved. Returning null rather than a guess is deliberate: a guess\n *     would label six documents' balances \"T1\".\n *\n * `instanceKey` matters: `contactValue` at `email` was `email`, at `mobile` was\n * `mobilePhoneNo`. An address without one matches only entries without one.\n */\nexport function v1KeyForAddress(\n  category: string,\n  field: string,\n  instanceKey?: string,\n): string | null {\n  const idx = reverseIndex();\n  const hits = idx.get(reverseKey(category, field, instanceKey));\n  return hits && hits.length === 1 ? hits[0]! : null;\n}\n\nfunction reverseKey(category: string, field: string, instanceKey?: string): string {\n  // NUL cannot appear in a category id, field name or instance key.\n  return `${category}\\u0000${field}\\u0000${instanceKey ?? ''}`;\n}\n\nlet reverse: Map<string, string[]> | null = null;\nlet keyedAddresses: Set<string> | null = null;\n\n/**\n * Whether the map holds ANY instance-keyed entry for (category, field). When it\n * does not, an instance key carries no discriminating power for that field and\n * a keyed lookup that misses may fall back to the keyless entry. When it does\n * (`contactValue`: email vs mobile), no such fallback is offered.\n */\nexport function v1AddressHasKeyedEntries(category: string, field: string): boolean {\n  reverseIndex();\n  return keyedAddresses!.has(`${category}\\u0000${field}`);\n}\n\nfunction reverseIndex(): Map<string, string[]> {\n  if (reverse) return reverse;\n  assertValidated();\n  const idx = new Map<string, string[]>();\n  const keyed = new Set<string>();\n  for (const [key, entry] of Object.entries(map.entries)) {\n    // The reverse question is \"what LABEL did this address carry\", and the\n    // label is right whether or not anything writes the address yet — so\n    // `mapped-pending-build` is admitted here (the forward lookup is where a\n    // not-yet-written destination is a wrong answer). Eleven addresses; the\n    // day they are written, they keep their v1 names instead of falling into\n    // General. `REVERSIBLE_DISPOSITIONS` — this bridge's disposition set and\n    // `legacyBaseNameIndex`'s must never diverge again; see that constant's doc.\n    if (!REVERSIBLE_DISPOSITIONS.has(entry.disposition)) continue;\n    for (const a of entry.addresses ?? (entry.address ? [entry.address] : [])) {\n      // A prefix address is a fan-out over N instances (document pointers);\n      // no single instance corresponds to the v1 key, so it is not reversible.\n      if (a.instanceKeyPrefix) continue;\n      const k = reverseKey(a.category, a.field, a.instanceKey);\n      const list = idx.get(k);\n      if (list) list.push(key);\n      else idx.set(k, [key]);\n      if (a.instanceKey !== undefined) keyed.add(`${a.category}\\u0000${a.field}`);\n    }\n  }\n  reverse = idx;\n  keyedAddresses = keyed;\n  return idx;\n}\n\n// ── Legacy base-name bridge (SYS-3334) ──────────────────────────────\n\n/**\n * The same T-slot suffix regex `scripts/build-v1-migration-map.py`'s own\n * PERIOD constant uses.\n *\n * The `(PriorYear)?` branch is UNREACHABLE here as of the map correction\n * (SYS-3334 round 2): the six `…PriorYearT{n}` keys (`netProfitPriorYearT1`,\n * …, `totalEquityPriorYearT3`) are now `needs-decision` — see\n * `scripts/build-v1-migration-map.py`'s `PRIOR_YEAR_COMPARATIVE` override and\n * this package's CHANGELOG — so no `mapped` / `mapped-fanout` /\n * `mapped-pending-build` key contains \"PriorYear\" for this regex to match\n * against. It stays literal-identical to the Python generator's PERIOD\n * constant rather than forking the two (the doc line above is the whole\n * point: one regex, read the same way in both places), and it regains a live\n * match the moment either candidate resolution ships a PriorYear key back\n * into `mapped`.\n */\nconst TIME_PERIOD_SUFFIX = /(PriorYear)?T[1-9]$/;\n\nfunction legacyBaseNameKey(category: string, field: string): string {\n  return category + '\u0000' + field;\n}\n\nlet legacyBaseNames: Map<string, string> | null = null;\n\n/**\n * Builds the (category, field) -> legacy BASE name index, lazily and once\n * (see `assertValidated`'s reasoning for why lazy: importing this module must\n * not throw for a consumer that never reads the map).\n *\n * SYS-3334 F1 (round 2 — CRITICAL, fixed here). This used to admit ONLY\n * `mapped` entries — a narrower set than `reverseIndex`'s (which already\n * admitted `mapped-fanout` and `mapped-pending-build`), and the two bridges\n * silently disagreeing is exactly the failure `REVERSIBLE_DISPOSITIONS`\n * exists to prevent (see its doc). The concrete casualty: `incorporatedDate`\n * is `mapped-fanout` (`company-profile`/`companyIncorporationDate` AND\n * `company-registration`/`companyIncorporationDate` — SYS-2722's two\n * attestors), so this index returned null for both addresses,\n * `instanceRowsFromView` `continue`d at the null, and the SSM / Form 9\n * instance rows silently lost the \"Incorporated Date\" column while the value\n * sat right there in the view. Now uses the SAME disposition set\n * `reverseIndex` does, so the two bridges cannot diverge again.\n *\n * A `mapped-fanout` entry contributes EVERY one of its `addresses`, not just\n * one — a fanout is two attestors of the SAME v1 key, and both attestors'\n * (category, field) pairs shared that key's base name in v1 (the wide column\n * held one value; either extractor could have written it).\n *\n * Restricted to addresses that carry neither `instanceKey` nor\n * `instanceKeyPrefix`. That is a DIFFERENT multiplicity from the one this\n * function bridges: several DISTINCT v1 keys landing on one (category, field)\n * because an INSTANCE tells them apart — `bankStatements`/`consentForm`/…\n * all onto `document-intake`/`pathInDms` (an instanceKeyPrefix each), or\n * `email`/`mobile`/`office`/`emergency` onto `applicant-contact`/\n * `contactValue` (an instanceKey each). Stripping a T-suffix from THOSE keys\n * would collide unrelated legacy names into one slot — `bankStatements` and\n * `consentForm` share no T-suffix to strip, so the naive index would record\n * two different \"base names\" for one address and throw on a case that is not\n * a defect at all. Excluding any address with an instance discriminator\n * leaves exactly the T-slot families (`bankBalanceT1..T6`, `revenueT1..T3`,\n * `incorporatedDate`'s two-attestor fanout, …) — verified empirically against\n * the live (post-F1, post-map-correction, post-SYS-3570) map: 620\n * instance-less addresses across `mapped` / `mapped-fanout` /\n * `mapped-pending-build`, converging to 253 distinct (category, field) bases,\n * 0 conflicts — the property this function relies on, and the conflict guard\n * below is what would catch a regression of it. (Was 616/252 before SYS-3570\n * gave the four `tangibleAssets*` keys an address; they share one base, so\n * they add four addresses and one base.)\n */\nfunction legacyBaseNameIndex(): Map<string, string> {\n  if (legacyBaseNames) return legacyBaseNames;\n  assertValidated();\n  const idx = new Map<string, string>();\n  for (const [key, entry] of Object.entries(map.entries)) {\n    if (!REVERSIBLE_DISPOSITIONS.has(entry.disposition)) continue;\n    const addrs = entry.addresses ?? (entry.address ? [entry.address] : []);\n    const baseName = key.replace(TIME_PERIOD_SUFFIX, '');\n    for (const addr of addrs) {\n      if (addr.instanceKey !== undefined || addr.instanceKeyPrefix !== undefined) continue;\n      const k = legacyBaseNameKey(addr.category, addr.field);\n      const existing = idx.get(k);\n      if (existing !== undefined && existing !== baseName) {\n        // A registry defect, not a data shape this function is meant to\n        // tolerate: two T-slot families at the SAME instance-less address\n        // disagreeing on their shared base name means the map (or the T-slot\n        // catalog entries it was built from) no longer agrees with itself.\n        // This is also the guard the brief calls out for a fanout whose TWO\n        // addresses disagree with each other — `addrs` is walked in the same\n        // loop, so a fanout entry hits this exact check across its own pair.\n        throw new Error(\n          `v1LegacyBaseNameOf(${addr.category}, ${addr.field}): two different legacy base names map here — ` +\n            `\"${existing}\" and \"${baseName}\" (from v1 key \"${key}\"). Regenerate the map with ` +\n            `scripts/build-v1-migration-map.py and check the T-slot catalog entries at this address.`,\n        );\n      }\n      idx.set(k, baseName);\n    }\n  }\n  legacyBaseNames = idx;\n  return idx;\n}\n\n/**\n * The T-suffix-stripped legacy name every `mapped` v1 key at this (category,\n * field) address shares — e.g. `finxtract-bank-statement`/`closingBalance` →\n * `bankBalance` (from `bankBalanceT1`..`bankBalanceT6`, all stripping to the\n * same base). This is the bridge `buildFileFieldTablesFromView` needs: it\n * feeds a `CanonicalView`'s values into `buildFileFieldTablesFromInstances`,\n * which is keyed by the legacy BASE column name, not the canonical one.\n *\n * Deliberately NOT `v1KeyForAddress`, which answers null on exactly this\n * T-slot case — it is answering a different question (\"which ONE v1 key was\n * this\"), and there is no single answer once a field has six T-slot\n * siblings. This function only needs the shared BASE, which (by construction\n * — see `legacyBaseNameIndex`'s comment) every slot in the family agrees on.\n *\n * Null when no instance-less REVERSIBLE v1 key (`mapped`, `mapped-fanout`, or\n * `mapped-pending-build` — the same set `legacyBaseNameIndex` admits, so this\n * function and `v1KeyForAddress` cannot disagree about which addresses have a\n * legacy name at all) ever held this (category, field) — a canonical-only\n * field: an alt-data category the wide table never had, or a registry field\n * newer than it (e.g. `financial-statement`/`consolidated`,\n * `financial-statement`/`localNo`). SYS-3334 F1 (round 2): this used to say\n * `mapped` only, which was wrong for exactly one case — `mapped-fanout` — and\n * that case was `incorporatedDate`, so this function answered null for a\n * field that very much had a wide column.\n */\nexport function v1LegacyBaseNameOf(category: string, field: string): string | null {\n  return legacyBaseNameIndex().get(legacyBaseNameKey(category, field)) ?? null;\n}\n\n// ── Fanout attestor index (SYS-3334 H-1, round 5) ────────────────────\n\nlet fanoutAddressCache: Map<string, { key: string; index: number }> | null = null;\n\n/**\n * Builds the (category, field) -> { fanout's own v1 key, address INDEX }\n * index, lazily and once — one entry per address of every `mapped-fanout`\n * entry (today: `incorporatedDate`'s two). `index` is the 0-based position\n * in the entry's OWN `addresses` array, the same order\n * `flatRecordFromView`'s `mapped-fanout` branch already treats as\n * authoritative (\"place the FIRST address, in map order, that has a value\").\n */\nfunction fanoutAddressIndex(): Map<string, { key: string; index: number }> {\n  if (fanoutAddressCache) return fanoutAddressCache;\n  assertValidated();\n  const idx = new Map<string, { key: string; index: number }>();\n  for (const [key, entry] of Object.entries(map.entries)) {\n    if (entry.disposition !== 'mapped-fanout') continue;\n    (entry.addresses ?? []).forEach((addr, index) => {\n      idx.set(legacyBaseNameKey(addr.category, addr.field), { key, index });\n    });\n  }\n  fanoutAddressCache = idx;\n  return idx;\n}\n\n/**\n * Whether (category, field) is one attestor of a `mapped-fanout` entry, and\n * if so its 0-based position in the map's own `addresses` order — null for\n * anything else (a plain `mapped` address, or no address at all).\n *\n * WHY IT EXISTS. `fieldProvenanceFromView` (`ihs-processing.ts`) has to tell\n * \"two DIFFERENT attestors of ONE fanout key disagreeing\" apart from \"two\n * instances of the SAME category colliding on one slot\" — SYS-2722 designed\n * the fanout so BOTH attestors survive (that is the whole point of a\n * two-address entry), so the first is not a collision at all; the second\n * is. This is the one piece of information that distinction needs, and it\n * did not exist anywhere in this module before H-1 — `v1LegacyBaseNameOf`\n * answers the shared BASE NAME both addresses resolve to, which is exactly\n * what makes the two writes LOOK like a collision (same key) without saying\n * whether they are one.\n */\nexport function v1FanoutAddressOf(category: string, field: string): { key: string; index: number } | null {\n  return fanoutAddressIndex().get(legacyBaseNameKey(category, field)) ?? null;\n}\n","{\n  \"accountHolderName\": \"Account Holder Name\",\n  \"statementDate\": \"Statement Date\",\n  \"bankName\": \"Bank Name\",\n  \"accountNumber\": \"Account Number\",\n  \"totalCredits\": \"Total Credits\",\n  \"totalDebits\": \"Total Debits\",\n  \"openingBalance\": \"Opening Balance\",\n  \"bankBalance\": \"Bank Balance\",\n  \"nonCurrentAssetsSubsidiaryCompanies\": \"Subsidiary Companies (Non-Current Assets)\",\n  \"nonCurrentAssetsAssociatedCompanies\": \"Associated Companies (Non-Current Assets)\",\n  \"nonCurrentAssetsDevelopmentPropertiesOrExpenditure\": \"Development Properties/Expenditure (Non-Current Assets)\",\n  \"nonCurrentAssetInvestmentProperties\": \"Investment Properties (Non-Current Assets)\",\n  \"nonCurrentAssetsInvestments\": \"Investments (Non-Current Assets)\",\n  \"nonCurrentAssetInvestmentSecurities\": \"Investment Securities (Non-Current Assets)\",\n  \"nonCurrentAssetDeferredAssets\": \"Deferred Assets (Non-Current Assets)\",\n  \"nonCurrentAssetDeposits\": \"Deposits (Non-Current Assets)\",\n  \"nonCurrentAssetOwnGoodwill\": \"Own Goodwill (Non-Current Assets)\",\n  \"nonCurrentAssetGoodwillOnConsolidation\": \"Goodwill on Consolidation (Non-Current Assets)\",\n  \"nonCurrentAssetSinkingFund\": \"Sinking Fund (Non-Current Assets)\",\n  \"nonCurrentAssetPropertyPlantEquipment\": \"Property, Plant & Equipment (Non-Current Assets)\",\n  \"nonCurrentAssetInventories\": \"Inventories (Non-Current Assets)\",\n  \"nonCurrentAssetRightOfUseAssets\": \"Right of Use Assets (Non-Current Assets)\",\n  \"nonCurrentAssetIntangibleAssets\": \"Intangible Assets (Non-Current Assets)\",\n  \"nonCurrentAssetPrepaidLeasePayments\": \"Prepaid Lease Payments (Non-Current Assets)\",\n  \"nonCurrentAssetFinancialAssetAtFairValue\": \"Financial Assets at Fair Value (Non-Current Assets)\",\n  \"nonCurrentAssetLandUseRight\": \"Land Use Rights (Non-Current Assets)\",\n  \"nonCurrentAssetTradeReceivables\": \"Trade Receivables (Non-Current Assets)\",\n  \"nonCurrentAssetOtherReceivables\": \"Other Receivables (Non-Current Assets)\",\n  \"nonCurrentAssetTradeAndOtherReceivables\": \"Trade and Other Receivables (Non-Current Assets)\",\n  \"nonCurrentAssetOtherReceivablesDepositsAndPrepayments\": \"Other Receivables, Deposits and Prepayments (Non-Current Assets)\",\n  \"totalNonCurrentAssets\": \"Total Non-Current Assets\",\n  \"currentAssetDevelopmentPropertiesOrExpenditure\": \"Development Properties/Expenditure (Current Assets)\",\n  \"currentAssetShortTermInvestments\": \"Short Term Investments (Current Assets)\",\n  \"currentAssetTradeDebtors\": \"Trade Debtors (Current Assets)\",\n  \"currentAssetShortTermDeposits\": \"Short Term Deposits (Current Assets)\",\n  \"currentAssetAmountDueFromHoldingCompany\": \"Amount Due from Holding Company (Current Assets)\",\n  \"currentAssetAmountDueFromSubsidiaryCompanies\": \"Amount Due from Subsidiary Companies (Current Assets)\",\n  \"currentAssetAmountDueFromAssociatedCompanies\": \"Amount Due from Associated Companies (Current Assets)\",\n  \"currentAssetAmountDueFromDirector\": \"Amount Due from Director (Current Assets)\",\n  \"currentAssetAmountDueFromCustomer\": \"Amount Due from Customer (Current Assets)\",\n  \"currentAssetAmountOwingByShareholders\": \"Amount Owing by Shareholders (Current Assets)\",\n  \"currentAssetInventories\": \"Inventories (Current Assets)\",\n  \"currentAssetFinancialAssetAtFairValue\": \"Financial Assets at Fair Value (Current Assets)\",\n  \"currentAssetLandUseRight\": \"Land Use Rights (Current Assets)\",\n  \"currentAssetTaxRecoverable\": \"Tax Recoverable (Current Assets)\",\n  \"currentAssetContractAssets\": \"Contract Assets (Current Assets)\",\n  \"currentAssetCurrentTaxAssets\": \"Current Tax Assets (Current Assets)\",\n  \"currentAssetPrepayments\": \"Prepayments (Current Assets)\",\n  \"currentAssetDerivative\": \"Derivatives (Current Assets)\",\n  \"currentAssetCashAndBankBalances\": \"Cash and Bank Balances (Current Assets)\",\n  \"currentAssetOtherReceivables\": \"Other Receivables (Current Assets)\",\n  \"currentAssetRestrictedCash\": \"Restricted Cash (Current Assets)\",\n  \"currentAssetCashAndCashEquivalents\": \"Cash and Cash Equivalents (Current Assets)\",\n  \"currentAssetDepositsCashAndBankBalances\": \"Deposits, Cash and Bank Balances (Current Assets)\",\n  \"currentAssetCashAtBanks\": \"Cash at Banks (Current Assets)\",\n  \"currentAssetCashOnHand\": \"Cash on Hand (Current Assets)\",\n  \"currentAssetDepositsAndPrepayments\": \"Deposits and Prepayments (Current Assets)\",\n  \"currentAssetTradeAndOtherReceivables\": \"Trade and Other Receivables (Current Assets)\",\n  \"currentAssetOtherReceivablesDepositsAndPrepayments\": \"Other Receivables, Deposits and Prepayments (Current Assets)\",\n  \"currentAssetOtherReceivablesAndDeposits\": \"Other Receivables and Deposits (Current Assets)\",\n  \"currentAssetOtherReceivablesAndPrepayments\": \"Other Receivables and Prepayments (Current Assets)\",\n  \"currentAssetCash\": \"Cash (Current Assets)\",\n  \"totalCurrentAssets\": \"Total Current Assets\",\n  \"totalAssets\": \"Total Assets\",\n  \"currentLiabilitiesTradeCreditors\": \"Trade Creditors (Current Liabilities)\",\n  \"currentLiabilitiesHirePurchasePayables\": \"Hire Purchase Payables (Current Liabilities)\",\n  \"currentLiabilitiesBankOverdraft\": \"Bank Overdraft (Current Liabilities)\",\n  \"currentLiabilitiesBankAcceptance\": \"Bank Acceptance (Current Liabilities)\",\n  \"currentLiabilitiesBorrowingsOrTermLoans\": \"Borrowings/Term Loans (Current Liabilities)\",\n  \"currentLiabilitiesBankborrowings\": \"Bank Borrowings (Current Liabilities)\",\n  \"currentLiabilitiesAmountsOwingToHoldingCompany\": \"Amounts Owing to Holding Company (Current Liabilities)\",\n  \"currentLiabilitiesAmountsOwingToSubsidiaryCompanies\": \"Amounts Owing to Subsidiary Companies (Current Liabilities)\",\n  \"currentLiabilitiesAmountOwingToAssociatedCompanies\": \"Amount Owing to Associated Companies (Current Liabilities)\",\n  \"currentLiabilitiesAmountsOwingToDirector\": \"Amounts Owing to Director (Current Liabilities)\",\n  \"currentLiabilitiesProvisionForTaxation\": \"Provision for Taxation (Current Liabilities)\",\n  \"currentLiabilitiesLeasePayables\": \"Lease Payables (Current Liabilities)\",\n  \"currentLiabilitiesFinanceLeasePayables\": \"Finance Lease Payables (Current Liabilities)\",\n  \"currentLiabilitiesOtherPayables\": \"Other Payables (Current Liabilities)\",\n  \"currentLiabilitiesDividendPayables\": \"Dividend Payables (Current Liabilities)\",\n  \"currentLiabilitiesTradeAndOtherPayables\": \"Trade and Other Payables (Current Liabilities)\",\n  \"currentLiabilitiesDepositsFromCustomers\": \"Deposits from Customers (Current Liabilities)\",\n  \"currentLiabilitiesOtherPayablesAccrualsAndDeposits\": \"Other Payables, Accruals and Deposits (Current Liabilities)\",\n  \"currentLiabilitiesOtherPayablesAndAccruals\": \"Other Payables and Accruals (Current Liabilities)\",\n  \"currentLiabilitiesContractLiabilities\": \"Contract Liabilities (Current Liabilities)\",\n  \"currentLiabilitiesDerivative\": \"Derivative Liabilities (Current Liabilities)\",\n  \"totalCurrentLiabilities\": \"Total Current Liabilities\",\n  \"shortTermLiabilities\": \"Short Term Liabilities\",\n  \"nonCurrentLiabilitiesBorrowingsOrTermLoans\": \"Borrowings/Term Loans (Non-Current Liabilities)\",\n  \"nonCurrentLiabilitiesBankBorrowings\": \"Bank Borrowings (Non-Current Liabilities)\",\n  \"nonCurrentLiabilitiesLeaseObligations\": \"Lease Obligations (Non-Current Liabilities)\",\n  \"nonCurrentLiabilitiesFinanceLeaseObligations\": \"Finance Lease Obligations (Non-Current Liabilities)\",\n  \"nonCurrentLiabilitiesDeferredTaxation\": \"Deferred Taxation (Non-Current Liabilities)\",\n  \"nonCurrentLiabilitiesRetirementBenefits\": \"Retirement Benefits (Non-Current Liabilities)\",\n  \"nonCurrentLiabilitiesHirePurchasePayables\": \"Hire Purchase Payables (Non-Current Liabilities)\",\n  \"nonCurrentLiabilitiesDepositsFromCustomers\": \"Deposits from Customers (Non-Current Liabilities)\",\n  \"nonCurrentLiabilitiesContractLiabilities\": \"Contract Liabilities (Non-Current Liabilities)\",\n  \"totalNonCurrentLiabilities\": \"Total Non-Current Liabilities\",\n  \"totalLiabilities\": \"Total Liabilities\",\n  \"tangibleAssets\": \"Tangible Assets\",\n  \"shareCapital\": \"Share Capital\",\n  \"preferenceShareCapital\": \"Preference Share Capital\",\n  \"sharePremium\": \"Share Premium\",\n  \"reserves\": \"Reserves\",\n  \"capitalReserves\": \"Capital Reserves\",\n  \"revaluationReserves\": \"Revaluation Reserves\",\n  \"exchangeEqualisationOrFluctuationReserves\": \"Exchange Equalisation/Fluctuation Reserves\",\n  \"retainedEarnings\": \"Retained Earnings\",\n  \"totalEquity\": \"Total Equity\",\n  \"revenue\": \"Revenue\",\n  \"costOfGoodsSold\": \"Cost of Goods Sold\",\n  \"grossProfit\": \"Gross Profit\",\n  \"otherIncome\": \"Other Income\",\n  \"profitFromOperations\": \"Profit from Operations\",\n  \"financeCost\": \"Finance Cost\",\n  \"ebitda\": \"Profit Before Tax\",\n  \"taxes\": \"Taxes\",\n  \"zakat\": \"Zakat\",\n  \"profitAfterTax\": \"Profit After Tax\",\n  \"netProfit\": \"Net Profit\",\n  \"netOperatingCashFlow\": \"Net Operating Cash Flow\",\n  \"depreciation\": \"Depreciation\",\n  \"depreciationOfPropertyPlantEquipment\": \"Depreciation of Property, Plant & Equipment\",\n  \"depreciationRightOfUseAssets\": \"Depreciation of Right of Use Assets\",\n  \"depreciationOfInvestmentProperties\": \"Depreciation of Investment Properties\",\n  \"depreciationOfInvestmentSecurities\": \"Depreciation of Investment Securities\",\n  \"endOfYearCash\": \"End of Year Cash\",\n  \"epfAccountHolderName\": \"Account Holder Name\",\n  \"epfAccountHolderAddress\": \"Account Holder Address\",\n  \"epfStatementYear\": \"Statement Year\",\n  \"epfKwspMemberNumber\": \"KWSP Member Number\",\n  \"epfIcNumber\": \"IC No.\",\n  \"epfEmployerNumber\": \"Employer Number\",\n  \"epfDateOfStatement\": \"Date Of Statement\",\n  \"epfTotalContribution\": \"Total Contribution\",\n  \"epfTotalCurrentContribution\": \"Total Current Contribution\",\n  \"payslipEmployerName\": \"Employer Name\",\n  \"payslipEmployeeName\": \"Employee Name\",\n  \"payslipPayPeriod\": \"Pay Period\",\n  \"payslipPayDate\": \"Pay Date\",\n  \"payslipGrossPay\": \"Gross Pay\",\n  \"payslipDeduction\": \"Deduction\",\n  \"payslipEmployeeEpfContribution\": \"Employee EPF Contribution\",\n  \"payslipEmployeeSocsoContribution\": \"Employee SOCSO Contribution\",\n  \"payslipNetPay\": \"Net Pay\",\n  \"incorporatedDate\": \"Incorporated Date\",\n  \"companyName\": \"Company Name\",\n  \"companyRegNo\": \"Company Registration No.\",\n  \"ssmCompanyName\": \"Company Name (SSM)\",\n  \"ssmCompanyRegNo\": \"Registration No. (SSM)\",\n  \"ssmCompanyEntityType\": \"Entity Type (SSM)\",\n  \"ssmPaidUpCapital\": \"Paid-Up Capital (SSM)\",\n  \"businessCommencementDate\": \"Business Commencement Date\",\n  \"businessNature\": \"Business Nature\",\n  \"companyStatus\": \"Company Status\",\n  \"shareholders\": \"Shareholders\",\n  \"directors\": \"Directors\",\n  \"previousDirectors\": \"Previous Directors\",\n  \"totalShareIssued\": \"Total Shares Issued\",\n  \"companyLastOldName\": \"Previous Company Name\",\n  \"companyNameDateOfChange\": \"Company Name Change Date\",\n  \"businessOrigin\": \"Business Origin\",\n  \"registeredAddress\": \"Registered Address\",\n  \"icName\": \"Name (IC)\",\n  \"icNumber\": \"IC Number\",\n  \"icAddress\": \"Address (IC)\",\n  \"icGender\": \"Gender (IC)\",\n  \"icReligion\": \"Religion (IC)\",\n  \"icDateOfBirth\": \"Date of Birth (IC)\",\n  \"icPlaceOfBirth\": \"Place of Birth (IC)\",\n  \"icNationality\": \"Nationality (IC)\",\n  \"icRace\": \"Race (IC)\"\n}\n","/*\n * IHS data processing functions.\n *\n * Pure data transformations for extracting structured detail and\n * file-field table data from raw IHS API responses. Used by both\n * finsys-client and finhub-adonisjs.\n */\n\nimport type { FieldData } from './survey-generator.js'\nimport {\n  IhsValueFormat,\n  FileFieldTableType,\n  isValidIhsFieldOrigin,\n} from './ihs-types.js'\nimport type {\n  IhsFieldDetail,\n  IhsDetailCategory,\n  FileFieldTableData,\n  FileFieldTableItem,\n  IhsFieldProvenance,\n  IhsFieldProvenanceWithOriginal,\n  IhsFieldOrigin,\n  DocumentRow,\n  DocumentFileMetadata,\n  InstanceRow,\n} from './ihs-types.js'\nimport { getBaseFieldSpecs, getBaseCategories, getBaseFieldSpecMap } from './catalogs.js'\nimport { getDocumentTypeGroups } from './document-types.js'\nimport { allCategories, assertAdapterCategory, type AdapterCategory } from './adapter-categories.js'\nimport {\n  v1Addresses,\n  v1KeyForAddress,\n  v1AddressHasKeyedEntries,\n  v1MigrationKeys,\n  v1MigrationEntry,\n  v1LegacyBaseNameOf,\n  v1FanoutAddressOf,\n} from './v1-migration-map.js'\nimport type { V1Address } from './v1-migration-map.js'\nimport type { CanonicalView, CanonicalInstance } from './canonical-view.js'\nimport type { TaggedFieldData } from './document-types.js'\nimport displayNamesData from './data/form-field-display-names.json' with { type: 'json' }\nimport { resolveDisplayCurrency } from './jurisdiction.js'\n\n// ── Display names ──────────────────────────────────────────────\n\nconst displayNames: Record<string, string> = displayNamesData as Record<string, string>\n\n/** Returns the full display name registry (extraction column → human label). */\nexport function getDisplayNames(): Record<string, string> {\n  return displayNames\n}\n\n/** Looks up a display name. Falls back to camelCase → Title Case conversion. */\nexport function getDisplayName(fieldName: string): string {\n  if (displayNames[fieldName]) return displayNames[fieldName]\n  return fieldName\n    .replace(/([A-Z])/g, ' $1')\n    .replace(/^./, (s) => s.toUpperCase())\n    .trim()\n}\n\n// ── Time-period utilities ──────────────────────────────────────\n\nconst TIME_PERIOD_REGEX = /T(\\d+)$/\n\nexport function extractTimePeriods(columnNames: string[]): string[] {\n  const periods = new Set<string>()\n  for (const col of columnNames) {\n    const match = TIME_PERIOD_REGEX.exec(col)\n    if (match) periods.add(`T${match[1]}`)\n  }\n  return [...periods].sort((a, b) => {\n    const numA = parseInt(a.slice(1), 10)\n    const numB = parseInt(b.slice(1), 10)\n    return numA - numB\n  })\n}\n\nexport function groupColumnsByTimePeriod(\n  columnNames: string[]\n): Record<string, Record<string, string>> {\n  const groups: Record<string, Record<string, string>> = {}\n  for (const col of columnNames) {\n    const match = /^(.+?)(T\\d+)$/.exec(col)\n    if (!match) continue\n    const [, baseName, period] = match\n    if (!groups[baseName]) groups[baseName] = {}\n    groups[baseName][period] = col\n  }\n  return groups\n}\n\n// ── Field grouping ─────────────────────────────────────────────\n\n/**\n * Groups fields by their catalog-declared document_group (falling back to\n * the field's own name for anything untagged). Was a hardcoded, closed\n * prefix-matching table (FIELD_GROUP_PREFIXES) requiring a code edit for\n * every new document type; now reads the same document_group tag the\n * catalog already carries for document-types.ts, so adding a document\n * type is a catalog-only data change.\n */\nexport function groupFieldsByPattern(fields: FieldData[]): Record<string, FieldData[]> {\n  const groups: Record<string, FieldData[]> = {}\n  for (const field of fields) {\n    if (!field.name) continue\n    const groupName = (field as TaggedFieldData).document_group ?? field.name\n    if (!groups[groupName]) groups[groupName] = []\n    groups[groupName].push(field)\n  }\n  return groups\n}\n\n/**\n * Human-friendly display names for field groups (when a group combines\n * multiple fields), derived from document-types.ts's catalog-backed\n * registry instead of a hardcoded map.\n */\nlet cachedGroupDisplayNames: Record<string, string> | null = null\n\nexport function getGroupDisplayNames(): Record<string, string> {\n  if (!cachedGroupDisplayNames) {\n    const names: Record<string, string> = {}\n    for (const group of getDocumentTypeGroups()) {\n      names[group.documentGroup] = group.label\n    }\n    cachedGroupDisplayNames = names\n  }\n  return cachedGroupDisplayNames\n}\n\n// ── File-field table building ──────────────────────────────────\n\n/**\n * SYS-3249: the set of canonical field names declared `kind: \"money\"`.\n *\n * `isNumericField` below is a 17-word substring match over the flat column\n * name, and it misses 51 of the 143 money fields — every `payslip*` amount,\n * `shareCapital`, `retainedEarnings`, every `*Payables`/`*Borrowings`\n * liability, all four `depreciation*`, `ebitda`, `zakat`, `ssmPaidUpCapital`.\n * Those simply never reached the numeric branch, so before this they merely\n * lost thousands separators.\n *\n * Once a value carries a denomination that stops being cosmetic: the\n * formatter would render `₫2,000,000` for a payslip's variable income (which\n * matches \"income\") beside a bare `15000000` for its gross pay (which matches\n * nothing) — in the same table, from the same document, in the same currency.\n * A bare number that looks authoritative is exactly what the currency exists\n * to prevent, so a partial rendering is worse than none.\n *\n * The category registry is the authority on what is money, so ask it rather\n * than extending the word list — a word list would drift from the vocabulary\n * the moment a category is added. No import cycle: adapter-categories.ts\n * imports nothing but its own JSON.\n */\nlet cachedMonetaryFieldNames: Set<string> | null = null\nfunction isMonetaryField(fieldName: string): boolean {\n  if (!cachedMonetaryFieldNames) {\n    // SYS-3333: BOTH spellings, and the legacy half is not optional.\n    //\n    // This function is handed a FLAT column name and matches it against\n    // CANONICAL names — which worked only while the two vocabularies were\n    // identical. The moment `payslipGrossPay` became `grossPay` canonically\n    // while the flat column kept its own name, the lookup missed and the\n    // value rendered as a bare number beside its denominated neighbours. No\n    // exception, no log line: exactly the silent degrade SYS-3249's\n    // denomination work exists to prevent, reintroduced by a rename.\n    //\n    // The legacy half is read off each field's own `legacyName`, so it cannot\n    // drift from the rename that created it, and it disappears with the flat\n    // columns at Phase 6.\n    cachedMonetaryFieldNames = new Set(\n      allCategories().flatMap((c) =>\n        c.fields\n          .filter((f) => f.kind === 'money')\n          .flatMap((f) => (f.legacyName ? [f.name, f.legacyName] : [f.name]))\n      )\n    )\n  }\n  return cachedMonetaryFieldNames.has(fieldName)\n}\n\nfunction isNumericField(fieldName: string): boolean {\n  const patterns = [\n    'balance',\n    'amount',\n    'credit',\n    'debit',\n    'total',\n    'revenue',\n    'cost',\n    'income',\n    'expense',\n    'liability',\n    'asset',\n    'equity',\n    'profit',\n    'loss',\n    'cash',\n    'tax',\n    'interest',\n  ]\n  const lower = fieldName.toLowerCase()\n  return patterns.some((p) => lower.includes(p))\n}\n\n/**\n * SYS-3249: `currency` is the ISO 4217 denomination of THIS value, read\n * from its provenance envelope — never from the field definition, and\n * never from a program-level default. It is optional, and absent means\n * \"unknown\", not \"MYR\": every pre-SYS-3249 row is absent, and defaulting\n * would render a VND amount as if it were ringgit, which is the exact\n * failure this carries a denomination to prevent.\n *\n * The two-fraction-digit default below is therefore kept ONLY for the\n * unknown case, where it preserves existing behaviour. When a currency IS\n * known the fraction digits come from the currency itself — VND is\n * zero-decimal, so 14,004,792,678,863 renders whole rather than gaining\n * two decimals that do not exist in the currency.\n *\n * The locale stays 'en-US' for now and governs only grouping/ordering,\n * not the decimal count. It becomes jurisdiction-driven under SYS-3258.\n */\n/**\n * SYS-3249: grouping, but NO invented decimals.\n *\n * This previously forced `minimumFractionDigits: 2` on everything that\n * reached the numeric branch. That is a claim about precision, and it is\n * wrong in two directions:\n *\n *  - Not every number here is money. `cashConversionCycleDays` rendered as\n *    \"45.00\" days and `totalShareIssued` as \"1,000,000.00\" shares.\n *  - Not every currency has two decimal places. VND and JPY have none, so a\n *    money value whose currency we do NOT know is exactly the value we have\n *    no basis to render with two decimals — and every row written before\n *    this change has no recorded currency.\n *\n * So the unknown case now groups and preserves what the value actually has,\n * rather than asserting a precision nobody supplied. Where the currency IS\n * known the formatter above is used instead, and the currency decides — which\n * is the only place that decision legitimately comes from.\n */\nconst PLAIN_NUMBER_FORMAT = new Intl.NumberFormat('en-US', {\n  maximumFractionDigits: 2,\n})\n\n/**\n * Formatters are cached because a 123-field financial statement across six\n * periods constructs ~730 of them per render, server-side on the IHS detail\n * path. Measured: ~22.5ms per 1000 construct+format vs ~0.2ms cached.\n * `null` caches a code Intl rejects, so a bad value costs one throw, not one\n * per cell.\n */\nconst currencyFormatters = new Map<string, Intl.NumberFormat | null>()\nfunction currencyFormatter(code: string): Intl.NumberFormat | null {\n  const cached = currencyFormatters.get(code)\n  if (cached !== undefined) return cached\n  let fmt: Intl.NumberFormat | null = null\n  try {\n    // `currencyDisplay: 'code'` rather than the default symbol, deliberately.\n    // Under en-US, USD renders as \"$\" while MYR/VND/THB/SGD render as codes —\n    // so the ONE currency that gets a bare glyph is the one whose glyph four\n    // other currencies also use. On a credit-bureau artifact read across\n    // jurisdictions that is the worst possible default. 'code' also makes the\n    // success and degraded paths agree on placement.\n    fmt = new Intl.NumberFormat('en-US', { style: 'currency', currency: code, currencyDisplay: 'code' })\n  } catch {\n    fmt = null\n  }\n  currencyFormatters.set(code, fmt)\n  return fmt\n}\n\n/**\n * SYS-3284/SYS-3285: the ONE money formatter the apps render through.\n *\n * FinHub and finsys-client each had their own. FinHub's hardcoded\n * `Intl.NumberFormat('en-MY', { currency: 'MYR' })` in the IHS views, so a\n * Vietnamese application's amounts read as ringgit. finsys-client had five\n * separate no-currency implementations plus two copy-pasted `myr()` helpers\n * that stamped \"RM\" unconditionally — including into the text fed to the AI\n * analyst, so the model reasoned about a Vietnamese company in ringgit.\n *\n * Both were reinventing something this package already did correctly for the\n * IHS detail path: a cached formatter using `currencyDisplay: 'code'`, which\n * matters more than it sounds — under en-US, USD renders as \"$\" while\n * MYR/VND/THB all render as codes, so symbol display gives a bare glyph to\n * the one currency whose glyph four others also use.\n *\n * Currency precedence is `resolveDisplayCurrency`'s: the value's own recorded\n * currency wins, then the jurisdiction's display default, then nothing — and\n * \"nothing\" prints a grouped number with no denomination, which is honest\n * rather than a guess.\n */\nexport function formatMoney(\n  value: unknown,\n  opts: {\n    currency?: string | null\n    /**\n     * REQUIRED, and deliberately not optional.\n     *\n     * `formatMoney(v, {})` used to return MYR — indistinguishable from\n     * `formatMoney(v, { jurisdiction: null })`, which is a different claim.\n     * `null` means \"a record said nothing, and the platform rule is\n     * Malaysia\"; an absent argument means \"I was never told\", and answering\n     * that with a confident MYR is the exact bug these helpers replace.\n     *\n     * Making the key required does not make the caller think harder — it\n     * makes the careless call fail to compile. Pass `NO_JURISDICTION_BASIS`\n     * when there is genuinely no basis; the result then carries no currency.\n     */\n    jurisdiction: string | null\n  }\n): string {\n  return formatValue(value, true, resolveDisplayCurrency(opts.currency, opts.jurisdiction))\n}\n\nfunction formatValue(value: unknown, numeric: boolean, currency?: string): string {\n  if (value === null || value === undefined || value === '') return '-'\n  if (numeric) {\n    const num = Number(value)\n    if (!isNaN(num)) {\n      if (currency) {\n        // Normalised before use: extraction output is exactly where stray\n        // whitespace and lowercase come from, and Intl rejects \" myr \" while\n        // accepting \"MYR\". Recovering those is free; leaving them to the\n        // degraded path renders a correct value as though it were suspect.\n        const code = currency.trim().toUpperCase()\n        const fmt = code ? currencyFormatter(code) : null\n        if (fmt) return fmt.format(num)\n        // Intl does not know this code. Degrade VISIBLY rather than either\n        // crashing the whole detail render for one bad field, or dropping the\n        // code and presenting a bare number that looks authoritative. Code\n        // first, matching the success path.\n        return `${code || currency} ${PLAIN_NUMBER_FORMAT.format(num)}`\n      }\n      return PLAIN_NUMBER_FORMAT.format(num)\n    }\n  }\n  return String(value)\n}\n\nfunction buildTableForGroup(\n  groupName: string,\n  fields: FieldData[],\n  ihsData: Record<string, unknown>,\n  fieldProvenance?: Record<string, IhsFieldProvenance>\n): FileFieldTableData | null {\n  const allColumns: string[] = []\n  for (const field of fields) {\n    if (field.ihs_column_names) {\n      allColumns.push(...field.ihs_column_names)\n    }\n  }\n  if (allColumns.length === 0) return null\n\n  const periods = extractTimePeriods(allColumns)\n  const isTimeSeries = periods.length > 0\n  const tableType = isTimeSeries ? FileFieldTableType.TIME_SERIES : FileFieldTableType.KEY_VALUE\n  const groupDisplayName =\n    getGroupDisplayNames()[groupName] || fields[0]?.displayName || getDisplayName(groupName)\n\n  if (isTimeSeries) {\n    const columnGroups = groupColumnsByTimePeriod(allColumns)\n    const items: FileFieldTableItem[] = []\n\n    for (const [baseName, periodMap] of Object.entries(columnGroups)) {\n      const numeric = isNumericField(baseName) || isMonetaryField(baseName)\n      const data: Record<string, unknown> = {}\n      const formattedData: Record<string, string> = {}\n      const confidence: Record<string, number> = {}\n      const provenance: Record<string, IhsFieldProvenance> = {}\n\n      for (const period of periods) {\n        const colName = periodMap[period]\n        const value = colName ? (ihsData[colName] ?? null) : null\n        data[period] = value\n        // SYS-2741: colName is the exact ihs_field_metadata key (incl. T{n} suffix).\n        // SYS-3249: resolved BEFORE formatting — the envelope carries this\n        // value's currency, so the formatter needs it in hand.\n        const prov = colName ? fieldProvenance?.[colName] : undefined\n        formattedData[period] = formatValue(value, numeric, prov?.currency)\n        if (prov) {\n          provenance[period] = prov\n          if (\n            prov.origin === 'extracted' &&\n            typeof prov.confidence === 'number' &&\n            !Number.isNaN(prov.confidence)\n          ) {\n            confidence[period] = prov.confidence\n          }\n        }\n      }\n\n      items.push({\n        displayName: getDisplayName(baseName),\n        timePeriods: periods,\n        data,\n        formattedData,\n        type: tableType,\n        isNumeric: numeric,\n        ...(Object.keys(confidence).length ? { confidence } : {}),\n        ...(Object.keys(provenance).length ? { provenance } : {}),\n      })\n    }\n\n    const hasData = items.some((item) =>\n      Object.values(item.data).some((v) => v !== null && v !== undefined && v !== '')\n    )\n    return { name: groupName, displayName: groupDisplayName, type: tableType, items, hasData }\n  } else {\n    const items: FileFieldTableItem[] = []\n    for (const colName of allColumns) {\n      const value = ihsData[colName] ?? null\n      const numeric = isNumericField(colName) || isMonetaryField(colName)\n      // SYS-2741: single-doc columns (ssmCompanyName, companyName, icName, …) are\n      // keyed directly in ihs_field_metadata — lit up here (the value-match interim\n      // had to skip these because filename-based OCR lookup was unreliable).\n      const prov = fieldProvenance?.[colName]\n      items.push({\n        displayName: getDisplayName(colName),\n        timePeriods: [],\n        data: { value },\n        formattedData: { value: formatValue(value, numeric, prov?.currency) },\n        type: tableType,\n        isNumeric: numeric,\n        ...(prov &&\n        prov.origin === 'extracted' &&\n        typeof prov.confidence === 'number' &&\n        !Number.isNaN(prov.confidence)\n          ? { confidence: { value: prov.confidence } }\n          : {}),\n        ...(prov ? { provenance: { value: prov } } : {}),\n      })\n    }\n    const hasData = items.some((item) => {\n      const v = item.data['value']\n      return v !== null && v !== undefined && v !== ''\n    })\n    return { name: groupName, displayName: groupDisplayName, type: tableType, items, hasData }\n  }\n}\n\nexport function buildFileFieldTables(\n  ihsData: Record<string, unknown>,\n  fieldProvenance?: Record<string, IhsFieldProvenance>\n): Record<string, FileFieldTableData> {\n  const specs = getBaseFieldSpecs()\n  const fileFields = specs.filter((f) => f.type === 'file' && f.ihs_column_names?.length)\n  const grouped = groupFieldsByPattern(fileFields)\n\n  const tables: Record<string, FileFieldTableData> = {}\n  for (const [groupName, fields] of Object.entries(grouped)) {\n    const table = buildTableForGroup(groupName, fields, ihsData, fieldProvenance)\n    if (table && table.hasData) {\n      tables[groupName] = table\n    }\n  }\n  return tables\n}\n\n// ── Instance-based field grouping (SYS-2886 / Phase 5) ──────────\n//\n// The catalog's T{n}-suffixed columns (bankBalanceT1..T6) declare a FIXED\n// cardinality per category -- at most 6 bank statements, 3 financial-year\n// slots, etc (buildFileFieldTables/groupColumnsByTimePeriod above are\n// bound to that fixed declaration). groupColumnsByInstance is the\n// unbounded counterpart: it takes the RAW sibling-table rows finsys-api\n// now exposes per category (SYS-2842's docInstanceStorageService -- one\n// row per uploaded document, keyed by a real instanceKey, not a\n// pre-declared T{n} slot) and groups them by base metric name, with one\n// column per ROW rather than per pre-declared period.\n//\n// Deliberately requires NO new catalog entries: every T{n} slot for a\n// given category declares the identical base column names (verified\n// across bank_statement_t1..t6 and the analogous financial/epf/payslip\n// entries), so the base names are derived by stripping the existing\n// suffixed specs' ihs_column_names rather than duplicating them in the\n// catalog. The 129 T{n}-suffixed wide-table columns and their catalog\n// entries stay exactly as they are (frozen, not migrated, per the\n// epic's Phase 6 scope) -- this is purely additive.\n\n/**\n * Human label for one instance column: \"Mar 2026 · Maybank\" when a\n * sourceLabel is known, else the bare period/instanceKey.\n */\nfunction instanceColumnLabel(row: InstanceRow): string {\n  const period = row.timePeriod || row.instanceKey\n  return row.sourceLabel ? `${period} · ${row.sourceLabel}` : period\n}\n\n/**\n * Adversarial-review finding (Phase 5): instanceColumnLabel is NOT\n * collision-free -- two distinct rows (distinct instanceKey) can share\n * the same timePeriod + sourceLabel (e.g. two same-bank, same-month\n * statements, or any row lacking sourceLabel that shares a period).\n * Since every consumer keys data/confidence/provenance BY this label\n * (matching FileFieldTableItem's existing contract, where timePeriods'\n * entries are literal object keys into `data`), an undisambiguated\n * collision doesn't just look wrong -- it silently drops one row's\n * value entirely (last-write-wins into the same object key) while\n * `timePeriods` keeps a duplicate entry pointing at the SURVIVING row's\n * value twice. Disambiguates by appending \"(2)\", \"(3)\", ... to every\n * occurrence after the first, keeping the common (non-colliding) case's\n * label exactly as before. Both groupColumnsByInstance and\n * buildInstanceTable call this SAME function on the SAME instanceRows\n * array (never the raw per-row instanceColumnLabel directly), so the\n * two independently-computed label lists always agree with each other.\n */\nfunction instanceColumnLabels(rows: InstanceRow[]): string[] {\n  const seenCounts = new Map<string, number>()\n  return rows.map((row) => {\n    const raw = instanceColumnLabel(row)\n    const occurrence = (seenCounts.get(raw) ?? 0) + 1\n    seenCounts.set(raw, occurrence)\n    return occurrence === 1 ? raw : `${raw} (${occurrence})`\n  })\n}\n\n/**\n * Groups instance rows by base metric name -- the unbounded analog of\n * groupColumnsByTimePeriod. `baseColumnNames` is the category's base\n * (unsuffixed) field list; each returned group maps instance column\n * label -> that metric's value on that row. Labels are disambiguated\n * (see instanceColumnLabels) so two rows can never collide into the\n * same key.\n */\nexport function groupColumnsByInstance(\n  baseColumnNames: string[],\n  instanceRows: InstanceRow[]\n): Record<string, Record<string, unknown>> {\n  const groups: Record<string, Record<string, unknown>> = {}\n  for (const baseName of baseColumnNames) {\n    groups[baseName] = {}\n  }\n  if (!instanceRows?.length) return groups\n  const labels = instanceColumnLabels(instanceRows)\n  instanceRows.forEach((row, i) => {\n    const label = labels[i]\n    for (const baseName of baseColumnNames) {\n      if (Object.prototype.hasOwnProperty.call(row, baseName)) {\n        groups[baseName][label] = row[baseName]\n      }\n    }\n  })\n  return groups\n}\n\n/**\n * Instance-based counterpart to buildFileFieldTables: builds one table\n * per category present in `instancesByCategory`, with one column per\n * instance row (unbounded) instead of one column per pre-declared T{n}\n * slot. Categories absent from `instancesByCategory` are simply skipped\n * -- callers merge this output with buildFileFieldTables' own (or use it\n * standalone once a category has fully cut over).\n *\n * Provenance stays keyed the legacy way (`${baseName}${timePeriod}`, per\n * the epic's established SYS-2842 rule that @finsys/core's exact-string\n * lookup can't change format without a coordinated release) -- so only\n * instances whose timePeriod maps onto a legacy T{n} slot carry a\n * confidence dot; instances beyond that (the very capability this\n * function exists for) simply render with no confidence, same limitation\n * buildFileFieldTables already has today for anything past T6.\n */\nfunction buildInstanceTable(\n  groupName: string,\n  baseNames: string[],\n  groupDisplayName: string,\n  instanceRows: InstanceRow[],\n  fieldProvenance?: Record<string, IhsFieldProvenance>\n): FileFieldTableData | null {\n  const columnGroups = groupColumnsByInstance(baseNames, instanceRows)\n  const instanceLabels = instanceColumnLabels(instanceRows)\n\n  const items: FileFieldTableItem[] = []\n  for (const [baseName, labelMap] of Object.entries(columnGroups)) {\n    const hasAny = Object.values(labelMap).some((v) => v !== null && v !== undefined && v !== '')\n    if (!hasAny) continue\n\n    const numeric = isNumericField(baseName) || isMonetaryField(baseName)\n    const data: Record<string, unknown> = {}\n    const formattedData: Record<string, string> = {}\n    const confidence: Record<string, number> = {}\n    const provenance: Record<string, IhsFieldProvenance> = {}\n\n    for (const [i, row] of instanceRows.entries()) {\n      const label = instanceLabels[i]\n      const value = labelMap[label] ?? null\n      data[label] = value\n\n      const legacyKey = row.timePeriod ? `${baseName}${row.timePeriod}` : undefined\n      // SYS-3249: hoisted above the format call — the envelope carries\n      // this value's currency.\n      const prov = legacyKey ? fieldProvenance?.[legacyKey] : undefined\n      formattedData[label] = formatValue(value, numeric, prov?.currency)\n      if (prov) {\n        provenance[label] = prov\n        if (\n          prov.origin === 'extracted' &&\n          typeof prov.confidence === 'number' &&\n          !Number.isNaN(prov.confidence)\n        ) {\n          confidence[label] = prov.confidence\n        }\n      }\n    }\n\n    items.push({\n      displayName: getDisplayName(baseName),\n      timePeriods: instanceLabels,\n      data,\n      formattedData,\n      type: FileFieldTableType.TIME_SERIES,\n      isNumeric: numeric,\n      ...(Object.keys(confidence).length ? { confidence } : {}),\n      ...(Object.keys(provenance).length ? { provenance } : {}),\n    })\n  }\n\n  const hasData = items.some((item) =>\n    Object.values(item.data).some((v) => v !== null && v !== undefined && v !== '')\n  )\n  if (!items.length || !hasData) return null\n\n  return {\n    name: groupName,\n    displayName: groupDisplayName,\n    type: FileFieldTableType.TIME_SERIES,\n    items,\n    hasData,\n  }\n}\n\n/**\n * Explicit base-column declaration for a category with NO catalog `file`\n * spec -- e.g. invoice (SYS-2842 Phase 3), which was deliberately never\n * registered in form-field-base-specs.json because getDocumentTypeGroups()\n * is shared with resolveExtractionStatus, which assumes a category's wide-\n * table columns exist to check \"is this populated\" against -- invoice has\n * none (sibling-table only, no wideTableMirror). Registering it there would\n * silently break resolveExtractionStatus's invoice status reporting. This\n * override lets a category be instance-rendered without entering that\n * shared registry at all.\n */\nexport interface CategorySpec {\n  displayName: string\n  baseColumnNames: string[]\n}\n\nexport function buildFileFieldTablesFromInstances(\n  instancesByCategory: Record<string, InstanceRow[]> = {},\n  fieldProvenance?: Record<string, IhsFieldProvenance>,\n  categoryOverrides?: Record<string, CategorySpec>\n): Record<string, FileFieldTableData> {\n  const specs = getBaseFieldSpecs()\n  const fileFields = specs.filter((f) => f.type === 'file' && f.ihs_column_names?.length)\n  const grouped = groupFieldsByPattern(fileFields)\n\n  const tables: Record<string, FileFieldTableData> = {}\n\n  for (const [groupName, fields] of Object.entries(grouped)) {\n    const instanceRows = instancesByCategory[groupName]\n    if (!instanceRows?.length) continue\n\n    const baseNames = new Set<string>()\n    for (const field of fields) {\n      for (const col of field.ihs_column_names ?? []) {\n        baseNames.add(col.replace(TIME_PERIOD_REGEX, ''))\n      }\n    }\n    const groupDisplayName =\n      getGroupDisplayNames()[groupName] || fields[0]?.displayName || getDisplayName(groupName)\n\n    const table = buildInstanceTable(\n      groupName, [...baseNames], groupDisplayName, instanceRows, fieldProvenance\n    )\n    if (table) tables[groupName] = table\n  }\n\n  for (const [groupName, spec] of Object.entries(categoryOverrides ?? {})) {\n    if (Object.prototype.hasOwnProperty.call(tables, groupName)) continue // catalog-derived takes precedence\n    const instanceRows = instancesByCategory[groupName]\n    if (!instanceRows?.length) continue\n\n    const table = buildInstanceTable(\n      groupName, spec.baseColumnNames, spec.displayName, instanceRows, fieldProvenance\n    )\n    if (table) tables[groupName] = table\n  }\n\n  return tables\n}\n\n// ── Documents table (SYS-2766) ─────────────────────────────────\n//\n// Presentation-agnostic model of the per-document table on the IHS detail page.\n// Absorbs the doc-type maps/rules FinHub used to own inline so FinHub and\n// finsys-client render the SAME table. Pure transform: file metadata is attached\n// upstream by finsys-api (the `documentMetadata` sibling map, SYS-2765).\n\n/** IHS doc-field key → human label. Its keys drive which fields become sections. */\nconst DOC_DISPLAY_NAMES: Record<string, string> = {\n  bankStatements: 'Bank Statements',\n  financialStatements: 'Financial Statements',\n  form9: 'Form 9',\n  epfStatements: 'EPF Statements',\n  payslips: 'Payslips',\n  // SYS-3376: a host pointer slot (extraction: true) the catalog never named —\n  // an uploaded invoice rendered in NEITHER product. The slot list is owned by\n  // the host (finsys-api IHS_DOCUMENT_POINTER_FIELDS); the host carries the\n  // comparator that every slot is named here.\n  invoices: 'Invoices',\n  ssm: 'SSM Company Profile',\n  ic: 'Identity Card',\n  ssm_registration_documents: 'Form 9',\n  ic_documents: 'Identity Documents (Supplementary)',\n  consentForm: 'Consent Form',\n  supplementaryDoc: 'Supplementary Documents',\n  coreIncomeDoc: 'Core Income Document',\n  incomeSupportingDoc: 'Income Supporting Document',\n  incomeEPF_iakaun: 'EPF i-Akaun',\n  photocopyRegistrationCard: 'Registration Card',\n  bankStatementOrSavingPassbook: 'Bank Passbook',\n  tnbBills: 'TNB Bills',\n}\n\n/** Doc types finsys-api can run extraction on (→ re-extract / view-JSON eligible). */\nconst EXTRACTABLE_DOC_TYPES = new Set<string>([\n  'bankStatements',\n  'financialStatements',\n  'form9',\n  'epfStatements',\n  'payslips',\n  'invoices',\n  'ssm',\n  'ic',\n  'ssm_registration_documents',\n  'ic_documents',\n])\n\n/** Doc types that accept a replacement upload (SYS-2229 — finsys-api ignores the rest). */\nconst REUPLOADABLE_DOC_TYPES = new Set<string>(['bankStatements', 'financialStatements'])\n\n/** IHS doc-field key → human label (the fields that become document sections). */\nexport function getDocDisplayNames(): Record<string, string> {\n  return DOC_DISPLAY_NAMES\n}\n\n/** Doc types eligible for extraction (re-extract / view-JSON). */\nexport function getExtractableDocTypes(): Set<string> {\n  return EXTRACTABLE_DOC_TYPES\n}\n\n/** Doc types eligible for a replacement upload. */\nexport function getReuploadableDocTypes(): Set<string> {\n  return REUPLOADABLE_DOC_TYPES\n}\n\n/** Heuristic: does a string look like an opaque id (UUID / long hex), not a real name? */\nfunction isProbablyId(str?: string | null): boolean {\n  if (!str) return false\n  const clean = str.split('.')[0] // ignore extension\n  if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(clean)) return true\n  if (/^[0-9a-f]{32,128}$/i.test(clean)) return true\n  return false\n}\n\n/**\n * One entry inside a document-pointer field.\n *\n * EXPORTED as of SYS-3174, and that is the point of exporting it. The host is\n * about to attest these entries as canonical `document-intake` rows, and the\n * alternative to naming the shape here was for it to declare a private copy —\n * which is precisely how this codebase ended up with seven hand-written,\n * mutually-disagreeing lists of \"the document fields\". Every property is\n * optional because every one of them is genuinely absent on some real row;\n * this describes what is STORED, not what is required.\n */\nexport interface ParsedDocFile {\n  path?: string\n  fileName?: string\n  documentId?: string\n  fileSize?: number | string\n  fileType?: string\n  createdAt?: string\n  month?: number\n  year?: number\n  /**\n   * SYS-2873: the uploader's per-file document-language choice (e.g. \"vi\",\n   * \"en\"), present only for slots whose catalog entry carries\n   * document_language_options. Selects the extraction endpoint upstream;\n   * absent on every Malaysia upload.\n   */\n  documentLanguage?: string\n  /**\n   * SYS-3174: who uploaded this file — the acting principal, not the subject\n   * the document is about.\n   *\n   * The one genuine gap in this shape. It had no declaration anywhere in this\n   * package, while one upload route wrote it ad hoc into a single column's\n   * entries — so for every other document the answer was unrecoverable rather\n   * than merely missing. Declared here so the next writer finds the spelling\n   * instead of inventing a second one.\n   *\n   * Absent on every entry written before that route existed; a consumer must\n   * treat \"no uploader recorded\" as a real and common state, never as a\n   * defect.\n   */\n  uploadedBy?: string\n}\n\n/**\n * Parse one IHS doc field into file entries. Handles the shapes the field takes:\n * a JSON-array string (bank/financial/…, possibly inline-enriched like\n * supplementaryDoc), an already-parsed array, or a bare URL string (ssm/form9/ic).\n */\nexport function parseFileField(value: unknown): ParsedDocFile[] {\n  if (!value) return []\n  if (Array.isArray(value)) return value as ParsedDocFile[]\n  if (typeof value === 'string') {\n    try {\n      const parsed = JSON.parse(value)\n      return Array.isArray(parsed) ? (parsed as ParsedDocFile[]) : []\n    } catch {\n      // Plain URL string (form9, ssm, ic) — wrap as a single entry.\n      if (value.startsWith('http')) {\n        return [{ path: value, documentId: value.split('/').pop() || undefined }]\n      }\n      return []\n    }\n  }\n  return []\n}\n\nfunction toBytes(value: unknown): number | null {\n  if (typeof value === 'number') return Number.isNaN(value) ? null : value\n  if (typeof value === 'string') {\n    const n = parseInt(value, 10)\n    return Number.isNaN(n) ? null : n\n  }\n  return null\n}\n\n/**\n * Build the presentation-agnostic document rows for an IHS. Reads the doc fields\n * named in DOC_DISPLAY_NAMES + the `documentMetadata` sibling map (SYS-2765) and\n * emits a flat DocumentRow[] (all sections, in DOC_DISPLAY_NAMES order). Metadata\n * is taken inline off the entry first (supplementaryDoc is enriched inline), then\n * from `documentMetadata[path]`.\n */\nexport function buildDocumentRows(ihsData: Record<string, unknown>): DocumentRow[] {\n  const metaMap = (ihsData.documentMetadata ?? {}) as Record<string, DocumentFileMetadata>\n  const rows: DocumentRow[] = []\n\n  for (const docType of Object.keys(DOC_DISPLAY_NAMES)) {\n    const files = parseFileField(ihsData[docType])\n    if (files.length === 0) continue\n\n    const label = DOC_DISPLAY_NAMES[docType]\n    const extractable = EXTRACTABLE_DOC_TYPES.has(docType)\n    const reUploadable = extractable && REUPLOADABLE_DOC_TYPES.has(docType)\n\n    files.forEach((file, index) => {\n      const path = file.path ?? null\n      const meta = path ? metaMap[path] : undefined\n\n      const documentId = file.documentId || (path ? path.split('/').pop() || null : null)\n      const timePeriod = file.month ? `T${file.month}` : file.year ? `T${file.year}` : 'ALL'\n\n      const rawName = file.fileName ?? meta?.fileName ?? undefined\n      const fileName = rawName && !isProbablyId(rawName) ? rawName : null\n\n      const rawExt = (rawName ?? '').split('.').pop()\n      const ext =\n        rawExt && rawExt.length <= 5 && !isProbablyId(rawExt) ? rawExt.toUpperCase() : null\n      const mime = file.fileType ?? meta?.fileType\n      const fileType = ext || (mime?.split('/').pop()?.toUpperCase() ?? null)\n\n      const fileSize = toBytes(file.fileSize) ?? meta?.fileSize ?? null\n      const uploadedAt = file.createdAt ?? meta?.createdAt ?? null\n\n      const periodLabel =\n        file.month && file.year\n          ? new Date(file.year, file.month - 1).toLocaleDateString('en-MY', {\n              year: 'numeric',\n              month: 'short',\n            })\n          : file.year\n            ? `Year ${file.year}`\n            : null\n\n      const displayName =\n        fileName ||\n        (periodLabel\n          ? `${label} — ${periodLabel}`\n          : files.length > 1\n            ? `${label} ${index + 1}`\n            : label)\n\n      rows.push({\n        docType,\n        label,\n        index,\n        displayName,\n        documentId,\n        path,\n        timePeriod,\n        periodLabel,\n        fileName,\n        fileType,\n        fileSize,\n        uploadedAt,\n        capabilities: {\n          download: !!documentId,\n          viewJson: extractable,\n          reExtract: extractable,\n          reUpload: reUploadable,\n        },\n      })\n    })\n  }\n\n  return rows\n}\n\n// ── Documents-table cell formatters (empty-state rules live here) ──\n// Single source for the Type / Size / Uploaded strings so FinHub + finsys-client\n// render identical cells (em-dash on unknown).\n\nconst EM_DASH = '—'\n\n/** Type column: the resolved type label, or em-dash. */\nexport function formatDocumentType(row: Pick<DocumentRow, 'fileType'>): string {\n  return row.fileType ?? EM_DASH\n}\n\n/** Size column: human bytes (B / KB / MB), or em-dash when unknown. */\nexport function formatDocumentSize(bytes: number | null | undefined): string {\n  if (!bytes || Number.isNaN(bytes)) return EM_DASH\n  if (bytes < 1024) return `${bytes} B`\n  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`\n  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n}\n\n/** Uploaded column: the upload date, else the period label, else em-dash. */\nexport function formatDocumentUploaded(\n  row: Pick<DocumentRow, 'uploadedAt' | 'periodLabel'>\n): string {\n  if (row.uploadedAt) {\n    const d = new Date(row.uploadedAt)\n    if (!Number.isNaN(d.getTime())) {\n      return d.toLocaleDateString('en-MY', { year: 'numeric', month: 'short', day: 'numeric' })\n    }\n  }\n  return row.periodLabel ?? EM_DASH\n}\n\n// ── IHS detail processing ──────────────────────────────────────\n\nfunction isFileOrFinancialColumn(fieldName: string, fileColumnSet: Set<string>): boolean {\n  return (\n    fileColumnSet.has(fieldName) ||\n    fieldName.startsWith('financials') ||\n    fieldName.startsWith('bank_statement')\n  )\n}\n\n\n/**\n * SYS-3259: money-ness is DERIVED from the registry, not listed here. A legacy\n * name resolves through the migration map to a canonical field, and the\n * registry says whether that field's `kind` is `money`. That is 471 v1 keys;\n * the hand-written set this replaces named four, so `monthlyNetIncome`,\n * `purchasePriceOTR` and every other money field rendered as a plain string.\n *\n * THE RESIDUAL, named for what it is. The ticket's premise — \"Phase 2.6 makes\n * this a deletion\" — held for ONE of the four names. `totalFinancing` is\n * `relocated` (the application record) and `approvedAmount` /\n * `monthlyInstallment` are not adapter fields at all; none has a registry\n * entry to derive from. They stay, as the application record's currency\n * fields, until that record carries its own field spec (SYS-3379 / SYS-3412).\n * A test pins that this set contains ONLY names the registry cannot answer.\n */\nexport const APPLICATION_RECORD_CURRENCY_FIELDS: ReadonlySet<string> = new Set([\n  'totalFinancing',\n  'approvedAmount',\n  'monthlyInstallment',\n])\n\nlet moneyLegacyNames: Set<string> | null = null\n\n/** Every v1 key whose canonical destination the registry declares as money. */\nexport function registryMoneyLegacyNames(): ReadonlySet<string> {\n  if (moneyLegacyNames) return moneyLegacyNames\n  const money = new Set<string>()\n  for (const cat of allCategories()) {\n    for (const f of cat.fields) if (f.kind === 'money') money.add(`${cat.id}|${f.name}`)\n  }\n  const names = new Set<string>()\n  for (const key of v1MigrationKeys()) {\n    if (v1Addresses(key).some((a) => money.has(`${a.category}|${a.field}`))) names.add(key)\n  }\n  moneyLegacyNames = names\n  return names\n}\n\nfunction inferValueFormat(fieldName: string, value: unknown): IhsValueFormat {\n  if (APPLICATION_RECORD_CURRENCY_FIELDS.has(fieldName) || registryMoneyLegacyNames().has(fieldName)) {\n    return IhsValueFormat.CURRENCY\n  }\n\n  const numberFields = new Set([\n    'age',\n    'noOfDependants',\n    'financingTenure',\n    'ihsId',\n    'programId',\n    'borrowerAgentId',\n  ])\n  if (numberFields.has(fieldName)) return IhsValueFormat.NUMBER\n\n  const tableFields = new Set(['shareholders', 'directors', 'previousDirectors'])\n  if (tableFields.has(fieldName)) return IhsValueFormat.TABLE\n\n  if (typeof value === 'string' && /^\\d{4}-\\d{2}-\\d{2}/.test(value)) return IhsValueFormat.DATE\n\n  return IhsValueFormat.STRING\n}\n\nconst EXCLUDED_FIELDS = new Set([\n  'updatedAt',\n  'programIds',\n  'borrowerAgentId',\n  'programId',\n  '__v',\n  '_id',\n  'id',\n])\n\nexport function processIhsDetails(ihsData: Record<string, unknown>): IhsFieldDetail[] {\n  const specs = getBaseFieldSpecs()\n  const fileColumnSet = new Set<string>()\n  for (const field of specs) {\n    if (field.type === 'file') {\n      if (field.name) fileColumnSet.add(field.name)\n      if (field.ihs_column_names) {\n        for (const col of field.ihs_column_names) {\n          fileColumnSet.add(col)\n        }\n      }\n    }\n  }\n\n  const specMap = getBaseFieldSpecMap()\n  const categories = getBaseCategories()\n  const categoryNameMap: Record<string, string> = {}\n  for (const cat of categories) {\n    categoryNameMap[String(cat.id)] = cat.name\n  }\n\n  const details: IhsFieldDetail[] = []\n\n  for (const [key, value] of Object.entries(ihsData)) {\n    if (value === null || value === undefined || value === '' || value === 'Not Specified') continue\n    if (value === false) continue\n    if (EXCLUDED_FIELDS.has(key)) continue\n    if (isFileOrFinancialColumn(key, fileColumnSet)) continue\n\n    const spec = specMap.get(key)\n    const categoryId = spec?.category ? String(spec.category) : '0'\n    const category = categoryNameMap[categoryId] || 'General'\n\n    details.push({\n      name: key,\n      displayName: getDisplayName(key),\n      category,\n      value,\n      valueFormat: inferValueFormat(key, value),\n    })\n  }\n\n  return details\n}\n\nexport function groupDetailsByCategory(details: IhsFieldDetail[]): IhsDetailCategory[] {\n  const groups: Record<string, IhsFieldDetail[]> = {}\n  for (const detail of details) {\n    if (!groups[detail.category]) groups[detail.category] = []\n    groups[detail.category].push(detail)\n  }\n\n  return Object.entries(groups)\n    .filter(([cat]) => cat !== 'Default Category' && cat !== 'General')\n    .map(([category, items]) => ({\n      category,\n      items: items.map((d) => ({\n        name: d.name,\n        displayName: d.displayName,\n        value: d.value,\n        valueFormat: d.valueFormat,\n      })),\n    }))\n}\n\n// ── Instance-shaped detail processing (SYS-3334) ────────────────────\n\n/**\n * `processIhsDetails` for a v2 `CanonicalView` — the same output type, the\n * same labels, the same groupings, so a consumer flipping from v1 to v2 sees\n * the panel it had. That parity is the point of an instance-shaped PATH rather\n * than a new panel: the flag flip on finhub is a migration, not a redesign,\n * and it can be checked against a before-picture (`groupDetailsByCategory` of\n * both, on the same subject).\n *\n * HOW PARITY IS ACHIEVED. v1 keyed everything — display name, form-spec\n * category, value format — by the LEGACY column name. This function walks the\n * view (category → instance → field) and asks the v1 migration map, in\n * reverse, which legacy key held each address. Where the map answers, the\n * detail is emitted exactly as v1 would have emitted it. Where it does not —\n * a canonical-only field the wide table never had — the detail is emitted\n * under the canonical name and, having no form spec, lands in `General`,\n * which `groupDetailsByCategory` drops. THAT TOO IS PARITY: v1's flat record\n * carried alt-data keys with no form spec (`arpu`, …), they landed in\n * `General`, and the panel never showed them. A consumer that wants those\n * reads the view directly; this function is the detail panel, not the view.\n *\n * WHAT IS EXCLUDED, AND WHY IT IS DERIVED RATHER THAN LISTED. v1 skipped the\n * file/financial columns because `buildFileFieldTables` renders them. The v2\n * equivalents are the extraction categories of every document type plus\n * `document-intake` — derived from the document-type groups through the map,\n * so a new document type excludes itself. A hand-written list here would be\n * the seventh copy of \"which fields are document fields\" in this estate.\n *\n * VALUE FILTER is v1's exactly (null / '' / 'Not Specified' / false skipped),\n * applied to the envelope's `value`. Provenance on the envelope is not\n * surfaced here — `IhsFieldDetail` has no slot for it, and adding one is a\n * type change every consumer would inherit; that is its own decision.\n *\n * Dropping `false` is INHERITED v1 behavior, not a rule this function\n * chose — and it is no longer hypothetical now that boolean-typed registry\n * fields exist (`telco-carrier.handsetFinancingActive`,\n * `social-media.verifiedBusinessAccount`, `financial-statement.consolidated`):\n * a lender cannot tell \"false\" from \"never asked\" in either panel. Left\n * unchanged here because parity with the flat path IS the contract and the\n * flat path drops it too; whether `false` should render is a product\n * decision, not a bug in this processor.\n */\n/**\n * L-2 (round 5): the v1 sentinel values this detail panel skips — `null`,\n * `undefined`, `''`, `'Not Specified'`, `false`. Named as its own function so\n * `valueAtPlainAddress`'s multi-instance pick (below) can share the EXACT\n * rule rather than growing its own copy that could silently drift from what\n * a reviewer actually sees rendered here.\n */\nfunction isSentinelValue(value: unknown): boolean {\n  return value === null || value === undefined || value === '' || value === 'Not Specified' || value === false\n}\n\nexport function processIhsDetailsFromView(view: CanonicalView): IhsFieldDetail[] {\n  const excluded = documentCategoryIds()\n  const specMap = getBaseFieldSpecMap()\n  const categoryNameMap: Record<string, string> = {}\n  for (const cat of getBaseCategories()) categoryNameMap[String(cat.id)] = cat.name\n\n  const details: IhsFieldDetail[] = []\n\n  for (const [categoryId, category] of Object.entries(view.categories)) {\n    if (excluded.has(categoryId as AdapterCategory)) continue\n    // Scoped per category: a name can only collide with another of the same\n    // category (the reverse map is injective across categories except for a\n    // fan-out key, and both fan-out categories are documents).\n    const seen = new Set<string>()\n    for (const instance of category.instances ?? []) {\n      for (const [field, envelope] of Object.entries(instance.fields)) {\n        const value = envelope.value\n        if (isSentinelValue(value)) continue\n\n        // The keyed lookup first. If it misses AND the map holds no keyed\n        // entry for this (category, field) at all, the key carries no\n        // discriminating power — a single-cardinality category whose adapter\n        // wrote 'default' or '' — so the keyless entry is the answer. This\n        // rule does not depend on `cardinality`, which the API omits when no\n        // manifest is reachable for the producing adapter.\n        const legacy =\n          v1KeyForAddress(categoryId, field, instance.instanceKey || undefined) ??\n          (v1AddressHasKeyedEntries(categoryId, field) ? null : v1KeyForAddress(categoryId, field))\n\n        // The name a v1 consumer keyed on, when there was one. Otherwise a name\n        // that cannot collide with a legacy key or with another instance's.\n        let name = legacy ?? canonicalDetailName(categoryId, field, instance.instanceKey)\n        let displayName = getDisplayName(legacy ?? field)\n        if (seen.has(name)) {\n          // Two instances of one category resolving to one name: two producers\n          // writing the same key (the registry allows several vendors per\n          // alt-data category). Not a reason to fail a page render, and not a\n          // reason to hide one — a disagreement between producers is exactly\n          // what a reviewer should see. The second keeps the same group, under\n          // a name that cannot collide and a label that says whose value it is.\n          const base = `${canonicalDetailName(categoryId, field, instance.instanceKey)}@${instance.adapterId}`\n          const baseDisplay = `${displayName} (${instance.adapterId})`\n          name = base\n          displayName = baseDisplay\n          // A third (or further) producer sharing the SAME (instanceKey,\n          // adapterId, field) collides on the disambiguated name too — it is\n          // never itself checked against `seen`. Number it until unique; this\n          // loop, not the disambiguation above, is what makes uniqueness hold\n          // for N > 2 producers.\n          let n = 2\n          while (seen.has(name)) {\n            name = `${base}#${n}`\n            displayName = `${baseDisplay} #${n}`\n            n++\n          }\n        }\n        seen.add(name)\n\n        const spec = legacy !== null ? specMap.get(legacy) : undefined\n        const categoryKey = spec?.category ? String(spec.category) : '0'\n\n        details.push({\n          name,\n          displayName,\n          category: categoryNameMap[categoryKey] || 'General',\n          value,\n          valueFormat: inferValueFormat(legacy ?? field, value),\n        })\n      }\n    }\n  }\n  return details\n}\n\nfunction canonicalDetailName(categoryId: string, field: string, instanceKey: string): string {\n  return instanceKey ? `${categoryId}/${instanceKey}/${field}` : `${categoryId}/${field}`\n}\n\nlet documentCategoryIdsCache: Set<AdapterCategory> | null = null\n\n/**\n * The adapter categories that hold DOCUMENT data — every document type's\n * extraction category (via the migration map: the type's legacy T-slot columns\n * → the category they map into) plus `document-intake` (the pointers). Derived,\n * not listed. A type whose columns map into two categories throws. A type whose\n * columns map NOWHERE (the map is frozen at the v1 surface, so any document\n * type added after it) resolves to null and would NOT be excluded here — that\n * case is caught by the test that pins the seven types by name, not by this\n * function; adding a document type means deciding its extraction category\n * there.\n */\nexport function documentCategoryIds(): ReadonlySet<AdapterCategory> {\n  if (documentCategoryIdsCache) return documentCategoryIdsCache\n  const ids = new Set<AdapterCategory>([assertAdapterCategory('document-intake')])\n  for (const group of getDocumentTypeGroups()) {\n    const target = extractionCategoryOf(group.documentType)\n    if (target) ids.add(target)\n  }\n  documentCategoryIdsCache = ids\n  return ids\n}\n\nconst extractionCategoryCache = new Map<string, AdapterCategory | null>()\n\n/**\n * Which adapter category carries the EXTRACTED values for a document type —\n * `bankStatements` → `finxtract-bank-statement`, `ssm` → `company-profile`.\n * Read off the migration map: the type's legacy extraction columns (the form\n * spec's `ihs_column_names`) and where they went.\n *\n * INTERSECTION, NOT UNION, across the columns. A fan-out key is attested by\n * more than one category — `incorporatedDate` (SYS-2722) by company-profile\n * from the SSM document AND by company-registration from Form 9 — so a single\n * column can name two categories and still be right. The category a document\n * type EXTRACTS INTO is the one every one of its mapped columns names: for\n * Form 9 that is company-registration ({cp,cr} ∩ {cr} ∩ {cr}); for SSM it is\n * company-profile. Unmapped columns do not vote. Null when nothing is mapped.\n * Throws when the intersection is empty or has two members, because then\n * \"the\" extraction category does not exist and every caller would pick one\n * silently.\n */\nexport function extractionCategoryOf(documentType: string): AdapterCategory | null {\n  if (extractionCategoryCache.has(documentType)) return extractionCategoryCache.get(documentType)!\n  const group = getDocumentTypeGroups().find((g) => g.documentType === documentType)\n  const votes: Array<Set<string>> = []\n  for (const field of group?.fields ?? []) {\n    for (const col of field.ihs_column_names ?? []) {\n      const cats = new Set<string>(v1Addresses(col).map((a) => a.category))\n      if (cats.size > 0) votes.push(cats)\n    }\n  }\n  const common = votes.length === 0\n    ? null\n    : votes.reduce((acc, cats) => new Set<string>([...acc].filter((c) => cats.has(c))))\n  if (common !== null && common.size !== 1) {\n    throw new Error(\n      `extractionCategoryOf(${documentType}): its mapped columns agree on ${common.size} categories ` +\n        `(${[...common].join(', ') || 'none'}); the migration map or the registry is inconsistent.`,\n    )\n  }\n  const result = common === null ? null : assertAdapterCategory([...common][0]!)\n  extractionCategoryCache.set(documentType, result)\n  return result\n}\n\n// ── Instance-shaped document rows (SYS-3378) ─────────────────────────\n\n/**\n * `buildDocumentRows` for a v2 `CanonicalView`. Same `DocumentRow[]`, same\n * grouping and order (DOC_DISPLAY_NAMES), same capabilities — read from the\n * `document-intake` instances instead of the wide pointer columns. This is\n * the Phase 6 blocker SYS-3378 names: until this exists, dropping a pointer\n * column blanks the documents table in both products.\n *\n * WHICH DOCUMENTS. Every `document-intake` instance whose `documentType` is a\n * type the table shows, in intake order — UNIONED with any document the\n * extraction categories know that intake does not (an upload predating the\n * intake writer; measured 1 of 1323 on the sim). The same union, in the same\n * order, that `resolveExtractionStatusFromView` walks, so a consumer aligning\n * status to rows by (docType, index) still can; and both now carry the\n * document hash as `documentId`, so it can join by identity instead.\n *\n * WHAT MOVED. `uploadedAt` comes from the intake instance's own `uploadedAt`\n * field, else its `observedAt` — the attestation IS the upload — with the\n * consumer-supplied `metadata` map (the `documentMetadata` sibling, keyed by\n * path) consulted first, exactly as v1 did, for fileName / fileType /\n * fileSize when the consumer has it. `uploadedBy` is read off the instance.\n *\n * WHAT DID NOT SURVIVE, said plainly. v1's `periodLabel` came from `month` /\n * `year` on the pointer entry, and in practice was the slot ordinal\n * (\"Year 1\", \"Year 2\") for financial statements and null elsewhere. Intake\n * instances carry no period, so `timePeriod` is 'ALL' and `periodLabel` is\n * null; the display name falls back to \"<label> <n>\" as v1's did for every\n * other type. The period a statement covers is a FACT about its content and\n * belongs on the extraction instance (`financialYearEnd`), not on the upload.\n */\nexport function buildDocumentRowsFromView(\n  view: CanonicalView,\n  metadata?: Record<string, DocumentFileMetadata>,\n): DocumentRow[] {\n  const metaMap = metadata ?? {}\n  const rows: DocumentRow[] = []\n  const intake = view.categories['document-intake']?.instances ?? []\n\n  for (const docType of Object.keys(DOC_DISPLAY_NAMES)) {\n    const label = DOC_DISPLAY_NAMES[docType]!\n    const extractable = EXTRACTABLE_DOC_TYPES.has(docType)\n    const reUploadable = extractable && REUPLOADABLE_DOC_TYPES.has(docType)\n\n    const documents = documentsOfType(view, intake, docType)\n    documents.forEach((doc, index) => {\n      const path = doc.path\n      const meta = path ? metaMap[path] : undefined\n      const documentId = doc.hash ?? (path ? path.split('/').pop() || null : null)\n\n      const rawName = meta?.fileName ?? undefined\n      const fileName = rawName && !isProbablyId(rawName) ? rawName : null\n      const rawExt = (rawName ?? '').split('.').pop()\n      const ext = rawExt && rawExt.length <= 5 && !isProbablyId(rawExt) ? rawExt.toUpperCase() : null\n      const mime = meta?.fileType\n      const fileType = ext || (mime?.split('/').pop()?.toUpperCase() ?? null)\n      const fileSize = meta?.fileSize ?? null\n      const uploadedAt = meta?.createdAt ?? doc.uploadedAt ?? null\n\n      rows.push({\n        docType,\n        label,\n        index,\n        displayName: fileName || (documents.length > 1 ? `${label} ${index + 1}` : label),\n        documentId,\n        path,\n        timePeriod: 'ALL',\n        periodLabel: null,\n        fileName,\n        fileType,\n        fileSize,\n        uploadedAt,\n        ...(doc.uploadedBy ? { uploadedBy: doc.uploadedBy } : {}),\n        capabilities: {\n          download: !!documentId,\n          viewJson: extractable,\n          reExtract: extractable,\n          reUpload: reUploadable,\n        },\n      })\n    })\n  }\n  return rows\n}\n\n/** One document the view knows about, from intake, from extraction, or both. */\nexport interface ViewDocument {\n  /** The DMS content hash — the join key across intake, extraction and status. Null when neither side carries one. */\n  hash: string | null\n  path: string | null\n  uploadedAt: string | null\n  uploadedBy: string | null\n  /** The extraction instances for this document (period rows grouped), possibly none. */\n  extraction: ReadonlyArray<CanonicalInstance>\n  /**\n   * 'intake' — an intake instance names this document (upload order, and the\n   * only rows a positional job record may be aligned to). 'extraction-only' —\n   * no intake row: a pre-writer upload, or a join miss between an intake path\n   * and an extraction key. Both are real; the second must stay observable.\n   */\n  origin: 'intake' | 'extraction-only'\n}\n\n/**\n * The documents of one type, in the order both instance-shaped functions use:\n * intake instances first (upload order), then any extracted document no\n * intake instance accounts for. Shared by `buildDocumentRowsFromView` and\n * `resolveExtractionStatusFromView` so their (docType, index) alignment is a\n * property of one function, not a coincidence of two.\n */\nexport function documentsOfType(\n  view: CanonicalView,\n  intake: ReadonlyArray<CanonicalInstance>,\n  docType: string,\n): ViewDocument[] {\n  const category = extractionCategoryOf(docType)\n  const extracted = category !== null ? (view.categories[category]?.instances ?? []) : []\n  const byHash = new Map<string, CanonicalInstance[]>()\n  const legacyByOrdinal = new Map<number, CanonicalInstance[]>()\n  for (const inst of extracted) {\n    const h = documentHashOfKey(inst.instanceKey)\n    if (h === null) {\n      const n = legacyOrdinalOfKey(inst.instanceKey)\n      if (n === null) continue // no identity and no slot: nothing to attribute it to\n      const list = legacyByOrdinal.get(n)\n      if (list) list.push(inst)\n      else legacyByOrdinal.set(n, [inst])\n      continue\n    }\n    const list = byHash.get(h)\n    if (list) list.push(inst)\n    else byHash.set(h, [inst])\n  }\n  const out: ViewDocument[] = []\n  const claimed = new Set<string>()\n  for (const inst of intake) {\n    if (inst.fields.documentType?.value !== docType) continue\n    const path = stringOrNull(inst.fields.pathInDms?.value)\n    const hash = path ? documentHashOfPath(path) : null\n    const extraction = hash !== null ? (byHash.get(hash) ?? []) : []\n    if (hash !== null && extraction.length > 0) claimed.add(hash)\n    out.push({\n      hash,\n      path,\n      uploadedAt: stringOrNull(inst.fields.uploadedAt?.value) ?? inst.observedAt ?? null,\n      uploadedBy: stringOrNull(inst.fields.uploadedBy?.value),\n      extraction,\n      origin: 'intake',\n    })\n  }\n  const intakeCount = out.length\n  for (const [hash, group] of byHash) {\n    if (!claimed.has(hash)) out.push({ hash, path: null, uploadedAt: null, uploadedBy: null, extraction: group, origin: 'extraction-only' })\n  }\n  // Legacy slot rows: positional, as v1 was — `legacy:T{n}` is the n-th\n  // INTAKE document's extraction, but only when that document has no hashed\n  // extraction (a hashed run for the same document supersedes its legacy\n  // duplicate). A slot beyond the intake documents is an extraction-only\n  // document with no identity: a pre-writer subject whose uploads left no\n  // intake row, still rendered, still counted, marked as such.\n  for (const n of [...legacyByOrdinal.keys()].sort((a, b) => a - b)) {\n    const group = legacyByOrdinal.get(n)!\n    const target = n >= 1 && n <= intakeCount ? out[n - 1]! : undefined\n    if (target && target.extraction.length === 0) out[n - 1] = { ...target, extraction: group }\n    else if (!target) out.push({ hash: null, path: null, uploadedAt: null, uploadedBy: null, extraction: group, origin: 'extraction-only' })\n    // else: the target already has hashed extraction — the legacy rows are its superseded duplicate.\n  }\n  return out\n}\n\n/**\n * The document identity inside an extraction instance key:\n * `bankStatement:<hash>` → `<hash>`, `financialStatement:<hash>#T2` → `<hash>`.\n * A key with no colon is its own identity. The `#…` tail is the per-document\n * period discriminator and is not part of the identity.\n *\n * NULL for a `legacy:T{n}` key. Those rows were written by the pre-hash path\n * — one per T-slot of the wide table, no document behind them — and on the sim\n * they are the ONLY extraction rows for 143 financial-statement subjects and\n * 33 bank-statement subjects. They carry no identity; `legacyOrdinalOfKey`\n * carries the one thing they do know, their slot.\n */\nexport function documentHashOfKey(instanceKey: string): string | null {\n  if (LEGACY_KEY.test(instanceKey)) return null\n  const colon = instanceKey.indexOf(':')\n  const afterColon = colon === -1 ? instanceKey : instanceKey.slice(colon + 1)\n  const hashAt = afterColon.indexOf('#')\n  const id = hashAt === -1 ? afterColon : afterColon.slice(0, hashAt)\n  return id === '' ? null : id\n}\n\nconst LEGACY_KEY = /^legacy:T(\\d+)$/\n\n/** `legacy:T3` → 3; null for any other key. The slot ordinal is 1-based, as the wide table's was. */\nexport function legacyOrdinalOfKey(instanceKey: string): number | null {\n  const m = LEGACY_KEY.exec(instanceKey)\n  return m ? Number(m[1]) : null\n}\n\n/** The DMS path's last segment, query and fragment stripped — the document's content hash. */\nexport function documentHashOfPath(path: string): string | null {\n  const tail = path.split(/[?#]/)[0]!.split('/').pop()\n  return tail || null\n}\n\nfunction stringOrNull(v: unknown): string | null {\n  return typeof v === 'string' && v !== '' ? v : null\n}\n\n// ── SYS-3334: buildFileFieldTables — the last flat function's instance-shaped sibling ──\n\nconst HASH_PERIOD_SUFFIX = /#T(\\d+)$/\n\n/**\n * v2's `documentType -> extraction category` map (`extractionCategoryOf`),\n * inverted: which document type OWNS this extraction category's instances.\n * A linear scan over ~7 document types, not worth a cache of its own on top\n * of `extractionCategoryOf`'s.\n */\nfunction documentTypeOfCategory(category: AdapterCategory): string | null {\n  for (const group of getDocumentTypeGroups()) {\n    if (extractionCategoryOf(group.documentType) === category) return group.documentType\n  }\n  return null\n}\n\n/**\n * A category's instances, positioned as `documentsOfType` orders that\n * category's documents — the 0-based index `instanceRowsFromView` falls\n * back to when an instance carries no period of its own (see `timePeriodOf`).\n */\nfunction instancePositions(view: CanonicalView, category: AdapterCategory): Map<string, number> {\n  const docType = documentTypeOfCategory(category)\n  if (docType === null) return new Map()\n  const intake = view.categories['document-intake']?.instances ?? []\n  const documents = documentsOfType(view, intake, docType)\n  const positions = new Map<string, number>()\n  documents.forEach((doc, i) => {\n    for (const inst of doc.extraction) {\n      if (!positions.has(inst.instanceKey)) positions.set(inst.instanceKey, i)\n    }\n  })\n  return positions\n}\n\n/**\n * `InstanceRow.timePeriod` for one instance, FIVE rules in priority order —\n * widened from three by SYS-3334 F4 (round 2 review), and from four by\n * SYS-3517 F1 (rule 1b, which is a STOP, not another derivation):\n *\n * 1. `instance.legacySlot`, VERBATIM, when present AND it matches\n *    `LEGACY_SLOT_SHAPE` (M4, round 4 — see that constant's doc: rejected\n *    outright when it does not, never trimmed or coerced, and rules 1b-4\n *    below are consulted exactly as if the member were absent). This is the\n *    actual v1 slot the source row stored (finsys-api's provenance-on-the-wire\n *    fix puts it on the instance) — the uploader-declared slot on the file\n *    entry (bank `month`, EPF `year`, payslip `period`), not a re-derivation\n *    of it. When it is present AND well-shaped, rules 1b-4 below are not\n *    even consulted: the wire already answered the question they exist to\n *    approximate.\n * 1b. NULL, when the instance carries a `periodPosition` (SYS-3517 F1 — see\n *    the rule's own comment in the function body for the mechanism and the\n *    measurement). A coordinate producer stamps `legacySlot` on every row\n *    that has a v1 slot, so having reached this line the wire has said\n *    there is none — an ANSWER, not silence, and the only one of the five\n *    rules that ends the cascade rather than deriving something. Rules 2-4\n *    all approximate a slot from a key or an ordering; on a coordinate row\n *    each of them manufactures a slot the producer deliberately withheld.\n * 2. A `#T{n}` suffix on the key IS the period (financial statements:\n *    `financialStatement:<hash>#T2` -> 'T2' — two periods, one document).\n * 3. A `legacy:T{n}` key names its slot directly (`legacyOrdinalOfKey`).\n * 4. Otherwise the instance carries NO period on the wire and no\n *    `legacySlot` either — true of every bank / payslip / EPF instance\n *    (and, in practice, SSM / Form 9 / IC: one document, one\n *    single-cardinality instance, no period at all). RULE: label it by the\n *    instance's 0-based position in `documentsOfType`'s ordering of that\n *    category's documents, as `T{position + 1}`.\n *\n *    THIS IS AN APPROXIMATION, not v1's own numbering — F4's finding, and\n *    the reason rule 1 exists and outranks it. v1's T-number was the\n *    UPLOADER-DECLARED slot (bank `month`, EPF `year`, payslip `period`),\n *    stored on the sibling row as `timePeriod`; upload-order position is a\n *    DIFFERENT fact that happens to equal it only when uploads are ordered,\n *    complete, and unique per slot — an applicant who uploads statements out\n *    of order, skips a month, or replaces one gets a position-derived label\n *    that disagrees with what v1 would have shown. Rule 1 is what removes\n *    the approximation once finsys-api's provenance-on-the-wire fix ships;\n *    until then, this rule is what this function has.\n *\n *    Null only when the instance is absent from that ordering too — no\n *    document type maps to this category (`documentTypeOfCategory` found\n *    none), or the instance has neither a hash nor a legacy ordinal AND\n *    `documentsOfType` could not place it either (its own doc comment: \"no\n *    identity and no slot: nothing to attribute it to\").\n */\n/**\n * M4 (round 4): the ONLY shape `legacySlot` is trusted in — bare `T`\n * followed by a positive integer with no leading zero, no whitespace, no\n * suffix (`'T1'`, `'T23'`; never `'T1 '`, `'1'`, `'2026-06'`, `'T01'`).\n * finsys-api has not shipped this member on any real instance as of\n * 2026-08-19 (see `CanonicalInstance.legacySlot`'s own doc), which makes\n * THIS the cheapest moment to pin the contract — before a real producer\n * exists to violate it. A value that fails this check is REJECTED, not\n * trimmed: trimming `'T1 '` to `'T1'` would silently accept a producer bug\n * that put a stray character on the wire, and this member's whole job is to\n * carry the wire's own claim verbatim. A rejected value is treated as\n * ABSENT — the cascade continues exactly as if `legacySlot` had never been\n * set — so a producer bug never renders as a period that looks legitimate in\n * a column header or a provenance key.\n *\n * CORRECTED (SYS-3517): this used to say \"falls through to rule 2\", and\n * since rule 1b that is true only for a row carrying no `periodPosition`. On\n * a COORDINATE row, \"as if absent\" now means the cascade STOPS at rule 1b\n * and the period is null — the coordinate producer's own statement that this\n * row had no v1 slot, which is the whole point of that rule. Two\n * consequences, both deliberate:\n *\n *  - The out-of-shape value is still never consumed, and rejecting it and\n *    then stopping is strictly safer than rejecting it and then deriving a\n *    slot off the key, which is what rule 2 would have done.\n *  - For a POSITION-1 row that genuinely owned T1, a malformed `legacySlot`\n *    now renders `timePeriod: null, periodPosition: 1` — exactly the shape\n *    finsys-client's coordinate branch SELECTS for, so such a producer bug\n *    would read as a true current-year row rather than as a visible anomaly.\n *    UNREACHABLE today and pinned by a test rather than left to trust:\n *    probed against the finsim MySQL 2026-08-22, no value outside\n *    `/^T[1-9]\\d*$/` exists in any of the four sibling tables. If a producer\n *    ever emits one, the answer is a loud rejection at the emitter, not a\n *    third rule here.\n */\nconst LEGACY_SLOT_SHAPE = /^T[1-9]\\d*$/\n\n/**\n * SYS-3517 F1 — the shape `periodPosition` is trusted in, and the same\n * discipline as `LEGACY_SLOT_SHAPE`: a finite number >= 1, per\n * `CanonicalInstance.periodPosition`'s declared \"1-based period\n * coordinate\". A value outside it (0, a negative, a non-finite number) is\n * treated as ABSENT — the instance is read as carrying no coordinate at\n * all and rules 2-4 run exactly as they always did — never coerced into\n * \"the current-year row\".\n *\n * THE GATE IS THE PRODUCER'S, CHARACTER FOR CHARACTER (SYS-3526 release\n * prep). finsys-api's projector applies `Number.isFinite(p) && p >= 1`\n * (`ihsCanonicalReadService.projectInstance`, B9), citing this package's\n * `legacySlot` precedent; this was written as `Number.isInteger` and was\n * therefore STRICTER than the producer it receives from. That is the wrong\n * direction for a receiver, and not a harmless one: a `2.5` crossed the wire\n * and was silently dropped here, and dropping the coordinate un-fires rule\n * 1b, so the row's adopted `#T{n}` key gets read as a real slot and the\n * DEVOPS-535 overlap comes back for exactly that row. Out of range is now\n * out of range on both sides and nothing in between is invented. Unreachable\n * today either way — the column is `int` — which is why this is a\n * consistency fix rather than a defect fix, and why it is cheap to make now.\n *\n * An admitted-but-odd coordinate is inert downstream rather than dangerous:\n * the consumer branch that reads coordinates tests `periodPosition === 1`,\n * so a 2.5 row is simply slotless — which is what v1 did with a\n * NULL-timePeriod row too.\n */\nfunction coordinateOf(instance: CanonicalInstance): number | null {\n  const p = instance.periodPosition\n  return typeof p === 'number' && Number.isFinite(p) && p >= 1 ? p : null\n}\n\nfunction timePeriodOf(instance: CanonicalInstance, positions: Map<string, number>): string | null {\n  if (instance.legacySlot && LEGACY_SLOT_SHAPE.test(instance.legacySlot)) return instance.legacySlot\n  // RULE 1b (SYS-3517 F1). A `periodPosition` on the wire says the producer\n  // stores this category by (instance, period) COORDINATE — and a coordinate\n  // producer stamps `legacySlot` on every row that HAS a v1 slot. So on such\n  // an instance the slot's absence is INFORMATIVE, not silence: it is the\n  // producer saying \"the v1 model had no slot for this row\", and the correct\n  // period is null. Rules 2-4 below are all DERIVATIONS of a slot the wire\n  // did not state, and running any of them here manufactures one.\n  //\n  // The row this protects is DEVOPS-535's: a year-2 financial statement's\n  // OWN current fiscal year, stored at position 1 with `timePeriod = NULL`\n  // (financialStatementSpec.ts `slotFor`, the only (year, position) pair\n  // that maps to null). Its key routinely ends `#T1` — not a period, but a\n  // HISTORICAL KEY the re-extraction ADOPTED (\"Historical keys are never\n  // rewritten ... the adopted row keeps its key and gains its\n  // periodPosition stamp\"). Reading the period off that key rewrites the\n  // one null the coordinate model exists to preserve into a second claimant\n  // on slot T1, and the finsys-client resolver's coordinate branch\n  // (`timePeriod === null && periodPosition === 1`) can then never fire —\n  // reinstating, under V2 only, the exact overlap projection DEVOPS-535\n  // removed. Measured on finsim 2026-08-22, ihs 282/283: 90000 returned\n  // where the document says 77777, and on ihs 282 the fabricated claimant\n  // also won `latest/currentYear`, returning 77777 where 120000 was right.\n  //\n  // NOT a widening of rule 1: this reads the slot's ABSENCE, never its\n  // presence. A coordinate row that DOES carry a well-shaped `legacySlot`\n  // took rule 1 above and never reaches here, and an out-of-shape one is\n  // absent by M4's own contract, so it lands here — slotless, which is what\n  // \"treated as absent\" means once a coordinate is on the wire.\n  //\n  // SCOPE, checked rather than assumed: `periodPosition` is emitted only for\n  // a row whose table carries the column, which today is financial\n  // statements alone (`CanonicalInstance.periodPosition`; finsys-api B9).\n  // Every bank / payslip / EPF / SSM / Form 9 / IC / alt-data instance has\n  // no coordinate, so this rule cannot fire for them and their cascade is\n  // byte-identical.\n  if (coordinateOf(instance) !== null) return null\n  const hashSuffix = HASH_PERIOD_SUFFIX.exec(instance.instanceKey)\n  if (hashSuffix) return `T${hashSuffix[1]}`\n  const legacyOrdinal = legacyOrdinalOfKey(instance.instanceKey)\n  if (legacyOrdinal !== null) return `T${legacyOrdinal}`\n  const position = positions.get(instance.instanceKey)\n  return position !== undefined ? `T${position + 1}` : null\n}\n\n/**\n * The one category with an obvious per-instance label field, per the\n * registry: `finxtract-bank-statement.issuingBankName` (legacy base name\n * `bankName`) — different statements can be different banks. No other\n * document-extraction category has an analogous field: payslip's\n * `employerName` and financial-statement's `companyName` are constant\n * across one applicant's own documents, so they would not discriminate one\n * instance from another the way a bank name does. Checked against the\n * registry directly (`src/data/adapter-categories.json`), not assumed.\n */\nconst SOURCE_LABEL_LEGACY_NAME: Partial<Record<AdapterCategory, string>> = {\n  'finxtract-bank-statement': 'bankName',\n}\n\n/** Numeric ordering for `InstanceRow.timePeriod` (SYS-3334 F5, round 2): `'T1'\n * < 'T2' < … < 'T10'`. Anything that is not a bare `T{n}` — null, or F6's\n * `'#1'`/`'#2'` index fallback — sorts LAST, stable in original order; it\n * carries no period to order BY, so v1's \"declared slot\" ordering has\n * nothing to say about it either. */\nfunction periodSortValue(period: string | null | undefined): number {\n  if (!period) return Number.POSITIVE_INFINITY\n  const m = /^T(\\d+)$/.exec(period)\n  return m ? Number(m[1]) : Number.POSITIVE_INFINITY\n}\n\ninterface InstanceRowPair {\n  row: InstanceRow\n  instance: CanonicalInstance\n}\n\n/**\n * `instanceRowsFromView`'s row-building step, paired with the SOURCE\n * instance and sorted by numeric period (SYS-3334 F5, round 2).\n *\n * WHY PAIRS, NOT TWO ARRAYS. `fieldProvenanceFromView` needs both a row's\n * RESOLVED period (`row.timePeriod` — the full four-rule cascade, F6's\n * `instanceKey: ''` rescue included) and the SAME instance's envelopes,\n * `adapterId`, `observedAt` and `runId` (what a provenance entry is built\n * from) — one pass, one resolved fact, rather than two.\n *\n * CORRECTED (M1, round 4): this comment used to name\n * `buildFileFieldTablesFromView` as the consumer that needed the pairing —\n * it does not; that function only ever calls `instanceRowsFromView`, which\n * keeps `.row` and discards `.instance`. `.instance` was, in fact, dead on\n * every path until M1's fix (below): `fieldProvenanceFromView` used to walk\n * `category.instances` directly and call `timePeriodOf` a SECOND time,\n * which — for a row F6 had rescued from a blank header — recomputed null\n * instead of reusing the rescued period, so the rescued column could never\n * carry a confidence dot. `fieldProvenanceFromView` now consumes THESE\n * pairs instead, making `.instance` load-bearing: one derivation of a row's\n * period, read by every caller that needs it.\n *\n * WHY SORT AT ALL (F5). `instanceRowsFromView` used to return rows in view\n * (extraction-array) order. v1's `extractTimePeriods` sorted its T-slots\n * ASCENDING before rendering, so whenever intake order (which\n * `instancePositions` derives period from) disagreed with the extraction\n * array's own order, the resulting table rendered out of sequence — a\n * later-uploaded, earlier-period document could render AFTER an\n * earlier-uploaded, later-period one. Sorted here, once, so every caller\n * (this function, `buildFileFieldTablesFromView`) sees ascending period\n * order without re-deriving it. Rows without a parseable period (null, or\n * F6's `#n` fallback) sort LAST, stable in their original order — nothing\n * ranks them against a real period, so they should not silently jump ahead\n * of one.\n */\nfunction instanceRowPairsFromView(view: CanonicalView, category: AdapterCategory): InstanceRowPair[] {\n  const instances = view.categories[category]?.instances ?? []\n  if (instances.length === 0) return []\n\n  const positions = instancePositions(view, category)\n  const sourceLabelField = SOURCE_LABEL_LEGACY_NAME[category]\n\n  const pairs: InstanceRowPair[] = instances.map((instance, i) => {\n    const row: InstanceRow = {\n      instanceKey: instance.instanceKey,\n      timePeriod: timePeriodOf(instance, positions),\n      sourceLabel: null,\n      // The period COORDINATE, when the wire carries one — v1's sidecar rows\n      // carried `periodPosition` too (finsys-api's toInstanceRow includes it\n      // deliberately), and the finsys-client resolver selects the true\n      // current-year row by it. Without this the flat-vs-view rows differ on\n      // exactly the column that decides which number a lender scores on.\n      //\n      // SYS-3517 F1: through `coordinateOf`, the SAME gate rule 1b applies,\n      // so the row can never advertise a coordinate the period rule refused\n      // to honor. A row carrying `periodPosition: 0` beside a slot derived\n      // as if no coordinate existed is a declared-vs-actual drift of the\n      // kind this package's release notes are organised against, and the\n      // resolver's `periodPosition === 1` test would read it as a real\n      // coordinate on a row that was never treated as one.\n      ...(coordinateOf(instance) !== null ? { periodPosition: instance.periodPosition } : {}),\n    }\n    // SYS-3517 F1: the `coordinateOf` clause is new. F6's rescue is for a\n    // period that is UNKNOWN (nothing on the wire named one, so label the\n    // lone document T1 rather than render a blank header). A coordinate\n    // row's period is KNOWN and is deliberately none — rule 1b just said so\n    // — and rescuing it would re-fabricate, eight lines later, the very slot\n    // that rule withheld. No producer emits `instanceKey: ''` WITH a\n    // coordinate today; the clause is here so rule 1b cannot be undone by a\n    // branch written for a different question if one ever does.\n    if (row.timePeriod === null && instance.instanceKey === '' && coordinateOf(instance) === null) {\n      // SYS-3334 F6 (round 2): a single-cardinality category's ONE instance\n      // carries instanceKey '' by convention (canonical-view.ts's own\n      // contract) — and IS slot 1, the same way any other lone document\n      // would position-fallback to T1. Without this, `timePeriodOf` answers\n      // null, `instanceColumnLabel` falls back to `row.instanceKey` (''),\n      // and the table renders a BLANK column header. More than one instance\n      // sharing '' is a data anomaly (the contract says '' means \"the ONE\n      // instance\"), so '' cannot mean slot 1 for either of them here —\n      // fall back to array position, never to a shared, ambiguous label.\n      row.timePeriod = instances.length === 1 ? 'T1' : `#${i + 1}`\n    }\n    for (const [field, envelope] of Object.entries(instance.fields)) {\n      const legacyBase = v1LegacyBaseNameOf(category, field)\n      if (legacyBase === null) continue\n      row[legacyBase] = envelope.value\n    }\n    // SYS-3334 F4 (round 2): the wire's OWN per-instance label (finsys-api's\n    // provenance-on-the-wire fix) wins over the registry-derived one — it is\n    // the actual value the source row carried, not a guess from a field this\n    // function happens to recognize. The registry fallback stays for every\n    // instance that predates the fix.\n    if (instance.sourceLabel) {\n      row.sourceLabel = instance.sourceLabel\n    } else if (sourceLabelField) {\n      const label = row[sourceLabelField]\n      if (typeof label === 'string' && label !== '') row.sourceLabel = label\n    }\n    return { row, instance }\n  })\n\n  // Stable sort (guaranteed since ES2019, which every runtime this package\n  // targets satisfies) — ties (including every no-period row, all sorting to\n  // +Infinity) keep their original relative order.\n  pairs.sort((a, b) => periodSortValue(a.row.timePeriod) - periodSortValue(b.row.timePeriod))\n  return pairs\n}\n\n/**\n * `InstanceRow[]` for one category of a `CanonicalView` — one row per v2\n * instance of that category, ORDERED BY NUMERIC PERIOD (SYS-3334 F5, round\n * 2 — see `instanceRowPairsFromView`'s doc for why; rows without one trail,\n * stable in view order). The bridge `buildFileFieldTablesFromView` needs: it\n * feeds a view into `buildFileFieldTablesFromInstances`, which was built for\n * finsys-api's sibling-table instance rows (one row per uploaded document,\n * keyed by a real instanceKey rather than a pre-declared T{n} slot) and\n * knows nothing about canonical envelopes.\n *\n * `instanceKey` is carried verbatim. `timePeriod` follows the four-rule\n * cascade in `timePeriodOf` (its own doc comment states the position-based\n * fallback rule, and F6's `instanceKey: ''` guard below it, in full — read\n * both before assuming a null or a `#n` here is a bug). `sourceLabel` is the\n * wire's own per-instance label (`instance.sourceLabel`) when present, else\n * the registry-derived one for the one category with an obvious label field\n * (`SOURCE_LABEL_LEGACY_NAME`), else null.\n *\n * Every field envelope becomes `row[legacyBaseName] = value`, via\n * `v1LegacyBaseNameOf`. A field with no legacy base name never had a wide\n * column — SKIPPED, not thrown: `buildFileFieldTablesFromInstances` only\n * ever reads the base names the catalog declares for this category, so an\n * unmapped field would never be looked up even if it were written into the\n * row. (A category with no v1 lineage at all has every field skipped this\n * way and produces rows with no metric keys — `groupColumnsByInstance`\n * treats that as \"no data\" for every base column, and\n * `buildFileFieldTablesFromInstances` omits the table, same as an empty\n * `instanceRows` array would.) SYS-3334 F1 (round 2): this claim used to be\n * false for exactly one shape — a `mapped-fanout` field (`incorporatedDate`)\n * — because `v1LegacyBaseNameOf` answered null for it despite it having a\n * wide column; fixed at the source in `v1-migration-map.ts`, so the claim\n * above is accurate again rather than merely aspirational.\n */\nexport function instanceRowsFromView(view: CanonicalView, category: AdapterCategory): InstanceRow[] {\n  return instanceRowPairsFromView(view, category).map((p) => p.row)\n}\n\n/**\n * v1's assertion-class vocabulary (`IhsFieldOrigin`: 'extracted' | 'derived'\n * | 'manual') is CLOSED; v2's `CanonicalFieldEnvelope.origin` is an open\n * string naming the assertion class the finsys-api resolver ranks\n * ('extraction' | 'form-intake' | 'manual' | …, per `CanonicalAttestation`'s\n * doc comment in canonical-view.ts). The one rename known today is\n * 'extraction' -> 'extracted'. Anything else — absent, or a class this\n * bridge does not recognize — degrades to 'derived'.\n *\n * SYS-3334 F7 (round 2 review): that fallback is NOT \"the type's documented\n * meaning\" for one real case, 'form-intake', and the earlier wording of this\n * comment overclaimed it. `IhsFieldOrigin`'s own doc (ihs-types.ts) says\n * `derived` means \"computed / no-confidence path\" — a value nobody attested,\n * produced by a formula. A form-intake value is neither: an APPLICANT typed\n * it, which is a real assertion, just not one the closed v1 vocabulary has a\n * slot for ('manual' means a LENDER correction, not an applicant's own\n * answer — see `CanonicalAttestation`'s doc). 'derived' is the\n * LEAST-WRONG of the three available answers, not a correct one: it is\n * right that a form-intake value carries no extraction confidence, and wrong\n * to imply the value was computed rather than asserted. Widening\n * `IhsFieldOrigin` to a fourth value is the real fix and is not this\n * function's call to make — every consumer of the closed enum would need\n * updating for one bridge function's honesty. Never claim 'extracted' for a\n * string this function does not understand — that would fabricate a\n * confidence-worthy classification, exactly the failure `confidence` exists\n * to prevent.\n */\nfunction legacyOriginOf(origin: string | undefined): IhsFieldOrigin {\n  if (origin === 'extraction') return 'extracted'\n  if (isValidIhsFieldOrigin(origin)) return origin\n  return 'derived'\n}\n\n/**\n * The per-(legacy-key) provenance map every instance-shaped file-field\n * function synthesizes from `CanonicalView` envelopes — HOISTED out of\n * `buildFileFieldTablesFromView` (SYS-3334 F3, round 2 review) so it can be\n * called on its own, and FIXED at the same time: the inline version this\n * replaces built its map with a bare `synthesized[key] = entry` inside a\n * loop, so two envelopes landing on the same key SILENTLY collided —\n * whichever was written last won, with no signal that a collision had even\n * happened. Two real shapes produce that collision: a re-extraction (two\n * runs of the SAME document, same key, same period) and two filings that\n * both land on `#T1` (see F5's own doc for why two filings can share a\n * slot).\n *\n * COVERS EVERY CATEGORY, not only document-extraction ones (unlike\n * `buildFileFieldTablesFromView`'s own loop, which only ever walked\n * `getDocumentTypeGroups()`). A scalar field's provenance — an applicant's\n * own `fullName` confidence, say — is exactly as real as a bank statement\n * cell's, and the caller-override contract (`fieldProvenance` beating the\n * synthesized map) should hold for it too.\n *\n * KEYING, two paths — BOTH emitted when both answer (H1, round 4;\n * corrected from \"only when (1) has no answer\" below):\n *   1. THE EXACT v1 KEY, via `v1KeyForAddress(category, field, instanceKey)`,\n *      with the SAME keyless fallback `processIhsDetailsFromView` uses when\n *      the instance key carries no discriminating power for this field\n *      (`v1AddressHasKeyedEntries`) — copied here rather than imported,\n *      because `processIhsDetailsFromView` is out of scope for this change\n *      (see the brief this function was built against) and duplicating four\n *      lines is safer than reaching into a function nobody may touch. What\n *      the detail panel and a v1 sidecar key on.\n *   2. THE T-SLOT FAMILY'S SHARED BASE + this instance's period, via\n *      `v1LegacyBaseNameOf(category, field)` and `${legacyBase}${period}`.\n *      What `buildInstanceTable` ALWAYS reads (unconditionally, never the\n *      exact key — see its own doc). `period` is `row.timePeriod`, from the\n *      SAME resolved rows `instanceRowsFromView` renders\n *      (`instanceRowPairsFromView` — M1, round 4, corrected below), not a\n *      second derivation that could silently disagree with what the row\n *      shows.\n *\n * H1 (HIGH, round 4): path 2 used to run ONLY when path 1 had no answer —\n * correct for a genuine T-slot family (`bankBalanceT1..T6`, no single v1 key\n * to name), wrong for `ssm`/`form9`/`ic`: their single-instance columns\n * carry NO T-suffix at all, so their exact key (`ssmCompanyName`,\n * `icName`, …) IS already their legacy base, and it beat path 2 to `key`\n * every time. `buildInstanceTable` never looks up the bare base — it always\n * appends the period — so these three document types lost 100% of their\n * provenance through this path (measured: `ssm_documents` 16/16,\n * `ic_documents` 9/9, `form9` 3/3 base columns). Both names point at the\n * SAME cell, so both are now emitted whenever both resolve — gated to\n * document-extraction categories (`documentTypeOfCategory(category) !==\n * null`, the same set `buildInstanceTable` is ever fed): a scalar category's\n * F6-rescued period (an `applicant-identity` sole `''` instance renders\n * `'T1'` too, for `instanceRowsFromView`'s OWN reason — see F6's doc) would\n * otherwise mint a `<base><period>` twin — e.g. `fullNameT1` — that nothing\n * ever reads, purely because path 2's two ingredients both happened to\n * resolve for a field `buildInstanceTable` will never render.\n *\n * NAMED, NOT HIDDEN: the period-suffixed key is per (base, slot), not per\n * instance — `buildInstanceTable`'s own contract (it looks provenance up by\n * `${baseName}${row.timePeriod}`, which does not include `instanceKey`). So\n * two DIFFERENT instances that land on the same slot (the re-extraction and\n * two-filings cases above) necessarily share ONE provenance entry; this is a\n * limitation of `buildInstanceTable`'s key format, not of this function.\n *\n * H2 (HIGH, round 4): a collided key is DROPPED from the returned\n * `provenance`, not resolved to the winner. `collided` still names it, so a\n * caller can log or investigate — but the entry itself is removed: with two\n * instances landing on one slot (a real shape during the `legacySlot`\n * migration window — one instance carrying it, its sibling falling through\n * to the SAME position-fallback slot), rendering the winner's confidence on\n * BOTH columns put a wrong-but-plausible number on the loser's column, which\n * never had that confidence. Absent is honest; wrong-and-confident is not —\n * exactly the property F3 (above) exists to protect, and rendering a\n * winner's number on a loser's column violated it as surely as the silent\n * last-write-wins F3 fixed did.\n *\n * M-5 (round 5): H2 above is why this function no longer picks a temporal\n * winner for a genuine collision at all. Round 2-4 kept a `challengerWins`\n * tie-break (newer `observedAt`, then larger `runId`, then last-in-order) so\n * `provenance[key]` briefly held \"the winner\" before H2's unconditional\n * delete removed it — but every key that ever REACHES a collision comparison\n * is, by definition, a key H2 deletes at the end, so that comparison's\n * result was never observable in the returned `provenance`: `challengerWins`\n * and the `winnerMeta` map that fed it were computing an answer nobody could\n * ever read. Deleted. A collision is now just recorded (`collidedSet.add`)\n * and left alone — SHIPPED BEHAVIOR, stated plainly: a collided key is\n * reported in `collided` and absent from `provenance`; no winner is chosen,\n * because a winner would be a guess with nowhere left to render it.\n *\n * H-1 (HIGH, round 5): a `mapped-fanout` key's two DIFFERENT attestors\n * (`sharedFanoutOf`, below) are NOT this kind of collision — the fanout's\n * whole design is that BOTH survive. See that function's own doc and the\n * loop below for the address-order tie-break that replaces\n * `challengerWins` for exactly this one case.\n *\n * NO ENTRY when the envelope asserts NEITHER `confidence` NOR `origin` (L1,\n * round 4 — corrected from \"none of `confidence`, `origin`, or\n * `originalValue`\"): `originalValue` alone used to admit an envelope here\n * too, then stamp it `origin: legacyOriginOf(undefined)` = `'derived'` — the\n * exact fabricated shape this paragraph says never happens, for a field\n * that asserted NOTHING beyond the value an overlay replaced. `confidence`\n * or `origin` is a real assertion; `originalValue` is carried ONTO an entry\n * one of those two justified, never a reason to create one by itself.\n */\n/**\n * H-1 (round 5): whether two DIFFERENT (category, field) addresses that just\n * wrote the SAME provenance key are the two attestors of one\n * `mapped-fanout` entry (`incorporatedDate` today) rather than a genuine\n * collision. Returns their positions in the fanout's own `addresses` order\n * when they are; null when they are not (including when either address is\n * not a fanout attestor at all, or the two belong to DIFFERENT fanouts).\n */\nfunction sharedFanoutOf(\n  a: { category: string; field: string },\n  b: { category: string; field: string },\n): { incumbentIndex: number; challengerIndex: number } | null {\n  const fa = v1FanoutAddressOf(a.category, a.field)\n  const fb = v1FanoutAddressOf(b.category, b.field)\n  if (fa === null || fb === null || fa.key !== fb.key) return null\n  return { incumbentIndex: fa.index, challengerIndex: fb.index }\n}\n\nexport function fieldProvenanceFromView(\n  view: CanonicalView,\n): { provenance: Record<string, IhsFieldProvenanceWithOriginal>; collided: string[] } {\n  const provenance: Record<string, IhsFieldProvenanceWithOriginal> = {}\n  // H-1: the (category, field) address that WROTE the current entry under\n  // each key, so a second write from a DIFFERENT address can be told apart\n  // from a second write from the SAME one — see the loop below. (M-5, round\n  // 5: this replaces the round 2-4 `winnerMeta` map, which tracked\n  // observedAt/runId for a temporal tie-break that H2's unconditional\n  // delete made unobservable for every key it was ever consulted on — see\n  // this function's own doc.)\n  // The VALUE rides along so a fanout co-attestation can be told from a\n  // fanout DISAGREEMENT (H-1r5, below): the carve-out is only honest when\n  // both attestors say the same thing.\n  const originAddress = new Map<string, { category: string; field: string; value: unknown }>()\n  const collidedSet = new Set<string>()\n\n  for (const categoryId of Object.keys(view.categories)) {\n    const category = categoryId as AdapterCategory\n    // H1: gates path 2 (below) to the categories buildInstanceTable ever\n    // renders — see the function doc for why a scalar category's rescued\n    // period must NOT feed a legacy-base+period key.\n    const isDocCategory = documentTypeOfCategory(category) !== null\n\n    for (const { row, instance } of instanceRowPairsFromView(view, category)) {\n      // M1: the SAME resolved period the row carries — including F6's\n      // rescue — never a second `timePeriodOf` call (see the function doc\n      // and `InstanceRowPair`'s own doc for the bug this replaces).\n      const period = row.timePeriod\n\n      for (const [field, envelope] of Object.entries(instance.fields)) {\n        // L1: `originalValue` alone does not justify synthesizing an entry.\n        if (envelope.confidence === undefined && envelope.origin === undefined) {\n          continue\n        }\n\n        // The keyed lookup first — same keyless fallback rule\n        // `processIhsDetailsFromView` uses (see that function's own comment\n        // for the reasoning): a miss only falls back to the keyless entry\n        // when the map holds no keyed entry for this address AT ALL.\n        const exact =\n          v1KeyForAddress(categoryId, field, instance.instanceKey || undefined) ??\n          (v1AddressHasKeyedEntries(categoryId, field) ? null : v1KeyForAddress(categoryId, field))\n\n        // H1: path 2, computed independently of path 1 and emitted\n        // ALONGSIDE it (not only as a fallback) — see the function doc.\n        let periodKey: string | null = null\n        if (isDocCategory && period !== null) {\n          const legacyBase = v1LegacyBaseNameOf(categoryId, field)\n          if (legacyBase !== null) periodKey = `${legacyBase}${period}`\n        }\n\n        const keys = new Set<string>()\n        if (exact !== null) keys.add(exact)\n        if (periodKey !== null) keys.add(periodKey)\n        if (keys.size === 0) continue\n\n        const entry: IhsFieldProvenanceWithOriginal = {\n          source: instance.adapterId,\n          confidence: envelope.confidence ?? null,\n          // F7/F10: '' is a documented sentinel — see IhsFieldProvenance.observedAt.\n          observedAt: instance.observedAt ?? '',\n          sourceRunId: instance.runId !== undefined ? String(instance.runId) : null,\n          origin: legacyOriginOf(envelope.origin),\n          ...(envelope.originalValue !== undefined ? { originalValue: envelope.originalValue } : {}),\n        }\n\n        for (const key of keys) {\n          const incumbentAddress = originAddress.get(key)\n          if (incumbentAddress === undefined) {\n            provenance[key] = entry\n            originAddress.set(key, { category: categoryId, field, value: envelope.value })\n            continue\n          }\n\n          // H-1: is this a SECOND write from the address that already holds\n          // the key, or from a DIFFERENT address? Only the latter can\n          // possibly be a fanout co-attestation rather than a collision.\n          const sameAddress = incumbentAddress.category === categoryId && incumbentAddress.field === field\n          const fanout = sameAddress ? null : sharedFanoutOf(incumbentAddress, { category: categoryId, field })\n\n          if (fanout) {\n            // Two DIFFERENT attestors of the SAME mapped-fanout v1 key —\n            // the fanout's whole design is that both survive, so this is\n            // NOT a collision WHEN THEY AGREE. Keep whichever address is\n            // FIRST in the map's own `addresses` order — the same rule\n            // `flatRecordFromView`'s `mapped-fanout` branch uses to pick\n            // \"the\" value. Never a temporal/run-based tie-break: that\n            // answers a different question (\"which INSTANCE of the SAME\n            // address is newest\"), and M-5 removed it as dead weight for\n            // the genuine-collision case below.\n            //\n            // H-1r5: when the two attestors DISAGREE on the value, this is\n            // a collision after all. Both tables render their OWN value,\n            // but the provenance map is keyed by the v1 column, so a single\n            // surviving entry would pair one table's value with the OTHER\n            // attestor's confidence, source and run — a wrong-but-plausible\n            // dot, the exact shape H2 exists to prevent. Absent is honest.\n            if (!candidateValuesAgree(incumbentAddress.value, envelope.value)) {\n              collidedSet.add(key)\n              continue\n            }\n            if (fanout.challengerIndex < fanout.incumbentIndex) {\n              provenance[key] = entry\n              originAddress.set(key, { category: categoryId, field, value: envelope.value })\n            }\n            continue\n          }\n\n          // M-5 (round 5): a real collision — the SAME address wrote this\n          // key twice, or two DIFFERENT addresses that are not both\n          // attestors of one fanout. Recorded and left alone: H2 (round 4,\n          // below) unconditionally deletes this key's `provenance` entry\n          // regardless of which write it is, so nothing here needs to pick\n          // a winner.\n          collidedSet.add(key)\n        }\n      }\n    }\n  }\n\n  // H2: a collided key is dropped from `provenance` — see the function doc.\n  // `collided` (returned below) still names every one of them.\n  for (const key of collidedSet) {\n    delete provenance[key]\n  }\n\n  return { provenance, collided: [...collidedSet] }\n}\n\n/**\n * `buildFileFieldTables` for a v2 `CanonicalView` — the fourth and last flat\n * file-field function to get an instance-shaped sibling (the finsys-client\n * migration's last flat surface to gain one; see this module's other\n * SYS-3334 doc comments on\n * `processIhsDetailsFromView` / `resolveExtractionStatusFromView` /\n * `buildDocumentRowsFromView` for the same discipline applied here).\n *\n * MECHANISM. For every document-type group (`getDocumentTypeGroups()`),\n * resolve its extraction category (`extractionCategoryOf`), turn that\n * category's instances into `InstanceRow[]` (`instanceRowsFromView`), and\n * hand the whole map to `buildFileFieldTablesFromInstances` keyed by\n * `documentGroup` — the exact key that function already groups its own\n * catalog output by (`groupFieldsByPattern` groups `type: 'file'` specs by\n * `document_group`, e.g. `bank_statements`, NOT `document_type`, e.g.\n * `bankStatements` — confirmed against the catalog data, not assumed). A\n * document type whose columns map to no extraction category\n * (`extractionCategoryOf` returns null) contributes no table, same as an\n * absent category does today for `buildFileFieldTablesFromInstances`.\n *\n * PROVENANCE, WITHOUT A V1 SIDECAR — now `fieldProvenanceFromView` (SYS-3334\n * F3, round 2). `buildInstanceTable` (inside `buildFileFieldTablesFromInstances`)\n * looks up per-cell provenance in a `fieldProvenance` map keyed by\n * `${legacyBaseName}${timePeriod}` — the exact wide-table column name\n * (`bankBalanceT1`). v1 fed that map from a sidecar finsys-api built\n * alongside the flat record; a `CanonicalView` has no such sidecar, but its\n * own envelopes already carry `confidence` / `origin` per field, plus\n * `adapterId` / `observedAt` / `runId` per instance —\n * `fieldProvenanceFromView` synthesizes the sidecar's shape from those, so\n * confidence dots keep working with NO caller-supplied provenance at all —\n * QUALIFIED (H1/F11, round 4): true once BOTH (a) finsys-api's own\n * provenance-on-the-wire fix ships (as of 2026-08-19 it has not — the wire\n * attaches provenance to 0 of 68k extraction fields) AND (b)\n * `fieldProvenanceFromView` emits both the exact v1 key and the\n * period-suffixed key this lookup actually reads (H1's fix — before it,\n * `ssm`/`form9`/`ic` rendered zero dots regardless of what finsys-api\n * ships, because their exact key won outright and this lookup never sees\n * it). See `fieldProvenanceFromView`'s own doc for the mechanism.\n * The optional `fieldProvenance` parameter still exists (same signature as\n * `buildFileFieldTables`) for a caller that has one anyway; where it and the\n * synthesized map name the same key, the CALLER'S entry wins — an explicit\n * override should beat a derived guess. `fieldProvenanceFromView`'s own\n * `collided` return is dropped here: this function's signature predates F3\n * and changing its return shape is out of scope for a review fix — a caller\n * that needs the collision signal calls `fieldProvenanceFromView` directly.\n *\n * M-4 (round 4, doc corrected round 5): THE OVERRIDE IS VACUOUS ON 28 BASE\n * COLUMNS — stated plainly, because \"the caller's entry wins\" reads as a\n * universal contract and is not one. `buildInstanceTable` reads ONLY\n * `${legacyBaseName}${timePeriod}` (H1, round 4's own finding), never the\n * bare v1 key — but for ssm (16 columns), ic (9), and form9 (3), the exact\n * v1 key IS the legacy base (their single-instance fields carry no\n * T-suffix at all), so a caller-supplied sidecar keyed by that bare v1 name\n * (`ssmCompanyName`, not `ssmCompanyNameT1`) never reaches the lookup this\n * function actually performs — it silently does nothing, and a `currency`\n * on that same caller entry is lost the identical way (never read, because\n * the entry itself is never read). The synthesized period-suffixed twin\n * (H1) is what actually reaches the cell; a caller wanting to override one\n * of these 28 must key its override the SAME way — `<base>T1`, not the\n * bare v1 name — behavior UNCHANGED by this correction; only the doc was\n * wrong.\n *\n * NOT CARRIED THROUGH: `currency` — the per-observation denomination\n * `IhsFieldProvenance.currency` records on the flat sidecar.\n * `CanonicalFieldEnvelope` has no currency member — v2 does not yet attach\n * one the way the v1 sidecar could — so money values through this path format\n * WITHOUT a currency code (a plain grouped number: `formatValue`'s existing,\n * honest \"no denomination known\" behavior; it does not invent one). This is\n * a real capability gap, not a bug introduced here, and it already applied\n * to `buildFileFieldTablesFromInstances` before this function existed.\n */\nexport function buildFileFieldTablesFromView(\n  view: CanonicalView,\n  fieldProvenance?: Record<string, IhsFieldProvenance>,\n): Record<string, FileFieldTableData> {\n  const instancesByCategory: Record<string, InstanceRow[]> = {}\n\n  for (const group of getDocumentTypeGroups()) {\n    const category = extractionCategoryOf(group.documentType)\n    if (category === null) continue\n\n    instancesByCategory[group.documentGroup] = instanceRowsFromView(view, category)\n  }\n\n  const { provenance: synthesized } = fieldProvenanceFromView(view)\n  const provenance = { ...synthesized, ...(fieldProvenance ?? {}) }\n  return buildFileFieldTablesFromInstances(\n    instancesByCategory,\n    Object.keys(provenance).length > 0 ? provenance : undefined,\n  )\n}\n\n// ── The v1-shape bridge (SYS-3334) ────────────────────────────────────\n\n/**\n * The record half of the v2 read pair, structurally — core does not import\n * the SDK or any host-side application-record type. `parties` / `facility` /\n * `system` are the three groupings finhub-adonisjs and finsys-client already\n * use for the non-adapter fields the `relocated` keys moved to (the\n * migration map's own NOT-ADAPTER column-audit classes); a caller with a\n * differently-shaped record adapts it to this shape at the call site rather\n * than this package widening to match one host's naming.\n *\n * L-6 (round 5): WHICH KEY LIVES IN WHICH BUCKET IS THE RECORD CONTRACT —\n * this package does not police it, `flatRecordFromView` just walks whichever\n * bucket the map's `relocated` entries and the caller agree on (H-2, round\n * 5: by PRESENCE, `parties` -> `facility` -> `system`, stopping at the first\n * bucket that carries the key at all). In practice: `system` carries the\n * administrative/timestamp keys (`createdAt`, `updatedAt`, `jurisdiction`,\n * `programId`, …), `facility` carries financing terms (`totalFinancing`, …),\n * `parties` carries borrower/lender identity. The ONE normalization\n * `flatRecordFromView` performs on ANY relocated value, regardless of which\n * bucket it came from: a `Date` instance becomes its ISO string — v1 served\n * every relocated timestamp as an ISO string, and a caller assembling this\n * record from an ORM row hands back `Date` objects instead. This is SHAPE,\n * not the value coercion `flatRecordFromView`'s own doc disclaims elsewhere\n * (a `Date` and its ISO string name the same instant; there is no second\n * opinion about what the value IS, only about which JS type carries it). See\n * `normalizeRelocatedValue`.\n */\nexport interface ApplicationRecordLike {\n  applicationId?: number\n  status?: string | null\n  statusDescription?: string | null\n  parties?: Record<string, unknown>\n  facility?: Record<string, unknown>\n  system?: Record<string, unknown>\n}\n\n/**\n * The v1 flat IHS record's SHAPE, re-derived from a `CanonicalView` (+ an\n * optional `ApplicationRecordLike` for the keys the migration map calls\n * `relocated`) — the migration map run FORWARD (v1 key → address → value),\n * so `EvaluationDataFactory`, the SSM panel, `MatchingUtil.isSatisfied`,\n * `jurisdictionOf` and every other v1-flat-shaped reader can consume a v2\n * view through one map instead of each growing its own reverse walk.\n */\nexport interface FlatRecordFromView {\n  /** v1 column name -> value, for every key the map could place from this view/record. */\n  record: Record<string, unknown>\n  /**\n   * v1 keys the map holds but this function could NOT place, one entry per\n   * key, NEVER silent — `flatRecordFromView` iterates `v1MigrationKeys()`,\n   * not the view, so a key with no v2 value is reported, not dropped. Every\n   * non-placed key ends up here exactly once, `disposition` is the map's own\n   * `V1Disposition` string (so a caller can filter — \"show me only the\n   * `needs-decision` residuals\"), and `reason` is either the map entry's own\n   * `note`/`reason` (retired / vocabulary-gap / needs-decision /\n   * mapped-pending-build / structural) or a fact this function discovered\n   * about the SUPPLIED view/record for a `mapped` / `mapped-fanout` /\n   * `relocated` key that had an address but no value at it today.\n   */\n  unplaced: { key: string; disposition: string; reason: string }[]\n  /**\n   * v1 keys that WERE placed, but the placement made a choice a reader\n   * should be able to see rather than trust silently: (a) a plain-address\n   * `mapped` key where more than one instance of the category carried that\n   * field (the first, in the SAME period-sorted order the rendered tables\n   * use — M-1, round 5 — was placed; v1's own wide column could hold only\n   * one value too, so this is not a new ambiguity, only a newly VISIBLE\n   * one); (b) a `mapped-fanout` key (`incorporatedDate`) where more than one\n   * attestor address had a value and they DISAGREED (the first address's\n   * value, in the map's own address order, was placed); (c) a T-slot family\n   * key (M-2, round 5) where more than one row shares the slot (the first,\n   * in row order, was placed — a T-slot key names the SLOT, not an\n   * INSTANCE, so `buildInstanceTable` can render two columns for the same\n   * period label while this can only ever hold one value). Never populated\n   * for an `instanceKey` / `instanceKeyPrefix` resolution — those are a\n   * single, unambiguous instance by construction (or, for a prefix,\n   * \"first in order\" IS the stated parity contract, not an accident worth\n   * flagging every time it fires).\n   */\n  ambiguous: string[]\n  /**\n   * The four v1 sidecars, one row per instance, keyed by LEGACY base names —\n   * `instanceRowsFromView` verbatim, one call per category. These are the\n   * `structural` map entries `bankStatementInstances` / `financialStatementInstances`\n   * / `epfStatementInstances` / `payslipInstances`: v1 shipped them as\n   * sibling arrays beside the flat record, and they still are one, just not\n   * a member of `record` — the flat record's OWN keys never held instance\n   * rows, so putting these here rather than flattening them into `record` is\n   * the honest shape, not a convenience.\n   */\n  instances: {\n    financialStatementInstances: InstanceRow[]\n    bankStatementInstances: InstanceRow[]\n    epfStatementInstances: InstanceRow[]\n    payslipInstances: InstanceRow[]\n  }\n}\n\n/** The v1 key's own trailing period suffix — `bankBalanceT1` -> `1`. Matches\n * ONLY the bare `T[1-9]` tail: the `(PriorYear)?` branch `v1-migration-map.ts`'s\n * `TIME_PERIOD_SUFFIX` also carries is UNREACHABLE for a `mapped` entry as of\n * the round 2 map correction (the six `…PriorYearT{n}` keys are\n * `needs-decision` now, not `mapped`) — see that regex's own doc comment. */\nconst T_SLOT_KEY_SUFFIX = /T([1-9])$/\n\ninterface AddressLookup {\n  found: boolean\n  value?: unknown\n  /**\n   * Set by the plain-address lookup (more than one instance carries the\n   * field) and, since M-2 (round 5), by the T-slot lookup too (more than one\n   * row shares the slot) — see `ambiguous` above.\n   */\n  multiple?: boolean\n  /**\n   * L-5 (round 5): only ever set by the T-slot lookup, on a miss — names\n   * WHICH of its three distinct not-found causes applied (`valueAtTSlot`'s\n   * own doc). Unset elsewhere; those callers' `missingReason` locals in\n   * `flatRecordFromView` are specific enough on their own.\n   */\n  reason?: string\n}\n\n/**\n * H-2 (round 5): PRESENCE, not nullishness. `record.parties[key] ??\n * record.facility[key] ?? record.system[key]` — the line this replaces —\n * fell through to the NEXT bucket whenever the current one held an explicit\n * `null`, so `parties: { jurisdiction: null }` beside `facility: {\n * jurisdiction: 'X' }` silently returned the WRONG bucket's value, and it\n * was inconsistent about it: a null in the LAST bucket (`system`) still got\n * placed (nothing left to fall through to), so the same \"null means try\n * again\" rule gave two different answers depending on which bucket happened\n * to hold the null. Walks `parties` -> `facility` -> `system`, the SAME\n * order and the SAME three buckets, but stops at the FIRST one that carries\n * the key AT ALL (`Object.prototype.hasOwnProperty`, never a nullish check)\n * — exactly the rule `valueAtPlainAddress` already applies to a v2 field\n * envelope. A bucket's explicit `null` is a real assertion (v1 served null\n * for an empty relocated column) and is placed as `null`, never treated as\n * \"try the next bucket\".\n */\nfunction relocatedBucketValue(record: ApplicationRecordLike | undefined, key: string): AddressLookup {\n  for (const bucket of [record?.parties, record?.facility, record?.system]) {\n    if (bucket && Object.prototype.hasOwnProperty.call(bucket, key)) {\n      return { found: true, value: bucket[key] }\n    }\n  }\n  return { found: false }\n}\n\n/**\n * L-6 (round 5): the ONE normalization `flatRecordFromView` performs on a\n * relocated value (`ApplicationRecordLike`'s own doc names the reason) — a\n * `Date` instance becomes its ISO string, v1's own shape for every\n * relocated timestamp. Applied uniformly to every relocated key, not only\n * `createdAt`/`updatedAt`, because the record contract does not name here\n * which keys a caller might hand a `Date` for.\n */\nfunction normalizeRelocatedValue(value: unknown): unknown {\n  return value instanceof Date ? value.toISOString() : value\n}\n\n/** A per-call memo of `instanceRowPairsFromView`, keyed by category — see `rowPairsCache` below. */\ntype RowPairsLookup = (view: CanonicalView, category: AdapterCategory) => InstanceRowPair[]\n\n/**\n * L-4 (round 5): a CALL-LOCAL memo of `instanceRowPairsFromView` — one\n * rebuild per category actually looked up during a single `flatRecordFromView`\n * call, not a module-level cache (a `CanonicalView` is call-scoped data;\n * caching across calls would leak one application's rows into another's\n * lookup, or go stale against a re-fetched view of the SAME application).\n *\n * Paired with M-1 (same finding): once `valueAtPlainAddress` reads row-pair\n * order instead of raw view order, it — like `valueAtTSlot` already did —\n * calls `instanceRowPairsFromView` once per key that shares a category, and\n * most keys DO share one (`finxtract-bank-statement` alone backs 8 T-slot\n * base columns x up to 6 periods). Measured on the round-5 fixture: 504\n * T-slot `mapped` keys with a plain (non-instance) address, each rebuilding\n * `instanceRowPairsFromView` for its category from scratch before this fix.\n * A fresh cache per `flatRecordFromView` call turns that into one rebuild\n * per DISTINCT category actually visited.\n */\nfunction rowPairsCache(): RowPairsLookup {\n  const cache = new Map<AdapterCategory, InstanceRowPair[]>()\n  return (view, category) => {\n    const cached = cache.get(category)\n    if (cached) return cached\n    const pairs = instanceRowPairsFromView(view, category)\n    cache.set(category, pairs)\n    return pairs\n  }\n}\n\n/**\n * L-1 (round 5): whether two candidate values from different attestors count\n * as AGREEING, for `ambiguous` purposes — the SAME rule everywhere a\n * candidate-value comparison happens (this function, the `mapped-fanout`\n * disagreement check below). `===` alone is too strict: v1 stored some\n * values as decimal STRINGS where v2 types the equivalent canonical field as\n * a NUMBER (`flatRecordFromView`'s own \"VALUE COERCION: NONE\" section names\n * this exact mismatch), so two attestors reporting the literal same fact —\n * one via a v1-shaped string sidecar, one via a v2 numeric envelope — must\n * not read as a disagreement merely because of which JS type carried it.\n *\n * `looksNumeric` gates the numeric comparison so `null`/`undefined`/`false`\n * are never coerced through `Number(...)` (`Number(null) === 0` would read a\n * cleared field as agreeing with a real zero). Falls back to a plain\n * `String()` compare for anything that isn't numeric on both sides.\n */\nfunction looksNumeric(value: unknown): boolean {\n  if (typeof value === 'number') return !Number.isNaN(value)\n  if (typeof value === 'string' && value.trim() !== '') return !Number.isNaN(Number(value))\n  return false\n}\n\nfunction candidateValuesAgree(a: unknown, b: unknown): boolean {\n  if (a === b) return true\n  if (looksNumeric(a) && looksNumeric(b)) return Number(a) === Number(b)\n  return String(a) === String(b)\n}\n\n/**\n * `mapped` with a plain address: the value of the FIRST instance of\n * `address.category` that carries `address.field` at all —\n * `Object.prototype.hasOwnProperty`, not a truthy/defined check, because a\n * field explicitly asserting a falsy value (0, '', false) is still asserted.\n *\n * M-1 (round 5): \"first\" means the SAME period-sorted order the rendered\n * file-field tables use (`instanceRowPairsFromView`, via `rowPairsFor` —\n * L-4's call-local cache), not the view's raw extraction-array order, which\n * this used to read directly. Before this fix, a category whose upload\n * order disagreed with its period order (a later upload, earlier period —\n * exactly the shape F5 sorts for) could place THIS scalar from a DIFFERENT\n * document than the one the table's own T1 column shows for the SAME field\n * — one function telling a reader two different facts about the same slot.\n * `valueAtTSlot` already read the resolved rows for this reason; this makes\n * it one derivation for the whole function instead of two that could\n * silently disagree.\n *\n * `multiple: true` (L-1, round 5 — corrected from \"more than one instance\n * carries the field\"): only when a DIFFERING candidate value exists\n * (`candidateValuesAgree`), never merely because more than one instance\n * carries the field. Two SSM uploads reporting the identical `companyName`\n * are not a disagreement, and flagging them as one buried the keys that\n * genuinely disagree in noise.\n *\n * L-2 (round 5): \"first\" prefers the first instance whose value is NOT one\n * of `isSentinelValue`'s sentinels — the same rule `processIhsDetailsFromView`\n * applies before ever showing a value to a reviewer. Before this fix, an\n * earlier instance's blank/'Not Specified'/false could win the slot while a\n * LATER instance held the real value, so a scoring consumer of `record`\n * read the sentinel while the detail panel (reading the SAME view through\n * its own, per-instance loop) showed the real name. If every instance\n * carries only a sentinel, the first is placed anyway — v1's own wide\n * column held exactly that, and there is no better answer available.\n */\nfunction valueAtPlainAddress(view: CanonicalView, address: V1Address, rowPairsFor: RowPairsLookup): AddressLookup {\n  const instances = rowPairsFor(view, assertAdapterCategory(address.category)).map((p) => p.instance)\n  const withField = instances.filter((i) => Object.prototype.hasOwnProperty.call(i.fields, address.field))\n  if (withField.length === 0) return { found: false }\n  const values = withField.map((i) => i.fields[address.field]!.value)\n  const nonSentinelIndex = values.findIndex((v) => !isSentinelValue(v))\n  const index = nonSentinelIndex === -1 ? 0 : nonSentinelIndex\n  const multiple = values.some((v, i) => i !== index && !candidateValuesAgree(v, values[index]))\n  return { found: true, value: values[index], multiple }\n}\n\n/** `mapped` with `instanceKey`: the ONE instance whose `instanceKey` equals it. */\nfunction valueAtInstanceKey(view: CanonicalView, address: V1Address): AddressLookup {\n  const instances = view.categories[address.category]?.instances ?? []\n  const inst = instances.find((i) => i.instanceKey === address.instanceKey)\n  if (!inst || !Object.prototype.hasOwnProperty.call(inst.fields, address.field)) return { found: false }\n  return { found: true, value: inst.fields[address.field]!.value }\n}\n\n/**\n * `mapped` with `instanceKeyPrefix`: EVERY instance whose key equals the\n * prefix or continues it at a `#`-delimited boundary (`document-intake` keys\n * are `<docType>#<sha256>`), aggregated into the array shape v1 held.\n *\n * SYS-3596 — this used to return the FIRST match only, and defended that as\n * \"the stated parity choice\" on the premise that \"v1 held ONE value per\n * pointer column\". That premise was wrong, and this package contradicted it\n * in seventeen places: every migration-map entry resolving through this\n * function says \"SHAPE CHANGE, not a rename. The v1 column held a JSON array\n * of paths\". So six bank statements came back as one bare URL string, and\n * `buildDocumentRows` — which feeds the document table — rendered one row.\n * The other five were not listed, not downloadable, and (bankStatements and\n * financialStatements being re-uploadable) not replaceable either.\n *\n * It stayed invisible because nothing user-facing reads the bridged fields\n * today: finsys-client's detail page bypasses this bridge, and finsys-api\n * does not import `flatRecordFromView` at all. It stops being invisible at\n * Phase 6, when the flat columns drop and the published read has to be served\n * from the canonical plane.\n *\n * ORDERED BY `periodPosition`, not view order — the same 1-based ordinal the\n * rendered tables use, so the bridged list and the instance-shaped list agree\n * on sequence. Instances without one sort last, in view order, which is the\n * only stable answer when the plane does not say.\n *\n * Each entry carries `path`, plus `uploadedBy`/`createdAt` where the instance\n * has them. Not `documentId` — see the note at the derivation.\n *\n * OBJECTS, not bare strings, and this is load-bearing rather than cosmetic:\n * `parseFileField` returns an already-parsed array AS-IS, so an array of bare\n * paths would reach `buildDocumentRows` with `file.path === undefined` on\n * every entry — six rows, none downloadable. That would look like a fix\n * (it is an array!) while being worse than the collapse it replaced.\n *\n * `month`/`year` are NOT emitted. v1 carried a real calendar period;\n * `periodPosition` is an ordinal, not a date, and `document-intake` carries\n * no statement period. Deriving `month` from `periodPosition` would render a\n * confident T1..T6 that no data supports — the same reason\n * `ihsCanonicalReadService` omits `confidence` rather than guessing it, since\n * a fabricated value reads as evidence. The consumer's `timePeriod` therefore\n * falls back to 'ALL'; that residual is tracked rather than papered over.\n *\n * Still never contributes to `ambiguous`: N documents under one v1 key is the\n * DECLARED shape, not two attestors disagreeing about one fact.\n *\n * L-3 (round 5): a bare `startsWith(prefix)` — this function's old body —\n * matches any LONGER prefix too: `bankStatements` is a prefix of\n * `bankStatementsExtraordinary`, so a doc type introduced later whose name\n * extends an existing one would silently steal the shorter type's match\n * whenever it sorts first. The `#` boundary makes `bankStatements` match\n * only `bankStatements` itself or `bankStatements#<n>`, never a sibling doc\n * type that merely starts with the same letters.\n */\nfunction valueAtInstanceKeyPrefix(view: CanonicalView, address: V1Address): AddressLookup {\n  const instances = view.categories[address.category]?.instances ?? []\n  const prefix = address.instanceKeyPrefix!\n  // The `#` boundary is L-3's fix and still matters: a bare startsWith would\n  // let `bankStatements` swallow `bankStatementsExtraordinary`.\n  const matches = instances.filter(\n    (i) => i.instanceKey === prefix || i.instanceKey.startsWith(`${prefix}#`),\n  )\n  const withField = matches.filter((i) =>\n    Object.prototype.hasOwnProperty.call(i.fields, address.field),\n  )\n  if (withField.length === 0) return { found: false }\n\n  const ordered = withField\n    .map((inst, viewOrder) => ({ inst, viewOrder }))\n    .sort((a, b) => {\n      const pa = a.inst.periodPosition\n      const pb = b.inst.periodPosition\n      if (pa !== undefined && pb !== undefined) return pa - pb || a.viewOrder - b.viewOrder\n      if (pa !== undefined) return -1\n      if (pb !== undefined) return 1\n      return a.viewOrder - b.viewOrder\n    })\n    .map(({ inst }) => {\n      const entry: Record<string, unknown> = { path: inst.fields[address.field]!.value }\n      // No `documentId` here, deliberately. `documentHashOfKey` looks like the\n      // right source and is NOT: it returns the segment BEFORE the `#`, so on\n      // a `<docType>#<n>` intake key it yields \"bankStatements\", the doc type.\n      // `buildDocumentRows` already derives the id from the path's last\n      // segment — the actual DMS content hash — so emitting a wrong one here\n      // would override a correct derivation with the field name.\n      const uploadedBy = inst.fields.uploadedBy?.value\n      if (uploadedBy !== undefined) entry.uploadedBy = uploadedBy\n      const uploadedAt = inst.fields.uploadedAt?.value\n      if (uploadedAt !== undefined) entry.createdAt = uploadedAt\n      return entry\n    })\n\n  return { found: true, value: ordered }\n}\n\n/**\n * A T-slot family member (`bankBalanceT1`, …): the row at this exact period,\n * read the same way the rendered file-field tables read it — `base` is the\n * shared legacy name every sibling in the family strips to\n * (`v1LegacyBaseNameOf`, not a second regex-strip here: reusing it means this\n * can never disagree with what `instanceRowsFromView` actually wrote onto the\n * row), and the row itself comes from `rowPairsFor` (L-4's call-local cache\n * of `instanceRowPairsFromView`) — the SAME rows and the SAME `timePeriodOf`\n * cascade the rendered tables use — not a second derivation of \"which period\n * is this\" that could silently disagree with what a reader sees on the\n * file-field table for the same instance.\n *\n * M-2 (round 5): a T-slot key names a SLOT, not an INSTANCE — `buildInstanceTable`\n * happily renders two columns for two rows sharing one period label, but this\n * function can only ever place ONE value under the key. More than one row\n * sharing `tSlot` used to pick silently, with no signal that a second,\n * un-placed row existed; `multiple: true` surfaces that choice into\n * `ambiguous`, the same way the plain-address lookup already does for its own\n * multi-instance case.\n *\n * SYS-3526 — WHICH one it picks is LAST, not first, and that is the whole of\n * this fix. Three consumers resolve a contested slot and this was the only one\n * that disagreed:\n *\n *   v1                 `ihsService.getIhsDetailsById` merges each sibling\n *                      row's `toSuffixedObject()` into ONE accumulating object\n *                      under `order: { id: \"ASC\" }` — the LAST row by id owns\n *                      the slot. All four tables that reach this lookup carry\n *                      that clause, under finsys-api's own SYS-2916 comment\n *                      naming \"the suffixed spread's later-masks-earlier\n *                      behavior\" as a contract rather than an accident.\n *   v2 instance path   finsys-client `selectFinancialRow` — last matching row\n *                      wins, over `instanceRowsFromView`'s rows.\n *   v2 flat path       THIS function, which took `withField[0]`.\n *\n * finsys-api #611 added `order: { id: \"ASC\" }` to the v2 read, which is what\n * the other two consumers need and what its own shipped comment says it is\n * for. It also made this path deterministically wrong rather than\n * accidentally so: `withField[0]` became guaranteed to be the OLDEST row.\n *\n * \"LAST\" IS LAST-BY-ARRIVAL, and that holds because of two facts, not one:\n * the emitter now hands over rows in id order, and `instanceRowPairsFromView`\n * does not destroy it — its F5 period sort is STABLE, and every row in\n * `withSlot` shares a period by construction, so those rows are still in the\n * view's own emission order when they get here. Both halves are pinned by\n * tests; neither is assumed.\n *\n * TWO SHAPES WHERE THIS IS STILL NOT EXACTLY v1, neither reachable from this\n * package, both named so nobody re-derives them as bugs:\n *\n *  1. v1 overwrites with NULL. `toSuffixedObject()` emits every non-excluded\n *     column including a null one, so a later row's null blanks an earlier\n *     row's real value. `projectInstance` OMITS a null field from the\n *     canonical instance (deliberately: a gated field and a never-produced\n *     field must be indistinguishable, so both are absent), so a null is not\n *     a candidate here at all — `withField` cannot see it, and this answers\n *     the earlier row's value where v1 answered null.\n *  2. v1 pre-filters by recency BEFORE spreading — financial statements drop\n *     a T1 row whose `financialYearEnd` is not the newest (SYS-2972), bank\n *     statements keep only the newest `statementDate` per period (SYS-2979);\n *     EPF and payslip have no filter, so for them v1 is pure\n *     last-write-wins. `financialYearEnd` has no v1 wide column at all, so it\n *     never reaches an `InstanceRow` and that filter is not expressible here.\n *     Replicating either would make this function a SECOND implementation of\n *     \"which document is newest\" — the drift SYS-2994 was filed to stop on\n *     the finsys-api side — so it deliberately does not. Where a filter would\n *     change the answer, first-match was not right either; last-match is\n *     right whenever the newer document has the higher id, which is the\n *     ordinary case and the measured one.\n */\nfunction valueAtTSlot(view: CanonicalView, address: V1Address, tSlot: string, rowPairsFor: RowPairsLookup): AddressLookup {\n  // L-5 (round 5): three DISTINCT not-found causes, each its own `reason` —\n  // `flatRecordFromView` used to report ONE fixed string (\"no T{n}\n  // instance\") regardless of which of these three actually happened, which\n  // reads identically to a reader whether the address has no base name at\n  // all, the slot has no row, or the row exists but never carried this\n  // field. (The first cause is DEFENSIVE: every T-slot `mapped` key's own\n  // address always contributes its base to `v1LegacyBaseNameOf`'s index —\n  // see that function's own doc — so it is unreachable via `v1MigrationKeys()`\n  // today; named anyway so a future change to that invariant fails loud\n  // rather than falling back to a misleading \"no row\" message.)\n  const base = v1LegacyBaseNameOf(address.category, address.field)\n  if (base === null) return { found: false, reason: 'no legacy base name' }\n  const rows = rowPairsFor(view, assertAdapterCategory(address.category)).map((p) => p.row)\n  const withSlot = rows.filter((r) => r.timePeriod === tSlot)\n  if (withSlot.length === 0) return { found: false, reason: `no ${tSlot} row` }\n  const withField = withSlot.filter((r) => Object.prototype.hasOwnProperty.call(r, base))\n  if (withField.length === 0) return { found: false, reason: `${tSlot} row lacks ${base}` }\n  // SYS-3526: the LAST row that carries the field, not the first — see this\n  // function's doc for the three-consumer disagreement this closes, and for\n  // why \"last\" is last-by-arrival here rather than merely last-in-array.\n  return { found: true, value: withField[withField.length - 1]![base], multiple: withField.length > 1 }\n}\n\n/**\n * The v1 flat record's shape, re-derived from a `CanonicalView` — the\n * migration map (`src/v1-migration-map.ts`) run FORWARD. `record` is\n * OPTIONAL: pass it to place the `relocated` keys too (the application\n * record's own surface, NOT adapter data — see below); omit it and every\n * `relocated` key reports `unplaced` instead of throwing.\n *\n * ITERATES `v1MigrationKeys()`, NOT `view.categories` — deliberately, so a\n * v1 key with no v2 value today is a REPORTED fact (`unplaced`), never a\n * silently absent one; this is how a parity spec finds its residuals. Per\n * key, dispatch on the map entry's OWN disposition:\n *\n * - `mapped` with `instanceKeyPrefix`: `valueAtInstanceKeyPrefix` (first\n *   instance whose key equals the prefix or continues it at a `#` boundary\n *   (L-3, round 5 — never a bare `startsWith`, which a longer sibling prefix\n *   could steal) — v1 held one path per pointer column, so first-in-order is\n *   the parity choice).\n * - `mapped` with `instanceKey`: `valueAtInstanceKey` (the one instance\n *   naming it).\n * - `mapped`, key ends in a bare `T[1-9]` (`T_SLOT_KEY_SUFFIX` — the\n *   `(PriorYear)?` branch is unreachable for `mapped` post-round-2, see that\n *   const's doc): `valueAtTSlot` — the T-slot family row lookup. A miss\n *   distinguishes THREE causes (L-5, round 5 — see that function's own doc):\n *   `'no legacy base name'`, `'no T{n} row'`, `'T{n} row lacks <base>'`.\n * - `mapped`, anything else: `valueAtPlainAddress` — the single-instance\n *   scalar read, `ambiguous` on a real collision.\n * - `mapped-fanout` (`incorporatedDate` only, today): resolve BOTH addresses\n *   via `valueAtPlainAddress`, in the map's own address order; place the\n *   FIRST one with a value; if a second address also has a value and it\n *   DIFFERS from the first, or either address's own lookup was itself\n *   ambiguous, record `ambiguous`. Neither address having a value → `unplaced`.\n * - `relocated`: the three top-level specials read straight off `record`\n *   (`ihsId` <- `applicationId`, `status` <- `status`, `statusDescription` <-\n *   `statusDescription`); every other relocated key walks `record.parties`\n *   -> `record.facility` -> `record.system`, PRESENCE not nullishness (H-2,\n *   round 5 — `relocatedBucketValue`, corrected from a `??` chain that fell\n *   through an explicit `null` in an earlier bucket to a LATER bucket that\n *   also happened to carry the key, silently returning the wrong bucket's\n *   value). A bucket's `null` is placed as `null` — v1 served null for an\n *   empty relocated column, and that is a real assertion, not \"try the next\n *   bucket\". `record` undefined, or the key present in NONE of the buckets\n *   -> `unplaced`, reason `` `relocated (surface: ${entry.surface}): not on\n *   the application record` `` (M-3, round 5 — names the surface so a\n *   parity spec can tell \"the record genuinely does not carry this\" from\n *   \"the caller forgot a bucket\"; 48 of 51 relocated keys carry\n *   `GET /lender/applications/:ihsId`, 3 carry the consent engine).\n * - `retired`, `vocabulary-gap`, `needs-decision`, `mapped-pending-build`,\n *   `structural`, `withheld`: NEVER placed, regardless of what the view holds —\n *   `unplaced` with the map entry's own `note`/`reason` string (never\n *   empty in the current map for these five dispositions). `structural`\n *   covers seven entries: the four instance sidecars this function DOES\n *   still surface, via the separate `instances` member below (NOT a member\n *   of `record` — v1 shipped them as sibling arrays beside the flat record,\n *   not flat keys, and this function keeps that shape); `documentMetadata`\n *   (v1's sidecar for File name/type/size — v2 carries that as canonical\n *   `document-intake` fields, so it has no destination of its OWN); `fieldProvenance`\n *   (v1's sidecar map — superseded by the per-value envelope; see\n *   `fieldProvenanceFromView`, which is the v2 equivalent for a caller that\n *   wants it); `invoiceInstances` (no invoice category exists in the\n *   registry yet).\n *\n * VALUE COERCION: NONE. Whatever the envelope (or, for a T-slot key, the\n * `InstanceRow`) holds is placed verbatim — v2 types some values v1 stored\n * as strings (e.g. a decimal) as numbers; the consumer's own `coerceFieldValue`\n * already handles both, and stringifying here would be a second, competing\n * opinion about the value's type.\n *\n * THE OVERLAY PROJECTION: nothing to do, deliberately. When `view` was read\n * under the lender-overlay projection (`?overlay=mine`), an overlaid\n * envelope's `value` already IS the overlaid one — the same thing v1's own\n * details-merge did — so every placement above reads it through unchanged.\n * `originalValue` (the attested value an overlay replaced) has no v1-shaped\n * home; a caller that needs it reads `fieldProvenanceFromView`'s\n * `IhsFieldProvenanceWithOriginal.originalValue` instead.\n */\nexport function flatRecordFromView(view: CanonicalView, record?: ApplicationRecordLike): FlatRecordFromView {\n  const out: Record<string, unknown> = {}\n  const unplaced: { key: string; disposition: string; reason: string }[] = []\n  const ambiguous: string[] = []\n  // L-4 (round 5): one row-pairs rebuild per category per CALL, not per key.\n  const rowPairsFor = rowPairsCache()\n\n  for (const key of v1MigrationKeys()) {\n    const entry = v1MigrationEntry(key)! // key came from the map itself; never null\n\n    if (entry.disposition === 'mapped') {\n      const address = entry.address!\n      let result: AddressLookup\n      let missingReason: string\n\n      if (address.instanceKeyPrefix !== undefined) {\n        result = valueAtInstanceKeyPrefix(view, address)\n        missingReason = 'mapped: no instance with this key prefix'\n      } else if (address.instanceKey !== undefined) {\n        result = valueAtInstanceKey(view, address)\n        missingReason = 'mapped: no instance with this instance key'\n      } else {\n        const tSlotMatch = T_SLOT_KEY_SUFFIX.exec(key)\n        if (tSlotMatch) {\n          const tSlot = `T${tSlotMatch[1]}`\n          result = valueAtTSlot(view, address, tSlot, rowPairsFor)\n          // L-5 (round 5): `result.reason` names WHICH of the three distinct\n          // causes applied; the fallback below is defensive only — every\n          // real miss from `valueAtTSlot` sets one.\n          missingReason = result.reason ?? `no ${tSlot} instance`\n        } else {\n          result = valueAtPlainAddress(view, address, rowPairsFor)\n          missingReason = 'mapped: no instance carries this field'\n        }\n      }\n\n      if (result.found) {\n        out[key] = result.value\n        if (result.multiple) ambiguous.push(key)\n      } else {\n        unplaced.push({ key, disposition: entry.disposition, reason: missingReason })\n      }\n    } else if (entry.disposition === 'mapped-fanout') {\n      const addresses = entry.addresses!\n      let placedValue: unknown\n      let placed = false\n      let anyMultiple = false\n      const foundValues: unknown[] = []\n\n      for (const address of addresses) {\n        const r = valueAtPlainAddress(view, address, rowPairsFor)\n        if (r.multiple) anyMultiple = true\n        if (r.found) {\n          foundValues.push(r.value)\n          if (!placed) {\n            placedValue = r.value\n            placed = true\n          }\n        }\n      }\n\n      if (placed) {\n        out[key] = placedValue\n        // L-1 (round 5): the SAME agreement rule the plain-address lookup\n        // uses — a strict `!==` flagged two attestors reporting the\n        // identical fact under different JS types (a v1 decimal string vs a\n        // v2 typed number) as a disagreement.\n        const disagree = foundValues.some((v) => !candidateValuesAgree(v, foundValues[0]))\n        if (anyMultiple || disagree) ambiguous.push(key)\n      } else {\n        unplaced.push({ key, disposition: entry.disposition, reason: 'mapped-fanout: neither address has a value' })\n      }\n    } else if (entry.disposition === 'relocated') {\n      let found: boolean\n      let value: unknown\n      if (key === 'ihsId') {\n        value = record?.applicationId\n        found = value !== undefined\n      } else if (key === 'status') {\n        value = record?.status\n        found = value !== undefined\n      } else if (key === 'statusDescription') {\n        value = record?.statusDescription\n        found = value !== undefined\n      } else {\n        const lookup = relocatedBucketValue(record, key)\n        found = lookup.found\n        value = lookup.value\n      }\n\n      if (found) out[key] = normalizeRelocatedValue(value)\n      else {\n        // M-3 (round 5): names the SURFACE (`entry.surface` — 48 of 51\n        // relocated keys are `GET /lender/applications/:ihsId`, 3 are the\n        // consent engine) so a parity spec can tell \"the record genuinely\n        // does not carry this\" from \"the caller forgot a bucket\" — the old\n        // bare string read identically for both.\n        unplaced.push({\n          key,\n          disposition: entry.disposition,\n          reason: `relocated (surface: ${entry.surface ?? 'unknown'}): not on the application record`,\n        })\n      }\n    } else {\n      // retired, vocabulary-gap, structural, needs-decision, mapped-pending-build,\n      // withheld: never placed, regardless of what the view holds.\n      //\n      // SYS-3604 — `withheld` lands here rather than in the `relocated` branch\n      // above, and that is the point of it existing. `relocated` LOOKS THE KEY\n      // UP in the application record and, on a miss, emits a reason quoting\n      // `entry.surface`. For a key the successor deliberately refuses, that\n      // told the caller to fetch from an endpoint that will not answer. Here\n      // the reason is the map's own, which says plainly that there is nowhere\n      // to go.\n      unplaced.push({ key, disposition: entry.disposition, reason: entry.note ?? entry.reason ?? '' })\n    }\n  }\n\n  return {\n    record: out,\n    unplaced,\n    ambiguous,\n    instances: {\n      financialStatementInstances: instanceRowsFromView(view, assertAdapterCategory('financial-statement')),\n      bankStatementInstances: instanceRowsFromView(view, assertAdapterCategory('finxtract-bank-statement')),\n      epfStatementInstances: instanceRowsFromView(view, assertAdapterCategory('epf-statement')),\n      payslipInstances: instanceRowsFromView(view, assertAdapterCategory('payslip')),\n    },\n  }\n}\n","/*\n * Copyright 2025 Sisters Inspire Sdn Bhd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Program access roles — shared across finsys-api and finhub-adonisjs.\n * Values must match the database enum column in the `programaccess` table.\n */\nexport enum Role {\n  ADMIN = 'Admin',\n  BORROWER_AGENT = 'Borrower Agent',\n  LENDER_AGENT = 'Lender Agent',\n}\n","/*\n * Copyright 2025 Sisters Inspire Sdn Bhd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Status of a document extraction job.\n * Used by finsys-api (writes) and finhub/finsys-client (reads/displays).\n */\nexport enum ExtractionJobStatus {\n  Queued = 'queued',\n  Processing = 'processing',\n  Succeeded = 'succeeded',\n  Failed = 'failed',\n}\n\n/**\n * Document types that go through FinXtract extraction. Values must match\n * the `type` field on finsys-api's File entity and the config keys in\n * finXtractApi.api.\n *\n * Was a closed enum (FinancialStatement/BankStatement/Epf/Payslip/Ssm/\n * Form9/Ic) requiring a core release to add a new document type, even\n * though nothing outside finsys-api's own request validation actually\n * needed it to be a closed set (confirmed: zero external consumers\n * import a specific member by name). Now an open string, matching the\n * AdapterCategory precedent (SYS-2500) -- the authoritative set of valid\n * values lives in document-types.ts, derived from the field-spec catalog.\n * Use isDocumentType()/assertDocumentType() from document-types.ts for\n * the runtime validation that used to be the enum's job.\n */\nexport type ExtractionFileType = string\n","/*\n * Copyright 2025 Sisters Inspire Sdn Bhd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * IHS application status — canonical source of truth, mirroring finsys-api's\n * `IHS_STATUS` enum and `allowedIhsStatus` list in src/utils/appHelper.ts.\n *\n * finsys-api originates these values (it writes them to the `ihs.status`\n * column). Consumer apps (finhub-adonisjs, finsys-client) read them off the\n * wire and use them for validation and display.\n *\n * Lender rejection is not represented by a distinct status: when a lender\n * rejects an application, finsys-api transitions the record back to\n * `APPLICATION_FINALIZED` from `LENDER_EVALUATION`.\n *\n * `EditingApplication` (SYS-2806) is a lender-scoped detour off\n * `LenderEvaluation` for manually editing extracted field values — not\n * reachable from `ApplicationFinalized`. A lender toggles into it and back\n * out to `LenderEvaluation`; it never appears on a record no lender has\n * claimed. See finsys-api's `updateIhsStatusByLender` for the transition\n * guard.\n */\nexport enum IhsStatus {\n  CreatingApplication = 'CREATING_APPLICATION',\n  ApplicationFinalized = 'APPLICATION_FINALIZED',\n  LenderEvaluation = 'LENDER_EVALUATION',\n  EditingApplication = 'EDITING_APPLICATION',\n  Approved = 'APPROVED',\n  LouDelivered = 'LOU_DELIVERED',\n  AwaitingDisbursement = 'AWAITING_DISBURSEMENT',\n  Disbursement = 'DISBURSEMENT',\n  Declined = 'DECLINED',\n  Expired = 'EXPIRED',\n  Canceled = 'CANCELED',\n}\n\n/**\n * All valid IHS status values, in display order (earliest lifecycle stage\n * first, terminal states last).\n */\nexport const IHS_VALID_STATUSES: readonly IhsStatus[] = [\n  IhsStatus.CreatingApplication,\n  IhsStatus.ApplicationFinalized,\n  IhsStatus.LenderEvaluation,\n  IhsStatus.EditingApplication,\n  IhsStatus.Approved,\n  IhsStatus.LouDelivered,\n  IhsStatus.AwaitingDisbursement,\n  IhsStatus.Disbursement,\n  IhsStatus.Declined,\n  IhsStatus.Expired,\n  IhsStatus.Canceled,\n] as const\n\n/**\n * Terminal statuses — the application lifecycle has completed and no further\n * transitions are expected. Useful for suppressing action UI (e.g. re-extract,\n * status update controls) on the application detail view.\n */\nexport const IHS_TERMINAL_STATUSES: readonly IhsStatus[] = [\n  IhsStatus.Disbursement,\n  IhsStatus.Declined,\n  IhsStatus.Expired,\n  IhsStatus.Canceled,\n] as const\n\n/**\n * Failure statuses — a subset of terminal statuses that represent an\n * unsuccessful outcome. Useful for badge colour / messaging.\n */\nexport const IHS_FAILURE_STATUSES: readonly IhsStatus[] = [\n  IhsStatus.Declined,\n  IhsStatus.Expired,\n  IhsStatus.Canceled,\n] as const\n\n/**\n * Type guard: narrows an unknown value to `IhsStatus` iff it is one of the\n * canonical status strings.\n */\nexport function isValidIhsStatus(status: unknown): status is IhsStatus {\n  return (\n    typeof status === 'string' &&\n    (IHS_VALID_STATUSES as readonly string[]).includes(status)\n  )\n}\n\n/**\n * Type guard: terminal (no further transitions expected).\n */\nexport function isTerminalIhsStatus(status: unknown): status is IhsStatus {\n  return (\n    typeof status === 'string' &&\n    (IHS_TERMINAL_STATUSES as readonly string[]).includes(status)\n  )\n}\n\n/**\n * Type guard: terminal and unsuccessful.\n */\nexport function isFailureIhsStatus(status: unknown): status is IhsStatus {\n  return (\n    typeof status === 'string' &&\n    (IHS_FAILURE_STATUSES as readonly string[]).includes(status)\n  )\n}\n","/*\n * Extraction status resolution.\n *\n * Determines per-document extraction status from IHS record data\n * and optional extraction job records. Pure synchronous function —\n * no HTTP, no async, trivially testable.\n *\n * For multi-file document types (bank statements, financial statements,\n * EPF, payslips), produces one result per time period (T1, T2, …).\n * For single-file types (SSM, Form 9, IC), produces one result.\n */\n\nimport { ExtractionFileType, ExtractionJobStatus } from './extraction.js'\nimport { getDocumentTypeGroups } from './document-types.js'\nimport type { FieldData } from './survey-generator.js'\nimport { categoryFieldsOf, type AdapterCategory } from './adapter-categories.js'\nimport { extractionCategoryOf, documentsOfType } from './ihs-processing.js'\nimport type { CanonicalView, CanonicalInstance } from './canonical-view.js'\n\n// ── Types ──────────────────────────────────────────────────\n\nexport enum DocExtractionStatus {\n  NotUploaded = 'not_uploaded',\n  Uploaded = 'uploaded',\n  Queued = 'queued',\n  Processing = 'processing',\n  Extracted = 'extracted',\n  Failed = 'failed',\n  Unknown = 'unknown',\n}\n\nexport interface ExtractionJobRecord {\n  fileType: string\n  status: string\n  errorMessage?: string | null\n}\n\nexport interface DocExtractionResult {\n  fileType: ExtractionFileType\n  status: DocExtractionStatus\n  displayName: string\n  populatedColumns: string[]\n  totalColumns: number\n  errorMessage?: string | null\n  /**\n   * SYS-3378: the document's DMS content hash — present on the instance-shaped\n   * path, absent on the flat one. The join key to `DocumentRow.documentId`, so\n   * a consumer can overlay status by identity rather than by (fileType, index).\n   */\n  documentId?: string\n  /**\n   * SYS-3334: set only on the instance-shaped path, for a document known from\n   * its extraction instances alone — no intake row names it. Either an upload\n   * that predates the intake writer, or a join miss between an intake path and\n   * an extraction key. Kept observable so a join regression cannot masquerade\n   * as a pre-writer upload.\n   */\n  unlinked?: true\n}\n\nexport interface ExtractionStatusResult {\n  documents: DocExtractionResult[]\n  summary: {\n    total: number\n    extracted: number\n    failed: number\n    pending: number\n    notUploaded: number\n  }\n}\n\n// ── Helpers ────────────────────────────────────────────────\n\nfunction isPopulated(value: unknown): boolean {\n  if (value === null || value === undefined || value === '') return false\n  if (value === 'Not Specified') return false\n  return true\n}\n\nfunction countUploadedFiles(ihsRecord: Record<string, unknown>, aggregateKey: string): number {\n  const raw = ihsRecord[aggregateKey]\n  if (!raw) return 0\n\n  // JSON array string (multi-file types like bankStatements)\n  if (typeof raw === 'string') {\n    try {\n      const parsed = JSON.parse(raw)\n      if (Array.isArray(parsed)) return parsed.length\n    } catch {\n      // Plain URL string (single-file type) — count as 1\n      return 1\n    }\n  }\n\n  if (Array.isArray(raw)) return raw.length\n\n  // Single object or URL string\n  return 1\n}\n\nfunction hasUploadedFile(\n  fields: FieldData[],\n  ihsRecord: Record<string, unknown>,\n  aggregateKey: string\n): boolean {\n  if (countUploadedFiles(ihsRecord, aggregateKey) > 0) return true\n\n  // Fall back to individual field names for single-file types (ssm, form9, ic)\n  return fields.some((field) => {\n    if (!field.name) return false\n    return isPopulated(ihsRecord[field.name])\n  })\n}\n\nfunction getPopulatedColumns(\n  columns: string[],\n  ihsRecord: Record<string, unknown>\n): string[] {\n  return columns.filter((col) => isPopulated(ihsRecord[col]))\n}\n\n/**\n * Resolve status for a single document (one field / one time period).\n */\nfunction resolveDocStatus(\n  columns: string[],\n  ihsRecord: Record<string, unknown>,\n  uploaded: boolean,\n  jobRecord: ExtractionJobRecord | undefined,\n  hasJobRecords: boolean\n): { status: DocExtractionStatus; errorMessage?: string | null } {\n  const populated = getPopulatedColumns(columns, ihsRecord)\n  const hasExtractedData = populated.length > 0\n\n  let status: DocExtractionStatus\n  let errorMessage: string | null | undefined\n\n  if (!uploaded) {\n    status = DocExtractionStatus.NotUploaded\n  } else if (hasJobRecords) {\n    if (jobRecord) {\n      if (jobRecord.status === ExtractionJobStatus.Queued) {\n        status = DocExtractionStatus.Queued\n      } else if (jobRecord.status === ExtractionJobStatus.Processing) {\n        status = DocExtractionStatus.Processing\n      } else if (jobRecord.status === ExtractionJobStatus.Failed) {\n        if (hasExtractedData) {\n          status = DocExtractionStatus.Extracted\n          errorMessage = jobRecord.errorMessage\n        } else {\n          status = DocExtractionStatus.Failed\n          errorMessage = jobRecord.errorMessage\n        }\n      } else if (jobRecord.status === ExtractionJobStatus.Succeeded || hasExtractedData) {\n        status = DocExtractionStatus.Extracted\n      } else {\n        status = DocExtractionStatus.Uploaded\n      }\n    } else if (hasExtractedData) {\n      status = DocExtractionStatus.Extracted\n    } else {\n      status = DocExtractionStatus.Uploaded\n    }\n  } else if (hasExtractedData) {\n    status = DocExtractionStatus.Extracted\n  } else {\n    status = DocExtractionStatus.Unknown\n  }\n\n  return { status, errorMessage }\n}\n\n// ── Main function ──────────────────────────────────────────\n\n/**\n * Determines per-document extraction status from IHS record data.\n *\n * For multi-file document types (bank statements, financial statements, EPF,\n * payslips) the result contains one entry per uploaded file, indexed in the\n * same order as the files appear in the IHS record's aggregate array.\n * For single-file types (SSM, Form 9, IC) there is one entry.\n *\n * @param ihsRecord - The IHS application record (any shape satisfying Record<string, unknown>)\n * @param jobRecords - Extraction job records for this IHS. Pass the array (even if empty)\n *   when job records were fetched. Omit or pass undefined when job records are unavailable;\n *   this produces `Unknown` status for uploaded-but-unextracted documents rather than `Uploaded`.\n */\nexport function resolveExtractionStatus(\n  ihsRecord: Record<string, unknown>,\n  jobRecords?: ExtractionJobRecord[]\n): ExtractionStatusResult {\n  const documents: DocExtractionResult[] = []\n  const hasJobRecords = jobRecords !== undefined\n\n  for (const group of getDocumentTypeGroups()) {\n    const fileType = group.documentType\n    const fields = group.fields\n    const displayName = group.label\n\n    const uploadedCount = countUploadedFiles(ihsRecord, fileType)\n    const isUploaded = uploadedCount > 0 || fields.some((f) => f.name && isPopulated(ihsRecord[f.name]))\n\n    // For multi-file types, match job records by fileType (there can be multiple)\n    const matchingJobs = jobRecords?.filter((j) => j.fileType === fileType) ?? []\n\n    if (fields.length <= 1) {\n      // Single-file type (ssm, form9, ic): one result\n      const field = fields[0]\n      const columns = field?.ihs_column_names ?? []\n      const populated = getPopulatedColumns(columns, ihsRecord)\n      const { status, errorMessage } = resolveDocStatus(\n        columns, ihsRecord, isUploaded, matchingJobs[0], hasJobRecords\n      )\n\n      documents.push({\n        fileType,\n        status,\n        displayName,\n        populatedColumns: populated,\n        totalColumns: columns.length,\n        errorMessage,\n      })\n    } else {\n      // Multi-file type (bank statements T1-T6, etc.): one result per uploaded file.\n      // Fields are sorted by name (bank_statement_t1, t2, …) so idx aligns with\n      // the file array order in the IHS record.\n      const count = Math.max(uploadedCount, 1)\n      for (let idx = 0; idx < count; idx++) {\n        const field = fields[idx]\n        const columns = field?.ihs_column_names ?? []\n        const populated = getPopulatedColumns(columns, ihsRecord)\n        const fileUploaded = idx < uploadedCount\n        const { status, errorMessage } = resolveDocStatus(\n          columns, ihsRecord, fileUploaded, matchingJobs[idx], hasJobRecords\n        )\n\n        documents.push({\n          fileType,\n          status,\n          displayName,\n          populatedColumns: populated,\n          totalColumns: columns.length,\n          errorMessage,\n        })\n      }\n    }\n  }\n\n  const summary = documents.reduce(\n    (acc, d) => {\n      if (d.status === DocExtractionStatus.Extracted) acc.extracted++\n      else if (d.status === DocExtractionStatus.Failed) acc.failed++\n      else if (d.status === DocExtractionStatus.NotUploaded) acc.notUploaded++\n      else acc.pending++\n      return acc\n    },\n    { total: documents.length, extracted: 0, failed: 0, pending: 0, notUploaded: 0 }\n  )\n\n  return { documents, summary }\n}\n\n// ── Instance-shaped resolution (SYS-3334) ──────────────────────────\n\n/**\n * `resolveExtractionStatus` for a v2 `CanonicalView`. Same result type, same\n * status vocabulary, same job-record semantics — but this is a RE-DERIVATION,\n * not a port, and three things were decided rather than translated. Each is\n * pinned by a test in extraction-status.test.ts that fails if it drifts.\n *\n * 1. UPLOADED means \"a document of this type is attested\". v1 counted the\n *    entries of the pointer column (`bankStatements` JSON array). v2 counts\n *    the documents known to the view: `document-intake` instances of that\n *    `documentType`, UNIONED with the extraction category's instances (an\n *    extracted document was necessarily uploaded — this covers uploads that\n *    predate the intake writer). Measured against v1 on 189 sim subjects ×\n *    7 types: 1321 of 1323 agree; the two that do not are one pre-writer\n *    upload (v2 now says uploaded, via the union) and one replaced file,\n *    where the append-only intake keeps the superseded write. That last one\n *    is a real semantic difference — attested writes vs current pointer —\n *    and it is stated here rather than papered over.\n *\n * 2. PER-DOCUMENT STATUS is joined by identity, not by position. v1 aligned\n *    upload index i with T-slot column family i and job record i. v2 joins an\n *    intake instance to its extraction instances by the document's DMS hash —\n *    intake's `pathInDms` tail IS the extraction key's hash\n *    (`bankStatement:<hash>`, `financialStatement:<hash>#T2` — period rows of\n *    one document are grouped). A document with no extraction instance is\n *    uploaded-but-not-extracted — exactly the case the panel exists to show.\n *    Measured: 520 of 670 intake instances join; the 150 that do not are that\n *    case. Job records still carry only fileType and order, so they are\n *    aligned positionally — but ONLY to the intake-ordered prefix, never to an\n *    extraction-only document that was never in the pointer array. One shift\n *    remains and is stated: intake is append-only, so a REPLACED file keeps\n *    its superseded row, and a positional job after that point lands one\n *    document later than v1 would have put it. Measured 1 of 1323 documents.\n *\n * 3. THE DENOMINATOR is the registry's field set for the extraction category\n *    — what the adapter DECLARES it produces — not the form spec's column\n *    list for a T-slot. v1's `totalColumns` was that slot's width: equal to\n *    the registry for bank (8), payslip (15), EPF (9), IC (9), SSM (16) and\n *    Form 9 (3) — and, for financial statements, 13 on the first slot then 0\n *    on the second, because v1's financial slots were misaligned with its\n *    documents. So the ONLY user-visible denominator change is financial\n *    statements: 13 → 123 on the first document and 0 → 123 on the rest, and\n *    that is a correction. The test pins BOTH sides — the flat path's numbers\n *    next to the registry's — so a drift on either is a decision.\n *\n * `populatedColumns` are CANONICAL field names now (`closingBalance`, not\n * `bankBalanceT1`). Same information, right vocabulary; consumers rendering\n * the names see that change.\n */\nexport function resolveExtractionStatusFromView(\n  view: CanonicalView,\n  jobRecords?: ExtractionJobRecord[]\n): ExtractionStatusResult {\n  const documents: DocExtractionResult[] = []\n  const hasJobRecords = jobRecords !== undefined\n  const intake = view.categories['document-intake']?.instances ?? []\n\n  for (const group of getDocumentTypeGroups()) {\n    const fileType = group.documentType\n    const displayName = group.label\n    const category = extractionCategoryOf(fileType)\n    const declared = category ? categoryFieldsOf(category as AdapterCategory) : []\n    const extracted = category ? (view.categories[category]?.instances ?? []) : []\n    const matchingJobs = jobRecords?.filter((j) => j.fileType === fileType) ?? []\n\n    // The documents of this type, in the ONE order both instance-shaped\n    // functions use (see documentsOfType): intake first, then extracted\n    // documents intake does not know. A document is the group of its\n    // extraction instances (`#T1`, `#T2` period rows), extracted if any of\n    // them carries data.\n    const uploads = documentsOfType(view, intake, fileType)\n\n    if (uploads.length === 0) {\n      // Not uploaded: v1 emitted one NotUploaded row per type (single-file\n      // types always; multi-file types via max(count, 1)). Same here.\n      const { status, errorMessage } = classify(false, false, matchingJobs[0], hasJobRecords)\n      documents.push({ fileType, status, displayName, populatedColumns: [], totalColumns: declared.length, errorMessage })\n      continue\n    }\n\n    uploads.forEach((u, idx) => {\n      const populated = populatedFields(u.extraction, declared)\n      // A positional job record is only meaningful against the intake-ordered\n      // prefix — the same order the pointer array had. An extraction-only\n      // document was never in that array, so no job may be aligned to it;\n      // `classify` without a job degrades to Uploaded/Extracted correctly.\n      const job = u.origin === 'intake' ? matchingJobs[idx] : undefined\n      const { status, errorMessage } = classify(true, populated.length > 0, job, hasJobRecords)\n      documents.push({\n        fileType, status, displayName, populatedColumns: populated, totalColumns: declared.length, errorMessage,\n        ...(u.hash !== null ? { documentId: u.hash } : {}),\n        ...(u.origin === 'extraction-only' ? { unlinked: true } : {}),\n      })\n    })\n  }\n\n  return { documents, summary: summarize(documents) }\n}\n\n/** The status decision, shared with the flat resolver's rules exactly. */\nfunction classify(\n  uploaded: boolean,\n  hasExtractedData: boolean,\n  jobRecord: ExtractionJobRecord | undefined,\n  hasJobRecords: boolean\n): { status: DocExtractionStatus; errorMessage?: string | null } {\n  if (!uploaded) return { status: DocExtractionStatus.NotUploaded }\n  if (hasJobRecords) {\n    if (jobRecord) {\n      if (jobRecord.status === ExtractionJobStatus.Queued) return { status: DocExtractionStatus.Queued }\n      if (jobRecord.status === ExtractionJobStatus.Processing) return { status: DocExtractionStatus.Processing }\n      if (jobRecord.status === ExtractionJobStatus.Failed) {\n        return hasExtractedData\n          ? { status: DocExtractionStatus.Extracted, errorMessage: jobRecord.errorMessage }\n          : { status: DocExtractionStatus.Failed, errorMessage: jobRecord.errorMessage }\n      }\n      if (jobRecord.status === ExtractionJobStatus.Succeeded || hasExtractedData) return { status: DocExtractionStatus.Extracted }\n      return { status: DocExtractionStatus.Uploaded }\n    }\n    return { status: hasExtractedData ? DocExtractionStatus.Extracted : DocExtractionStatus.Uploaded }\n  }\n  return { status: hasExtractedData ? DocExtractionStatus.Extracted : DocExtractionStatus.Unknown }\n}\n\nfunction summarize(documents: DocExtractionResult[]): ExtractionStatusResult['summary'] {\n  return documents.reduce(\n    (acc, d) => {\n      if (d.status === DocExtractionStatus.Extracted) acc.extracted++\n      else if (d.status === DocExtractionStatus.Failed) acc.failed++\n      else if (d.status === DocExtractionStatus.NotUploaded) acc.notUploaded++\n      else acc.pending++\n      return acc\n    },\n    { total: documents.length, extracted: 0, failed: 0, pending: 0, notUploaded: 0 }\n  )\n}\n\n/**\n * Declared fields populated on ANY of the document's instances, in registry\n * order — the union across periods, so a two-period statement counts a field\n * once however many periods carry it (v1 counted a T-slot column once too).\n */\nfunction populatedFields(instances: ReadonlyArray<CanonicalInstance>, declared: ReadonlyArray<string>): string[] {\n  return declared.filter((f) => instances.some((inst) => {\n    const env = inst.fields[f]\n    return env !== undefined && isPopulated(env.value)\n  }))\n}\n\n\n","/*\n * Copyright 2025 Sisters Inspire Sdn Bhd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Source Adapter contract — the framework for ingesting unstructured\n * or partner-specific inputs and producing canonical field values that\n * the eval engine + CRA report consume.\n *\n * The contract has no vendor-specific knowledge. Generic categories\n * (telco-carrier, payment-network, document-extractor, social-presence,\n * …) are declared here; specific vendor implementations live OUTSIDE\n * this open-source package, in private extension directories loaded\n * by the host app at runtime (see SYS-2444 plugin discovery).\n *\n * Design notes:\n *   - extract() is async — every real adapter does I/O (HTTP, OCR, LLM).\n *   - Errors are thrown as `AdapterError` instances. We DELIBERATELY\n *     don't use a Result<> type — the rest of finsys-core uses throw/\n *     catch, and bringing a Result idiom in for one subsystem creates\n *     dialect inconsistency.\n *   - The contract makes no statement about persistence. The host app's\n *     adapter runner catches the return value, persists canonical fields\n *     + raw payload to the storage tables (SYS-2441), and writes\n *     provenance to `ihs_extraction_runs`. Adapters are pure functions\n *     of (raw payload) → (canonical fields). This separation lets\n *     adapters be swapped, replayed, and tested without DB state.\n */\n\nimport type { AdapterCategory, CanonicalFieldName } from \"./adapter-categories.js\";\n\n/**\n * An adapter receives a raw payload — opaque to the framework. The\n * shape is whatever the vendor's source produces: a JSON object from a\n * partner API, a base64 PDF blob, a web-scrape result. Vendor adapters\n * narrow this type internally. The host app's adapter runner is\n * responsible for putting the bytes/structure in front of the adapter;\n * what those bytes are is the adapter's problem.\n */\nexport type RawPayload = unknown;\n\n/**\n * Canonical field values produced by an adapter for ONE instance.\n * Keys MUST be drawn from the field set declared by the adapter's\n * category (see `categoryFieldsOf` in adapter-categories.ts). Values\n * are typed narrowly per field by the category schema; this loose TS\n * type is runtime-validated against the category schema by the host\n * app at registration time, AND at every extract() call result.\n *\n * The framework rejects:\n *   - Field names not declared by the adapter's category\n *   - Values whose runtime type doesn't match the category schema\n *\n * Adapters MAY return a partial set — not every category field has to\n * be produced on every applicant (telco fields may be absent if the\n * borrower didn't opt in, for instance). Missing fields are aggregated\n * as zero / null in the eval engine; that's a feature, not a defect.\n */\nexport type CanonicalFieldValues = Partial<Record<CanonicalFieldName, CanonicalFieldValue>>;\n\n/**\n * One extraction \"instance\" — the framework supports multi-instance\n * per applicant per adapter. Examples:\n *   - 6 bank statements from one bank (one adapter call, 6 instances)\n *   - 12 monthly payment-summary snapshots from one payment network\n *   - 3 mobile lines from one telco carrier\n *\n * For multi-VENDOR cases (3 different telco carriers), use separate\n * adapter registrations — each vendor is its own SourceAdapter with\n * its own id. For multi-INSTANCE-from-one-vendor (6 statements from\n * one bank), the adapter returns multiple AdapterExtraction entries\n * in a single extract() call.\n *\n * `instanceKey` is the within-adapter discriminator: free-form, but\n * MUST be stable across re-extractions so the storage layer can\n * replace-in-place rather than accumulating duplicates. Conventions:\n *   - For periodic data: encode the period (`'2026-Q1'`, `'2026-03'`)\n   * NOTE (SYS-3002): that is the multi-INSTANCE axis — one snapshot per\n   * instance. Do NOT encode a within-document period into the instance\n   * key; period-scoped values belong in `periods` (contractual 1-based\n   * positions). The two axes compose: instance = which document/snapshot,\n   * period = which declared position within it.\n *   - For per-line data: encode the line id (`'msisdn-60123456789'`,\n *     `'card-last4-1234'`)\n *   - For natively single-instance adapters: use the empty string `''`\n *     (the framework treats `''` as \"this adapter only ever has one\n *     instance per applicant\").\n */\nexport interface AdapterExtraction {\n  /**\n   * Stable within-adapter instance discriminator. Empty string for\n   * adapters that only ever produce one instance per applicant.\n   */\n  readonly instanceKey: string;\n\n  /**\n   * The canonical field values for this instance.\n   */\n  readonly values: CanonicalFieldValues;\n\n  /**\n   * SYS-2502: when this instance's data was OBSERVED at the source\n   * (ISO-8601) — the statement's own date, the partner snapshot's\n   * timestamp — as distinct from when the adapter RAN. Optional for\n   * backward compatibility with already-shipped adapters (the host\n   * falls back to the run's ranAt when absent, exactly the inference\n   * it always did), but new adapters should treat it as required:\n   * ranAt-inference conflates \"when we fetched\" with \"when it was\n   * true\", which corrupts recency ordering for backfilled or delayed\n   * data. Expected to become mandatory at the next major version.\n   */\n  readonly observedAt?: string;\n\n  /**\n   * SYS-2502 (prototyped in finsys-api under SYS-2977): optional\n   * per-field extraction confidence, 0..1, keyed by canonical field\n   * name. This is the provenance slot SYS-2819 identified as the\n   * missing precondition for FinXtract-as-adapter — probabilistic\n   * extractors (OCR/LLM) carry real per-field confidence; partner-API\n   * adapters (a telco returning a number) simply omit it. `null` marks\n   * a field whose value is derived/computed rather than directly\n   * extracted (renders as \"no confidence\" rather than low confidence,\n   * matching IhsFieldProvenance.origin semantics).\n   */\n  readonly confidence?: Partial<Record<CanonicalFieldName, number | null>>;\n\n  /**\n   * SYS-3002: per-period value sets for adapters whose category\n   * declares a period axis (see `AdapterManifest.periods`). Each entry\n   * carries the values for ONE contractual position; `position` is\n   * 1-based — period1 is the first declared period, there is no\n   * period0.\n   *\n   * An instance carrying `periods` uses them for period-scoped fields,\n   * while the instance-level `values` above remains the home for\n   * period-less (singleton / instance-scoped) fields. Instances of\n   * single-period adapters (no `periods` on the manifest) omit this\n   * entirely and keep everything in `values` — the existing flat path\n   * is unchanged and remains the single-period path.\n   *\n   * Periods are scoped WITHIN this instance: this instance's period1\n   * and another instance's period1 are unrelated data points.\n   */\n  readonly periods?: ReadonlyArray<PeriodValues>;\n}\n\n/**\n * SYS-3002: one period's value set within an AdapterExtraction\n * instance. Identity is `position` — the 1-based index into the\n * manifest's declared `periods` array — never the dates: declared\n * positions may overlap, nest, vary in length, or be staggered (e.g.\n * period1 = an annual table, periods 2–5 = the four quarters\n * overlapping it), so dates cannot identify a period and recency\n * ordering across positions is meaningless.\n */\nexport interface PeriodValues {\n  /**\n   * 1-based contractual position into the manifest's `periods`\n   * declaration. MUST be >= 1 — period1 is the first declared period;\n   * there is no period0. This IS the period's identity.\n   */\n  readonly position: number;\n\n  /**\n   * ISO-8601 date the period starts — display/temporal metadata only,\n   * NEVER identity.\n   */\n  readonly start?: string;\n\n  /**\n   * ISO-8601 date the period ends — display/temporal metadata only,\n   * NEVER identity.\n   */\n  readonly end?: string;\n\n  /**\n   * The canonical field values for this period, same shape as the\n   * instance-level `values`.\n   */\n  readonly values: CanonicalFieldValues;\n\n  /**\n   * Optional per-field extraction confidence for this period's values,\n   * same semantics as the instance-level `confidence` (0..1 keyed by\n   * canonical field name; `null` marks a derived/computed value).\n   */\n  readonly confidence?: Partial<Record<CanonicalFieldName, number | null>>;\n}\n\n/**\n * Allowed value shapes for canonical fields. Per-field type narrowing\n * happens at the category schema level — telcoOnTimePaymentRatio24m is\n * a number 0..1; telcoHandsetFinancingActive is a boolean; etc.\n * Numbers + booleans + strings cover everything we expect from credit\n * signals; nested objects are intentionally excluded to keep canonical\n * fields atomic + queryable.\n */\nexport type CanonicalFieldValue = number | string | boolean | null;\n\n/**\n * The interface every adapter implements. Adapters are loaded by the\n * host app's discovery mechanism (SYS-2444); the host app constructs\n * the adapter from its manifest + extract module, then registers it\n * against the registry by `id`.\n *\n * Type parameter `E` lets adapter authors declare the partner-specific\n * extension shape on ApplicantIdentity. v2.7.0+ — defaults to `{}` so\n * v2.6.0 adapters (which didn't have fetch and never read identity)\n * stay assignment-compatible. A telco adapter that needs an MSISDN\n * declares it once at the interface level:\n *\n *     interface TelcoPartnerExt { msisdn: string }\n *     const telcoAdapter: SourceAdapter<TelcoPartnerExt> = {\n *       async fetch(identity) {\n *         identity.msisdn  // string  (typed via E)\n *         identity.ic      // string  (core)\n *       },\n *       ...\n *     }\n *\n * The generic flows from interface → method, so implementations\n * don't have to redeclare it on fetch.\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface SourceAdapter<E extends Record<string, unknown> = {}> {\n  /**\n   * Globally unique id for this adapter instance. By convention:\n   * `<vendor>-<category-short>-v<n>` — e.g. `example-telco-v1`. Vendor\n   * names appear here in deployment-specific code, NEVER in\n   * finsys-core. The id is what the registry uses to dedupe + what\n   * provenance records pin to.\n   */\n  readonly id: string;\n\n  /**\n   * Which generic category this adapter implements. Determines which\n   * canonical fields the adapter MAY produce + how its output is\n   * persisted (each category has its own canonical sibling table —\n   * `ihs_alt_data_telco`, `ihs_alt_data_payments`, etc.).\n   */\n  readonly category: AdapterCategory;\n\n  /**\n   * Monotonic version per adapter. Bumped whenever the adapter's\n   * payload shape, field-mapping logic, or output semantics change.\n   * Versions are stored alongside each extraction run for replay /\n   * audit; the framework allows multiple versions of the same adapter\n   * to coexist in the registry (deployment-controlled).\n   */\n  readonly version: number;\n\n  /**\n   * Subset of the adapter's category fields that this adapter promises\n   * to produce. Used by the host app at boot to log adapter capability\n   * + by the CRA report to render \"provided by adapter X\" badges.\n   * MUST be a subset of `categoryFieldsOf(category)`; the host app\n   * validates this at registration time and refuses to load adapters\n   * that promise fields outside their category.\n   */\n  readonly produces: ReadonlyArray<CanonicalFieldName>;\n\n  /**\n   * Transform a raw payload into canonical field values. The host app\n   * calls this once per applicant per adapter, passes the result to\n   * the persistence layer (one row per AdapterExtraction in the\n   * canonical sibling table), and writes provenance.\n   *\n   * The return is ALWAYS a list, even when the adapter produces only\n   * one instance per applicant — return a one-element array in that\n   * case with `instanceKey: ''`. The list shape exists to support\n   * inherently multi-instance sources (6 bank statements, 12 monthly\n   * payment snapshots, 3 mobile lines) without forcing adapters to\n   * batch their own calls.\n   *\n   * Throw `AdapterError` for any failure path — network timeout,\n   * schema mismatch, partner API rate limit, malformed payload. The\n   * host's adapter runner catches AdapterError + records the failure\n   * on `ihs_extraction_runs` so the operator sees what happened\n   * without losing the applicant.\n   *\n   * Adapters MUST NOT throw plain `Error` or unknown types — the\n   * runner will treat those as adapter implementation bugs and surface\n   * them to logs separately. Stick to AdapterError for the\n   * expected-failure path.\n   */\n  extract(raw: RawPayload): Promise<AdapterExtraction[]>;\n\n  /**\n   * Optional partner-data fetch path. v2.7.0+ — adapters that own their\n   * partner-API integration declare this method; the host invokes it\n   * before extract() and passes the result through. Adapters that\n   * receive raw payload from elsewhere (e.g., bank-statement adapters\n   * reading FinXtract OCR output, or webhook-driven push ingest) omit\n   * fetch() entirely and the host treats raw as already-staged.\n   *\n   * The host builds `identity` from the IHS row (ic, fullName, etc.)\n   * plus any partner-specific fields the adapter declared via the\n   * manifest's `requiredIdentityFields`. If a required field is missing\n   * from the IHS, the host logs + skips this adapter for the run\n   * (no extract call, no canonical rows).\n   *\n   * Implementations should:\n   *   - Throw AdapterError('source_unavailable') ONLY on transient,\n   *     retryable upstream failures (timeouts, 5xx, rate limits). The\n   *     host runner is free to retry these; misclassifying a permanent\n   *     failure here will burn retry budget for nothing.\n   *   - Throw AdapterError('not_applicable') on permanent\n   *     no-relationship signals — 404 (\"applicant unknown to partner\"),\n   *     410, an explicit \"not a subscriber\" response. Communicates\n   *     'we asked and they said no' so the host records the run + skips\n   *     retry. This is the correct reason for most non-retryable\n   *     upstream conditions.\n   *   - Throw AdapterError('payload_invalid') if the partner returned\n   *     a malformed response (200 with garbage body, schema violation).\n   *   - Return a RawPayload that extract() will translate. The same\n   *     adapter's extract() is the only consumer; the host doesn't\n   *     inspect the shape.\n   *\n   * Strict additive — v2.6.0 read-only adapters that omit fetch()\n   * keep working without change.\n   *\n   * @example WRONG — recurses into the adapter method:\n   * ```ts\n   * const adapter: SourceAdapter = {\n   *   async fetch(identity) {\n   *     const res = await fetch(`/api/lookup/${identity.ic}`)  // infinite recursion\n   *     return res.json()\n   *   },\n   *   ...\n   * }\n   * ```\n   *\n   * @example RIGHT — explicit globalThis access:\n   * ```ts\n   * const adapter: SourceAdapter = {\n   *   async fetch(identity) {\n   *     const res = await globalThis.fetch(`/api/lookup/${identity.ic}`)\n   *     return res.json()\n   *   },\n   *   ...\n   * }\n   * ```\n   *\n   * Implementation note: this method is named `fetch` which shadows\n   * the global `fetch()` inside the method body — see the @example\n   * blocks above. The fake-* reference adapters in\n   * @finsys/adapter-toolkit use the explicit-globalThis pattern.\n   * Partner repos can also pin this with the lint rule\n   * `no-restricted-syntax`: `CallExpression[callee.name='fetch']`\n   * inside any method literal named `fetch`.\n   */\n  fetch?(identity: ApplicantIdentity<E>): Promise<RawPayload>;\n}\n\n/**\n * Identity payload the host hands to fetch() so adapters can call\n * partner APIs with the right per-applicant identifiers.\n *\n * The shape is an intersection of three pieces:\n *   - Core fields (`ihsId`, `ic`, `fullName`) — always present, the\n *     host populates them from the IHS row before invoking fetch().\n *   - Partner extensions (`E`) — typed declaratively per adapter.\n *     Defaults to `{}` (no extra typed fields) for adapters that only\n *     need the core trio.\n *   - Open index signature (`[k: string]: unknown`) — catches any\n *     ad-hoc field a host might pass through; reads land on `unknown`\n *     so partners must validate before use.\n *\n * Narrowing example (the ergonomics win this type is designed to deliver):\n *\n *     interface TelcoPartnerExt { msisdn: string; accountRef: string }\n *\n *     // declare adapter with the extension shape baked in:\n *     const telcoAdapter: SourceAdapter<TelcoPartnerExt> = {\n *       async fetch(identity) {\n *         identity.ic        // string\n *         identity.msisdn    // string  (NOT unknown — narrowed by E)\n *         identity.foo       // unknown (falls through to index signature)\n *         // ...\n *       },\n *       // ...\n *     }\n *\n * The intersection puts narrowed members at the root, so partners get\n * `identity.msisdn` (not `identity.extensions?.msisdn`) — matching the\n * pattern the host actually uses (it spreads partner-required fields\n * onto the root identity object, no nested 'extensions' envelope).\n *\n * Examples:\n *   - Telco adapter declares `requiredIdentityFields: ['msisdn']`.\n *     Identity arrives with msisdn populated; adapter calls partner API.\n *     (Don't include 'ihsId', 'ic', or 'fullName' in\n *     `requiredIdentityFields` — those are core fields. `ic` in\n *     particular can be legitimately empty for non-MY scope, so\n *     declaring it required would cause the host to skip every applicant.)\n *   - Payment-network adapter declares `requiredIdentityFields:\n *     ['businessRegistrationNumber']`. Adapter looks it up + calls.\n *   - An adapter that only needs the IHS id declares no extra\n *     fields; identity has just the core trio.\n */\nexport type ApplicantIdentity<\n  // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n  E extends Record<string, unknown> = {},\n> = {\n  /** Internal IHS id — always present. */\n  readonly ihsId: number;\n  /** Malaysian IC (or analogous national id). May be empty for non-MY scope. */\n  readonly ic: string;\n  /** Applicant full legal name. */\n  readonly fullName: string;\n} & E & {\n  /** Catch-all for ad-hoc reads (typed `unknown` — validate before use). */\n  readonly [key: string]: unknown;\n};\n\n/**\n * Typed error thrown by adapters on expected failure paths. The\n * `reason` discriminator lets the host app's adapter runner classify\n * failures (transient vs permanent, partner-side vs schema-side)\n * without parsing strings.\n */\nexport class AdapterError extends Error {\n  public readonly reason: AdapterErrorReason;\n  public readonly cause?: unknown;\n\n  constructor(reason: AdapterErrorReason, message: string, cause?: unknown) {\n    super(message);\n    this.name = \"AdapterError\";\n    this.reason = reason;\n    this.cause = cause;\n  }\n}\n\n/**\n * Discriminator for adapter failure modes. The runner uses this to\n * decide whether to retry, surface to the operator, or write off the\n * extraction run.\n *\n *   payload_invalid     — the raw payload didn't conform to the\n *                         adapter's expected source shape. Permanent;\n *                         re-running won't help. Likely a partner-side\n *                         schema change → bump adapter version.\n *\n *   source_unavailable  — the upstream source was unreachable or\n *                         returned a transient error (timeout, 5xx,\n *                         rate limit). Transient; safe to retry.\n *\n *   mapping_failed      — extraction logic raised a domain-specific\n *                         failure (e.g. value out of expected range).\n *                         Permanent for this payload; surface to the\n *                         operator.\n *\n *   not_applicable      — the applicant doesn't have data for this\n *                         adapter (e.g. no telco opt-in). Not a\n *                         failure per se — the runner records a\n *                         no-op extraction run, eval engine sees no\n *                         canonical fields, components score zero.\n */\nexport type AdapterErrorReason =\n  | \"payload_invalid\"\n  | \"source_unavailable\"\n  | \"mapping_failed\"\n  | \"not_applicable\";\n","/*\n * Copyright 2025 Sisters Inspire Sdn Bhd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Aggregation operators applied by the eval engine when a scoring\n * component reads a canonical field that has multiple instances\n * persisted for the same applicant.\n *\n * Multi-instance is the framework's first-class shape — an adapter\n * may produce 6 bank-statement instances, 12 monthly payment\n * snapshots, 3 mobile lines, etc., per applicant. Eval components\n * must declare HOW they want those instances collapsed into a single\n * scoring value. This module declares the operator set + the runtime\n * helper that applies one to a value list.\n *\n * Consumer is the eval engine (today: finsys-client + FinSim sim-\n * runner; tomorrow: anywhere else evaluating against canonical\n * fields). finsys-core publishes the operator surface so policy\n * fixtures across all consumers reference the same set.\n *\n * v1 operator set, in order of expected use frequency:\n *\n *   sum    — total across instances. Bank balance sum across t1..tN.\n *   mean   — arithmetic mean. Average monthly payment volume.\n *   latest — the instance with the most recent observed_at. Telco\n *            snapshot when only the latest matters.\n *   max    — maximum value across instances. Worst-case suspension\n *            count when multiple telco lines exist.\n *   count  — number of instances with a non-null value for this\n *            field. Useful for \"how many bank statements does this\n *            applicant have on file\" as a score input.\n */\n\nimport type { CanonicalFieldValue } from \"./adapter.js\";\n\nexport type AggregationOp = \"sum\" | \"mean\" | \"latest\" | \"max\" | \"count\";\n\n/** Every operator declared in this version of finsys-core. */\nexport const ALL_AGGREGATION_OPS: ReadonlyArray<AggregationOp> = [\n  \"sum\",\n  \"mean\",\n  \"latest\",\n  \"max\",\n  \"count\",\n] as const;\n\n/**\n * One value contributed by one instance. The eval engine builds a\n * list of these (one per instance, in observed-at order — the\n * persistence layer is the source of truth on ordering) and passes\n * to applyAggregation.\n */\nexport interface InstanceValue {\n  readonly value: CanonicalFieldValue;\n  /**\n   * The instance's observed-at timestamp. MUST be an ISO-8601 UTC\n   * string (`Z`-suffixed, e.g. `2026-04-01T00:00:00Z`). The `latest`\n   * operator compares these lexicographically, which is only\n   * monotonic with wall-time when all timestamps share the UTC\n   * offset — mixed offsets (e.g. `+08:00` vs `Z`) can yield\n   * incorrect ordering. Other operators ignore this field; pass an\n   * empty string if the operator in question doesn't need it.\n   */\n  readonly observedAt: string;\n}\n\n/**\n * Apply an aggregation operator to a list of instance values.\n *\n * Behaviour for empty + null-only lists:\n *   - empty list → `null`\n *   - all-null values → `null`\n *   - `count` on either of the above → `0`\n *\n * Returns:\n *   - `sum`, `mean`, `max`, `count` → `number | null`\n *   - `latest` → matches the value type of the most-recent instance\n *     (number / boolean / string / null)\n *\n * Throws on operators that don't apply to the value types present\n * (e.g. `sum` of booleans). Eval-policy authors are expected to pair\n * operators with appropriate field types; this is a guardrail against\n * silent garbage rather than an error-recovery mechanism.\n */\nexport function applyAggregation(\n  op: AggregationOp,\n  instances: ReadonlyArray<InstanceValue>,\n): CanonicalFieldValue {\n  if (instances.length === 0) {\n    return op === \"count\" ? 0 : null;\n  }\n\n  if (op === \"count\") {\n    // Single-pass count of non-null/undefined values; avoids the\n    // intermediate array filter().length would allocate.\n    return instances.reduce(\n      (acc, i) =>\n        i.value !== null && i.value !== undefined ? acc + 1 : acc,\n      0,\n    );\n  }\n\n  if (op === \"latest\") {\n    // Newest by observedAt wins. Stable for tied timestamps (first\n    // in list — caller controls input ordering).\n    let pick = instances[0]!;\n    for (let i = 1; i < instances.length; i++) {\n      if (instances[i]!.observedAt > pick.observedAt) pick = instances[i]!;\n    }\n    return pick.value;\n  }\n\n  // Numeric operators below this point. Filter to numeric values.\n  // Null/undefined values are silently dropped (consistent with the\n  // contract's \"no usable data → null\" semantics). Non-null,\n  // non-numeric values throw — the operator was misused at policy-\n  // authoring time and silent zero-coercion would mask the bug.\n  const nums: number[] = [];\n  for (const i of instances) {\n    if (typeof i.value === \"number\" && Number.isFinite(i.value)) {\n      nums.push(i.value);\n    } else if (i.value !== null && typeof i.value !== \"undefined\") {\n      throw new Error(\n        `applyAggregation: '${op}' requires numeric values; got ${typeof i.value}`,\n      );\n    }\n  }\n\n  if (nums.length === 0) return null;\n\n  switch (op) {\n    case \"sum\":\n      return nums.reduce((a, b) => a + b, 0);\n    case \"mean\":\n      return nums.reduce((a, b) => a + b, 0) / nums.length;\n    case \"max\":\n      // `Math.max(...nums)` spreads through the call stack — V8 throws\n      // RangeError once `nums.length` crosses the engine's argument\n      // limit (~65k on current V8). Reduce form is safe for any size.\n      return nums.reduce((a, b) => (a > b ? a : b));\n  }\n}\n","/*\n * Copyright 2025 Sisters Inspire Sdn Bhd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Adapter manifest — the declarative descriptor every adapter ships\n * alongside its implementation. The host app's discovery mechanism\n * (SYS-2444) reads `manifest.json` from each adapter directory, validates\n * it against the JSON-schema in `schema/adapter-manifest.schema.json`,\n * and uses the manifest to construct + register the runtime adapter.\n *\n * Two adapter flavours both use this manifest shape:\n *\n *   1. Declarative JSON-only adapter (no TypeScript code) — `manifest.json`\n *      includes a `fieldMap` declaring source-path → canonical-field\n *      translations. The host's adapter runner applies the mapping +\n *      transforms generically. Suitable for partners whose API maps\n *      cleanly to canonical fields with rename + simple transforms.\n *\n *   2. TypeScript adapter — `manifest.json` includes an `entryPoint`\n *      pointing at an `extract.ts` (or compiled `.js`) module that\n *      exports a function implementing the `SourceAdapter#extract`\n *      contract. Used when the source needs OAuth, multi-endpoint\n *      merging, OCR pipelines, or partner-version negotiation.\n *\n * The JSON-schema (`schema/adapter-manifest.schema.json`) is the\n * authoritative format; this TypeScript type mirrors it. They MUST\n * stay in sync — when one changes, change the other.\n */\n\nimport type { AdapterCategory, CanonicalFieldName } from \"./adapter-categories.js\";\n\n/**\n * Top-level manifest shape. Mirrors `schema/adapter-manifest.schema.json`.\n */\nexport interface AdapterManifest {\n  /** Manifest format version. Bump this file's schema → bump this field. */\n  readonly manifestVersion: 1;\n\n  /**\n   * Globally unique adapter id. Conventional pattern:\n   * `<vendor>-<category-short>-v<n>` (e.g. `example-telco-v1`). The id is\n   * what `SourceAdapter#id` returns + what provenance records pin to.\n   */\n  readonly id: string;\n\n  /** Human-readable label rendered in operator UIs. */\n  readonly displayName: string;\n\n  /**\n   * Generic category this adapter implements. Determines which\n   * canonical fields the adapter is allowed to produce + which\n   * canonical sibling table its output is persisted into.\n   */\n  readonly category: AdapterCategory;\n\n  /**\n   * Monotonic version per adapter. Bump on any change to payload shape,\n   * field-mapping logic, or output semantics. Multiple versions of the\n   * same adapter family MAY coexist in a deployment (deployment-time\n   * pin).\n   */\n  readonly version: number;\n\n  /**\n   * Which canonical fields (subset of the category's field set) this\n   * adapter promises to produce. The host validates at registration\n   * time that every entry is declared by `categoryFieldsOf(category)`;\n   * adapters promising out-of-category fields are refused.\n   */\n  readonly produces: ReadonlyArray<CanonicalFieldName>;\n\n  /**\n   * Adapter implementation flavour. Discriminator drives the rest of\n   * the manifest shape.\n   *\n   *   - `declarative` — JSON-only adapter; `fieldMap` is required, no\n   *     code is loaded.\n   *   - `typescript` — TS/JS adapter; `entryPoint` is required, the\n   *     host imports it dynamically.\n   *   - `form-intake` — SYS-2501: data-only adapter declaring\n   *     form-field-id → canonical-field mappings. No code is loaded and\n   *     no fetch()/extract() ever runs; the host's form submission\n   *     handler IS the runtime, and this manifest is how a\n   *     borrower-entered scalar becomes a canonical, provenance-carrying\n   *     field instead of a hand-wired column write.\n   *   - `manual-override` — SYS-2501: data-only adapter declaring that\n   *     this category's fields may be operator-overridden\n   *     post-extraction. `produces` IS the override surface (a separate\n   *     list could only duplicate or contradict it); the host's\n   *     override endpoints gate on membership.\n   *   - `extraction-pipeline` — SYS-2998: declaration-only adapter whose\n   *     implementation IS the host application's own document-extraction\n   *     pipeline. No code is loaded and neither fetch() nor extract()\n   *     ever runs — the host's pipeline writes the canonical rows and\n   *     records the adapter runs itself; the manifest exists purely as\n   *     the declaration plane (produces, cardinality,\n   *     fieldAuthorizations) for data the host was already producing.\n   *   - `external-assertion` — SYS-3036 (ownership moved here from a\n   *     host-local extension): declaration-only adapter that is executed\n   *     entirely OUTSIDE the host. An externally-orchestrated process\n   *     completes its own ceremony/extraction and PUSHES the result to\n   *     the host's assertion-ingest surface. No code is loaded and\n   *     neither fetch() nor extract() ever runs — the same\n   *     declaration-only shape as `form-intake`/`manual-override`/\n   *     `extraction-pipeline`, but data arrives via an external push\n   *     rather than the host's own pipeline, form submission, or a\n   *     dynamic-imported/declarative extract() call.\n   */\n  readonly implementation:\n    | DeclarativeImplementation\n    | TypescriptImplementation\n    | FormIntakeImplementation\n    | ManualOverrideImplementation\n    | ExtractionPipelineImplementation\n    | ExternalAssertionImplementation\n    | DocumentIntakeImplementation;\n\n  /**\n   * SYS-2502: explicit instance cardinality.\n   *\n   *   - `single` — at most one instance per applicant; extract() returns\n   *     one AdapterExtraction with `instanceKey: \"\"`.\n   *   - `multi` — unbounded instances per applicant, each with a stable,\n   *     non-empty instanceKey.\n   *\n   * REQUIRED as of 5.0.0 (SYS-3171). It was optional for backward\n   * compatibility with manifests written before the field existed, which\n   * relied on the implicit convention (instanceKey `\"\"` → single,\n   * non-empty → multi) and let the host infer. Inference is the problem:\n   * it cannot tell a declared-single adapter emitting a multi-keyed\n   * instance from a legitimately multi one, so the host silently stored\n   * the mismatch instead of rejecting it. An explicit declaration is what\n   * makes that rejection possible at persistence time.\n   *\n   * Every in-repo manifest already declared it, so this costs nothing\n   * here; the migration is for adapters maintained outside this package.\n   */\n  readonly cardinality: \"single\" | \"multi\";\n\n  /**\n   * SYS-2502: per-applicant singleton fields on a multi-instance\n   * category — fields whose value describes the APPLICANT (one value\n   * regardless of how many instances exist) rather than the instance,\n   * e.g. accountHolderName on bank statements. Every entry MUST also\n   * appear in `produces` (host validates at registration, same as\n   * `produces` ⊆ category fields). Only meaningful when cardinality is\n   * `multi`; the host treats a singleton field's value as shared across\n   * the instance set.\n   */\n  readonly singletonFields?: ReadonlyArray<CanonicalFieldName>;\n\n  /**\n   * v2.7.0 — partner-specific identity fields the adapter needs from\n   * the IHS row when fetch() is invoked. Strings name the keys that\n   * MUST be present on the ApplicantIdentity payload — the host\n   * validates per-applicant before calling fetch() and skips the\n   * adapter (with a logged warning) if any required field is missing.\n   *\n   * Examples:\n   *   - Telco adapter: `[\"ic\", \"msisdn\"]`\n   *   - Payment-network adapter: `[\"businessRegistrationNumber\"]`\n   *   - Bank-statement-from-OCR adapter: `[]` (no fetch — extract\n   *     reads from FinXtract output staged elsewhere)\n   *\n   * Omit entirely (or use empty array) for adapters that don't\n   * implement fetch() — the host then passes an empty raw payload\n   * to extract() and the adapter is responsible for sourcing data\n   * via some other path (FinXtract output, webhook ingest, etc.).\n   *\n   * Core identity fields (`ihsId`, `ic`, `fullName`) are always\n   * present — declaring them is harmless but unnecessary.\n   */\n  readonly requiredIdentityFields?: ReadonlyArray<string>;\n\n  /**\n   * SYS-2503: declarative per-field authorization gating. Keyed by\n   * canonical field name (every key MUST also appear in `produces` —\n   * host validates at registration, same as `singletonFields`).\n   *\n   * Semantics, enforced by the HOST at read time (the manifest only\n   * declares):\n   *\n   *   - No entry for a field → visible to every reader (gating is\n   *     strictly opt-in; pre-existing manifests are unaffected).\n   *   - An entry restricts: the reader must satisfy EVERY dimension\n   *     the entry declares (AND across dimensions), matching ANY value\n   *     within a dimension's list (OR within a list).\n   *   - `lenderRoles` — reader's lender-role identifier must be listed.\n   *   - `programIds` — the application's program must be listed.\n   *\n   * Both dimensions are host-interpreted opaque strings: core neither\n   * knows nor validates what a \"role\" or \"program id\" is, keeping the\n   * contract deployment-agnostic. An entry must declare at least one\n   * dimension, and a declared dimension must be non-empty — an empty\n   * list would read as deny-all, which is better expressed by simply\n   * not producing the field.\n   */\n  readonly fieldAuthorizations?: Readonly<\n    Partial<Record<CanonicalFieldName, FieldAuthorization>>\n  >;\n\n  /**\n   * SYS-3002: ordered period declarations — the contract for the\n   * period axis of this adapter's category.\n   *\n   * The period axis is ordered BY CONTRACT: `periodN` is a POSITIONAL\n   * identifier into this array. Numbering is 1-BASED — period1 is the\n   * FIRST declared period (array index 0); there is no period0.\n   * Position is the period's IDENTITY: two extractions' period1 values\n   * are comparable because they occupy the same contractual slot, not\n   * because their dates match.\n   *\n   * Declared positions may overlap, nest, vary in length, or be\n   * staggered — e.g. period1 = an annual table, periods 2–5 = the four\n   * quarters overlapping it. The declaration makes no statement about\n   * dates; each extraction-time period carries its own dated metadata\n   * (see `PeriodValues.start`/`end`) for display and temporal\n   * reasoning, never for identity. Periods are scoped WITHIN one\n   * instance: one document's period1 and another document's period1\n   * are unrelated data points.\n   *\n   * ABSENT means the single-period convention: the adapter's output\n   * has exactly one implicit period, and instance-level `values` is\n   * that period's value set. Single-period categories (bank\n   * statements, EPF, payslips) never need to declare. Non-empty when\n   * present — declaring zero periods would contradict the implicit\n   * single-period convention, so the schema requires at least one\n   * entry.\n   *\n   * The motivating consumer is financial statements — one document\n   * carries period1 (its current fiscal year) plus period2 (its prior\n   * comparative year) — but any implementation type may declare\n   * periods: the axis is a property of the contract, not of how the\n   * adapter is implemented.\n   */\n  readonly periods?: ReadonlyArray<PeriodDeclaration>;\n\n  /**\n   * Vendor-specific value sets for the enum-kind fields this adapter\n   * produces. The category declares only THAT a field is enumerated\n   * (`kind: \"enum\"` — no values, no ordering); the manifest declares\n   * exactly WHICH labels this vendor emits, because two vendors\n   * implementing the same category may bucket differently. Scoring\n   * interpretation lives further out still, in the consumer (an eval\n   * model's per-value mapping with a mandatory fallback) — never here.\n   *\n   * Host-validated at registration (same posture as `produces` ⊆\n   * category fields):\n   *   - every key MUST appear in `produces`;\n   *   - every key MUST be declared `kind: \"enum\"` by the adapter's\n   *     category — a non-enum field with declared values is refused;\n   *   - every enum-kind field in `produces` MUST have an entry here —\n   *     an adapter that promises an enum field but not its labels\n   *     gives clients nothing to render or map against;\n   *   - each value set is a non-empty array of unique, string-\n   *     normalized labels (non-empty, no leading/trailing whitespace).\n   *\n   * At runtime the adapter emits labels from its declared set\n   * VERBATIM; the host refuses out-of-set values at ingest, so a\n   * vendor-side vocabulary change is a loud manifest-version bump,\n   * never silent data drift. Clients (form-spec and eval-model\n   * editors) read these sets through the registry-metadata surface to\n   * offer the labels without hardcoding any vendor's vocabulary.\n   *\n   * Matching is EXACT-STRING — case and whitespace variations from a\n   * declared label are treated as distinct (and therefore out-of-set),\n   * deliberately. `uniqueItems` at the schema layer is likewise\n   * exact-match, so e.g. `[\"High\", \"high\"]` is a legal (if unusual)\n   * two-label set; nothing here folds case or reconciles near-miss\n   * spelling. Silently normalizing would band-aid over a vendor-side\n   * inconsistency instead of surfacing it — a vendor emitting `\"high\"`\n   * when its manifest declares `\"High\"` is a vendor bug that should be\n   * refused loudly, not coerced into matching. Vendors own their exact\n   * label byte-for-byte; hosts never guess at reconciliation.\n   */\n  // SYS-3347: PARTIAL. This was a total Record, which only ever type-checked\n  // because the key was `string` — an index signature, so any subset\n  // satisfied it. Under the literal union a total Record demands all 224\n  // canonical fields, which is not and never was the intent: enumValues is a\n  // sparse map naming only the enum-kind fields this adapter produces. Every\n  // other vocabulary-keyed map here is already Partial; this one was the\n  // outlier, and the union is what made that visible.\n  readonly enumValues?: Readonly<Partial<Record<CanonicalFieldName, ReadonlyArray<string>>>>;\n\n  /**\n   * Optional free-form notes — useful for partner-side documentation\n   * (where to find the adapter's source, who owns it, what version of\n   * the partner API it expects). Not consumed by the runtime.\n   */\n  readonly notes?: string;\n}\n\n/**\n * SYS-3002: one declared period on the adapter's period axis. See\n * {@link AdapterManifest.periods} for the positional (1-based) identity\n * semantics — the entry's position in the `periods` array IS the\n * period's identity; the entry itself only labels the role.\n */\nexport interface PeriodDeclaration {\n  /**\n   * Human role label for the position, e.g. \"Current fiscal year\",\n   * \"Prior comparative year\". Rendered in operator UIs; carries no\n   * identity semantics.\n   */\n  readonly name: string;\n\n  /** Optional longer description of what this position holds. */\n  readonly description?: string;\n}\n\n/**\n * SYS-2503: one field's authorization gate. See\n * {@link AdapterManifest.fieldAuthorizations} for semantics.\n *\n * A union rather than an all-optional interface so a no-op gate (`{}`)\n * is unrepresentable at COMPILE time too, not just rejected by the JSON\n * schema's `minProperties: 1` at runtime — the TS type and the schema\n * enforce the same invariant at their respective layers.\n */\nexport type FieldAuthorization =\n  | {\n      readonly lenderRoles: ReadonlyArray<string>;\n      readonly programIds?: ReadonlyArray<string>;\n    }\n  | {\n      readonly lenderRoles?: ReadonlyArray<string>;\n      readonly programIds: ReadonlyArray<string>;\n    };\n\nexport interface DeclarativeImplementation {\n  readonly type: \"declarative\";\n\n  /**\n   * Each entry maps a JSONPath into the raw payload to a canonical\n   * field name, optionally applying a transform. The host's adapter\n   * runner walks this list per `extract()` invocation.\n   */\n  readonly fieldMap: ReadonlyArray<FieldMapEntry>;\n}\n\nexport interface TypescriptImplementation {\n  readonly type: \"typescript\";\n\n  /**\n   * Relative path (from the adapter's directory) to the module that\n   * exports the extract function. The host's discovery mechanism\n   * dynamic-imports this path at adapter registration time.\n   */\n  readonly entryPoint: string;\n}\n\n/**\n * SYS-2501: data-only implementation for borrower/operator form intake.\n * The manifest declares which form fields feed which canonical fields;\n * the host's form submission handler applies the mapping — no adapter\n * code exists to load, and neither fetch() nor extract() ever runs.\n */\nexport interface FormIntakeImplementation {\n  readonly type: \"form-intake\";\n\n  /**\n   * form-field-id → canonical-field mappings. `formFieldId` is the form\n   * spec's field name (the same identifier UnifiedFormConfig fields\n   * carry); `canonical` MUST be declared by the adapter's category —\n   * host validates at registration, exactly like declarative fieldMap\n   * entries. Values arrive already typed from the form layer, so there\n   * is deliberately no transform slot here: a form field needing value\n   * transformation is a form-spec concern, not an adapter one.\n   */\n  readonly fieldMap: ReadonlyArray<FormIntakeFieldMapEntry>;\n}\n\nexport interface FormIntakeFieldMapEntry {\n  /** The form spec's field name this mapping consumes. */\n  readonly formFieldId: string;\n\n  /**\n   * Canonical field name this maps to. MUST be declared by the\n   * adapter's category. Host validates at registration.\n   */\n  readonly canonical: CanonicalFieldName;\n\n  /**\n   * SYS-3358: which INSTANCE of a multi-cardinality category this form\n   * field feeds. Omitted means the single instance (`\"\"`).\n   *\n   * WHY IT LIVES ON THE ENTRY, not on a rule\n   *\n   * The wide `ihs` table flattens every repeat of a thing into suffixed\n   * columns — `bankBalanceT1..T6`, `revenueT1` beside `revenueT3`,\n   * `mobilePhoneNo` beside `officePhoneNo`. The suffix IS the instance,\n   * and it is the whole reason a third bank statement or a second job\n   * cannot be recorded today. A form-intake adapter that could only\n   * produce one instance would re-encode that limitation into the\n   * canonical model, which is precisely what the transition exists to\n   * undo.\n   *\n   * The alternative — deriving the instance from a suffix convention —\n   * was rejected. A rule that reads `T1` off the end of a column name\n   * is a parser of someone else's naming accident: it silently maps\n   * `bankBalanceT1` and `totalCreditsT1` together (correct) and\n   * `emerContactTelNo1` too (wrong), and nothing in the data says which\n   * it did. An explicit key per entry is verbose and cannot be wrong\n   * about what it meant.\n   *\n   * INVARIANT, enforced by the host at derivation time: a manifest\n   * declaring `cardinality: \"single\"` MUST NOT carry an instanceKey on\n   * any entry. Since SYS-3171 the host infers nothing from instanceKey\n   * shape, so a single-cardinality adapter quietly emitting keyed\n   * instances would store rows no single-instance reader ever looks at —\n   * a declaration and a behavior disagreeing, with nothing comparing\n   * them.\n   *\n   * The value is opaque to the host: it is stored verbatim as the row's\n   * `instanceKey` and is only ever compared for equality. Choose\n   * something a human reading a row can interpret (\"T1\", \"mobile\") over\n   * an ordinal.\n   */\n  readonly instanceKey?: string;\n}\n\n/**\n * SYS-2501: data-only implementation declaring that the adapter's\n * `produces` list is operator-overridable post-extraction. The manifest\n * gates the override surface; the host's override endpoints check\n * membership in `produces` before accepting a manual value. No code, no\n * fetch(), no extract() — the discriminator alone carries the meaning,\n * so this shape is intentionally empty beyond `type`.\n */\nexport interface ManualOverrideImplementation {\n  readonly type: \"manual-override\";\n}\n\n/**\n * SYS-2998: declaration-only implementation for adapters whose\n * implementation IS the host application's own extraction pipeline\n * (e.g. the FinXtract document-processing pipeline wrapped as\n * \"finxtract-bank-statement-v1\"). The host's pipeline code performs the\n * extraction, writes the canonical rows, and records the adapter runs —\n * this manifest is how that pipeline's output becomes declared,\n * provenance-carrying, per-field-gateable adapter data instead of\n * hand-wired writes. No code, no fetch(), no extract(); like\n * `manual-override`, the discriminator alone carries the meaning.\n *\n * Distinct from `form-intake` (whose runtime is the form submission\n * handler and which needs a fieldMap) and from `manual-override` (which\n * declares an override SURFACE): an extraction-pipeline manifest\n * declares the pipeline's produced fields verbatim — `produces` is the\n * contract, and the host validates the pipeline's writes against it.\n */\nexport interface ExtractionPipelineImplementation {\n  readonly type: \"extraction-pipeline\";\n}\n\n/**\n * SYS-3036: declaration-only implementation for adapters that are\n * executed entirely OUTSIDE the host application. An externally-\n * orchestrated process (a partner-run ceremony, an out-of-band\n * verification flow, etc.) completes its own extraction and PUSHES the\n * result to the host's assertion-ingest surface, rather than the host\n * pulling it via `fetch()`/`extract()` or a form submission. No code,\n * no fetch(), no extract(); like `manual-override` and\n * `extraction-pipeline`, the discriminator alone carries the meaning —\n * the shape is intentionally empty beyond `type`.\n *\n * Ownership note: this type + its schema branch were previously a\n * host-local extension (a runtime clone of the compiled schema with one\n * extra `oneOf` branch bolted on) because core hadn't yet published the\n * concept. Publishing it here means every host validates the SAME\n * schema — no more per-host schema patches for this discriminator.\n */\nexport interface ExternalAssertionImplementation {\n  readonly type: \"external-assertion\";\n}\n\n/**\n * SYS-3174: declaration-only implementation for the host's own document\n * UPLOAD path. The host receives a file, stores it, and records the pointer;\n * this manifest is how that write becomes declared, provenance-carrying\n * data instead of an untracked poke at a wide column. No code, no fetch(),\n * no extract() — like the three above, the discriminator alone carries the\n * meaning.\n *\n * WHY THIS IS NOT `extraction-pipeline`, which is the type it most resembles\n * and the one it would have been easiest to reuse. Uploading a document is\n * what happens BEFORE extraction, and frequently without any extraction\n * following it at all — a supplementary document may never be parsed. Filing\n * an upload under a discriminator that says \"extraction\" would leave\n * provenance unable to distinguish \"this file arrived\" from \"this file was\n * read\", by type alone, which is the exact question the `document-intake`\n * category exists to answer. A type name asserting the wrong origin is not a\n * cosmetic problem here: it is baked into every provenance row ever written\n * under it, and unpicking it later means rewriting history rather than\n * changing a constant.\n *\n * Nor `manual-override` (an operator-override SURFACE, and the type the\n * correction model needs) nor `external-assertion` (the host never saw the\n * process; here the host handles the upload itself).\n */\nexport interface DocumentIntakeImplementation {\n  readonly type: \"document-intake\";\n}\n\n/**\n * SYS-3036: how a registered adapter participates at execution time,\n * derived purely from `implementation.type`. Published here (rather than\n * re-derived per host) so every host classifies manifests identically:\n *\n *   - `Runnable` — the host loads (declarative) or dynamic-imports\n *     (typescript) a `SourceAdapter`; the host's run loop executes it.\n *   - `DeclarationOnly` — the manifest is pure declaration plane\n *     (`form-intake`, `manual-override`, `extraction-pipeline`). No code\n *     exists to load; the entry is registered so `list()`-style\n *     consumers (field-authorization gating, provenance rendering,\n *     diagnostics) see the manifest, and every execution path skips it.\n *   - `ExternallyAsserted` — the manifest declares\n *     `implementation.type: \"external-assertion\"`. Same \"no code, host\n *     never calls fetch()/extract()\" shape as `DeclarationOnly`, but data\n *     arrives via an external push rather than the host's own\n *     extraction pipeline or form intake. Hosts that used to fork on\n *     this case separately can safely fold it into the same \"not\n *     Runnable\" branch that already skips `DeclarationOnly` entries.\n *\n * String values mirror the discriminators they classify so a logged\n * `executionMode` reads naturally alongside `implementation.type`.\n */\nexport enum AdapterExecutionMode {\n  Runnable = \"runnable\",\n  DeclarationOnly = \"declaration-only\",\n  ExternallyAsserted = \"externally-asserted\",\n}\n\n/**\n * SYS-3036: classify a manifest's `implementation.type` into its\n * `AdapterExecutionMode`. Exhaustive over every discriminator this\n * version of `@finsys/core` publishes — the switch has an explicit case\n * per type and THROWS on anything else (Ajv should already have refused\n * an unrecognized discriminator at validation time, but a schema/host\n * version skew must surface as a loud refusal here too, never as a\n * silently-guessed mode; no fallback branch assigns one).\n */\nexport function executionModeOf(\n  manifest: Pick<AdapterManifest, \"implementation\">,\n): AdapterExecutionMode {\n  const implementationType = manifest.implementation.type;\n  switch (implementationType) {\n    case \"declarative\":\n    case \"typescript\":\n      return AdapterExecutionMode.Runnable;\n    case \"form-intake\":\n    case \"manual-override\":\n    case \"extraction-pipeline\":\n    case \"document-intake\":\n      return AdapterExecutionMode.DeclarationOnly;\n    case \"external-assertion\":\n      return AdapterExecutionMode.ExternallyAsserted;\n    default: {\n      const unhandled: never = implementationType;\n      throw new Error(`unknown adapter implementation type: ${String(unhandled)}`);\n    }\n  }\n}\n\nexport interface FieldMapEntry {\n  /**\n   * JSONPath expression into the raw payload. E.g.\n   * `$.bill.payment_24m_pct` or `$.account.tenure_months`. Single-\n   * value extraction; arrays + objects MUST be flattened by the\n   * partner-API client before invoking the adapter.\n   */\n  readonly source: string;\n\n  /**\n   * Canonical field name this maps to. MUST be declared by the\n   * adapter's category. Host validates at registration.\n   */\n  readonly canonical: CanonicalFieldName;\n\n  /**\n   * Optional value transform applied between source extraction +\n   * canonical-field write. Built-in transforms TBD as the pattern\n   * settles; v1 supports:\n   *   - `identity`        — default; pass through\n   *   - `pct_to_ratio01`  — divide by 100, clamp to [0, 1]\n   *   - `to_boolean`      — truthy → true, falsy → false\n   *   - `to_integer`      — round + cast\n   * Adapters needing more complex transforms should use the\n   * `typescript` implementation flavour instead.\n   */\n  readonly transform?: \"identity\" | \"pct_to_ratio01\" | \"to_boolean\" | \"to_integer\";\n}\n","/*\n * Copyright 2025 Sisters Inspire Sdn Bhd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * SYS-3542 (SYS-3463a) — the merge that builds a `SubjectCanonicalView` out\n * of several furnished records' `CanonicalView`s.\n *\n * SYS-3554 GAVE THIS FUNCTION A FURNISHER AXIS, and it is the reason most of\n * the paragraphs below were rewritten rather than extended. A bureau\n * aggregates from MANY furnishers, each running their own finsys-api\n * instance; this function was built when there was one, and it used that one\n * instance's auto-increment primary key (`ihsId`) as a global identity, as an\n * instance-key qualifier, and as a recency proxy. All three break on the\n * second furnisher, and two of the three break SILENTLY: lender A's\n * application 7 and lender B's application 7 are the same number, so their\n * documents merged under one qualified key (one lender's financial statement\n * landing in another's place inside a credit report) and the recency proxy\n * ranked by whoever had the higher sequence numbers. Identity here is now the\n * pair `(furnisherId, recordRef)`, carried STRUCTURALLY on every instance and\n * never encoded into a string — see `SubjectSource` (`canonical-view.ts`) for\n * why no delimiter would have been safe.\n *\n * WHY THIS IS A SEPARATE FILE FROM `canonical-view.ts`. That file's own doc\n * says what it is not: \"a description of a payload, not a client... there is\n * no fetching here and no instance-selection rule — selection is one\n * decision that every consumer must make identically, so it belongs with the\n * code that reads the envelope rather than with the types that describe it.\"\n * This function IS an instance-selection rule (an ordering one), so it lives\n * here, alongside the types rather than inside them — one file declares the\n * subject-scoped shape, this one is the single place that builds it, and the\n * two cannot drift apart from each other the way a type re-declared in two\n * consumers would.\n *\n * THE ORDERING RULE, established once so every consumer sees the same\n * answer: within each merged category, instances are sorted LATEST-FIRST,\n * across every source record, regardless of the order records were passed\n * in. `CanonicalAddress`'s own doc already commits this package to \"latest\n * by observedAt\" as the resolution rule for an unaddressed field; this is\n * that rule applied at subject scope, where the same field can now be\n * attested by more than one APPLICATION rather than by more than one\n * instance within one application.\n *\n * A merge that instead preserved record-arrival order would produce a result\n * indistinguishable from a correct one on any single test that only checks\n * one feed order — every field present, every type correct, the wrong\n * instance sorted first. `subject-canonical-view.test.ts` proves the primary\n * key is `observedAt` (not array position) by feeding the same two records\n * in both orders and asserting the same instance sorts first either way, and\n * separately proves the secondary key is the SOURCE pair (not array position\n * either) the same way.\n *\n * PARSING, NOT COMPARING THE RAW STRING (this is the SYS-3542 review's F1).\n * `CanonicalInstance.observedAt`'s own doc documents two ways a raw string\n * comparison silently misorders real inputs: a mixed UTC offset (`+08:00` —\n * this estate's own timezone — sorts as \"later\" than an earlier moment\n * written as `Z`) and mixed precision (a no-millis `Z` timestamp outsorts\n * every millisecond-precision one, because `'Z'` (0x5A) > `'.'` (0x2E)\n * byte-for-byte). Both are realistic here — this merge is the first place in\n * the package that compares `observedAt` values written by DIFFERENT\n * adapters across DIFFERENT applications, so the single-writer assumption a\n * same-format comparison depends on does not hold. `timeRank` below parses\n * with `Date.parse` instead: two timestamps naming the same instant sort\n * equal regardless of offset or precision, which is the guarantee a\n * \"latest wins\" rule actually needs.\n *\n * A VALUE THAT FAILS TO PARSE (`Date.parse` returns `NaN`) is treated\n * EXACTLY like an absent `observedAt` — ranked oldest, never thrown. This\n * matches the one house precedent for a malformed-but-typed value on this\n * same interface: `CanonicalInstance.legacySlot`'s own doc says a value\n * outside its shape contract \"is treated as ABSENT... rather than trimming\n * or coercing it\", specifically so a receiver stricter than its producer\n * does not silently re-enable a hazard the shape contract exists to close.\n * The alternative — throwing on a malformed timestamp — would let one\n * adapter's bad string take the whole subject merge down; per that same\n * precedent, that is the producer's failure to raise loudly at the point it\n * happened, not a reason for every consumer to gain a novel throw path.\n *\n * WHAT HAPPENS WHEN `observedAt` CANNOT SEPARATE TWO INSTANCES (SYS-3554,\n * replacing the SYS-3542 review's F5 tie-break). This function has shipped\n * three answers and the first two were both wrong in the same direction —\n * they invented an ordering and told nobody.\n *\n * The FIRST was \"keep the earlier-listed record\", which is ordering by\n * ARRIVAL: on a category where NO instance carries `observedAt` (routine for\n * some alt-data adapters, which this package documents `observedAt` as\n * optional to allow for) the result was purely the caller's array order.\n *\n * The SECOND was `sourceIhsId` DESCENDING as a recency proxy, and its own\n * docblock stated the assumption that killed it: higher-id-wins is defensible\n * \"since applications are id-ordered by creation in every producer this\n * package has observed\" — SINGULAR producer. `sourceIhsId` was one\n * finsys-api instance's auto-increment primary key. A bureau aggregates from\n * MANY furnishers, each with their own sequence, so across furnishers the\n * proxy is not weak, it is meaningless: it systematically prefers whoever has\n * the higher sequence numbers. Lender B's application 500 is not newer than\n * lender A's 12000.\n *\n * THE THIRD, AND THE CURRENT ONE: the merge stops inventing an ordering it\n * cannot justify, and reports the question instead. Two decisions, and they\n * are separate:\n *\n *   1. ORDER: `compareSources` below, an ASCENDING lexicographic comparison\n *      of `furnisherId` then `recordRef`, compared FIELD BY FIELD. Its only\n *      job is to be a deterministic TOTAL order so that the merge stays\n *      genuinely order-independent — the same instance sorts first regardless\n *      of which record a caller listed first — and it carries NO temporal\n *      meaning whatsoever. That is a downgrade from F5's claim and a\n *      deliberate one: F5's key also carried no temporal meaning across\n *      furnishers, it merely looked as though it did. There is no honest\n *      replacement proxy to reach for, because the one per-record axis a\n *      furnisher could have ordered by is `recordRef`, which `SubjectSource`\n *      makes OPAQUE by contract precisely so that nobody reasons from it.\n *\n *   2. DISCLOSURE: `contestedLead` on the merged category\n *      (`canonical-view.ts`), present iff the instances tied at rank 0 span\n *      more than one source. That is the part that matters — an arbitrary\n *      order is only dangerous when a consumer cannot tell it is arbitrary,\n *      and `SubjectCanonicalCategory.instances[0]` is documented as the\n *      instance `CanonicalAddress`'s \"latest wins\" rule would pick. Per\n *      SYS-3464's principle, two records that can disagree about a disputed\n *      value are worse than one incomplete record, and the disagreement is\n *      itself the finding. The per-field resolution that would legitimately\n *      settle a contested lead SHIPPED in SYS-3464, in this same version —\n *      see `buildFieldSelections` below. This sentence used to defer to it.\n *\n * WITHIN ONE SOURCE nothing changed and nothing needed to: `compareSources`\n * returns 0 for two instances of the same record, so they keep their relative\n * order within that record's own `instances` array — which IS meaningful,\n * being one producer's own ordering of its own instances — because\n * `Array.prototype.sort` has been a stable sort since ES2019 (V8 7.0+, every\n * runtime this package targets) and this function never reorders a record's\n * own instance list before sorting. A same-source tie is likewise NOT\n * `contestedLead`: one furnisher listing its own instances in its own order\n * is not a disagreement between sources.\n *\n * ALIASING (SYS-3542 review's F7): a merged `SubjectInstance`'s `fields` is\n * a FRESH object (`{ ...instance.fields }`), not the source instance's own —\n * so replacing a field on a merged instance (`fields.someKey = redacted`,\n * this codebase's own idiom throughout, e.g. `ihs-processing.ts`'s\n * provenance building) never touches the `CanonicalView` the record came\n * from. What is NOT cloned is each field's `CanonicalFieldEnvelope` object\n * itself: `fields.someKey` after the merge is the SAME envelope reference\n * the source instance held. A caller that mutates an envelope IN PLACE\n * (`envelope.value = x`) still aliases the source — but no code in this\n * package does that; every existing consumer (`flatRecordFromView`,\n * `fieldProvenanceFromView`) builds a new value rather than assigning into\n * an envelope, and this merge is deliberately consistent with that idiom\n * rather than deep-cloning a wire payload nobody here mutates in place.\n *\n * `source` IS THE THIRD CASE, and it behaves like the envelope rather than\n * like `fields` (SYS-3554): every instance a record contributes shares ONE\n * `SubjectSource` object, and it is the caller's own — the object passed\n * in on `SubjectViewRecord.source`, not a copy. Same idiom, same caveat:\n * mutating it in place reaches every merged instance AND the caller's input,\n * and nothing in this package does that. Sharing is deliberate rather than\n * incidental — re-deriving a source per instance would be the only place\n * a record's furnisher axis could drift WITHIN one record — and it is\n * safe to depend on by VALUE but not by IDENTITY: `sameSubjectSource` compares\n * the two members, so a consumer that builds its own `SubjectSource` to\n * compare against never behaves differently from one holding a reference to\n * this one. The same object is what `contestedLead.sources` lists.\n *\n * PER-APPLICATION MEMBERS ARE STRIPPED, NOT JUST UN-TYPED (SYS-3542 review's\n * F12): `SubjectInstance` (`canonical-view.ts`) types `legacySlot` and\n * `periodPosition` out via `Omit`, for the same reason `SubjectCanonicalCategory`\n * omits `cardinality` — both describe exactly one application's v1\n * reconstruction and stop meaning anything merged across several. A type\n * that omits a member while the runtime object still carries it would be\n * worse than carrying it typed: the value would leak through every `as`,\n * every JSON round-trip, and every consumer that doesn't fully trust the\n * type — so this merge deletes both keys from each instance it builds, not\n * only from the type that describes the result.\n *\n * THE ERROR TYPE (SYS-3542 review's F11). Every throw below raises\n * `SubjectViewError`, not a bare `Error` — matching the one precedent this\n * package already ships for a typed, caller-branchable failure\n * (`AdapterError`, `adapter.ts`: a `readonly` discriminator set in the\n * constructor alongside the message). SYS-3545 (SYS-3463d) needs to turn\n * \"zero released records for this digest\" into a denial with a specific\n * reason rather than a 500; if the only way to tell that apart from, say,\n * \"the caller passed contradictory subjectKinds\" is regexing an English\n * sentence, the first rewording of that sentence breaks a bureau's\n * disclosure path silently, because a failed regex just falls through to\n * the generic handler. `code` is the contract; the message stays exactly as\n * worded (still asserted by this file's own tests) but is not one.\n *\n * BRANCH ON `error.code`, NOT `error instanceof SubjectViewError` alone — a\n * bundler that ends up with two copies of this package's module graph\n * produces two different `SubjectViewError` constructors, and `instanceof`\n * silently fails across that boundary while `.code` does not, because it is\n * a plain string comparison rather than a prototype-chain check.\n *\n * ─────────────────────────────────────────────────────────────────────────\n *\n * PER-FIELD RECENCY (SYS-3464), AND WHY IT IS BUREAU-SIDE ONLY. The sort\n * above orders ROWS. A consumer that then spreads `instances[0].fields` flat\n * has performed latest-ROW-wins, and at subject scope that ERASES: a fresher\n * PARTIAL row from one source blanks every field of that category another\n * source supplied, and nothing errors. `ihs_field_attestation`'s own docblock\n * states the same consequence at application scope — an attestation written\n * as an ordinary canonical row with a fresh `observedAt` \"would become latest\n * and blank every OTHER field of that category\". s.29 RACUN requires\n * Complete and Not misleading; a subject file that silently drops a field\n * nobody retracted fails both. `fieldsByInstanceKey` is the fix:\n * `buildFieldSelections` below resolves each field independently, so a field\n * survives on the newest instance that actually carried it.\n *\n * A SECOND CALLER CONTRACT THIS FUNCTION CANNOT ENFORCE: an `instanceKey`\n * that is non-empty must MEAN THE SAME THING across furnishers, or the\n * caller must not let both into one merge.\n *\n * Selection is keyed on `instanceKey` precisely so that fields describing\n * two different things are never fused — two bank statements are two\n * accounts. But that protection is only as good as the key. A content-derived\n * key (a document hash) compares across furnishers; a bare ordinal like\n * `bankStatements#1` does not, and two furnishers both using it for\n * DIFFERENT accounts will have their fields resolved into one selection map\n * per field — an account number from one and a closing balance from the\n * other. That is a row nobody attested, and it is the failure this design\n * calls WORSE than the erasure it fixes, because a fabricated figure reads\n * as a fact while a missing one reads as missing.\n *\n * Nothing here can detect it. Core sees two opaque strings that happen to be\n * equal and has no way to ask whether they denote the same document. The\n * obligation is the ingest side's: normalize keys to something comparable,\n * or namespace them per furnisher before they reach this function. What\n * this function CAN do, and does, is make the result inspectable rather than\n * silent — every `SubjectFieldSelection` names its own `source`, so fields\n * under one key resolving to different furnishers is visible field by field\n * to a caller that looks. It will not look unless told to; hence this\n * paragraph.\n *\n * THE ROW-LATEST CONTRACT IS UNCHANGED FOR APPLICATION SCOPE, deliberately.\n * `CanonicalView` describes ONE application, where one document produces one\n * coherent row and the newest document supersedes the older wholesale — that\n * is correct, every v1 consumer holds it through Phases 4 and 5, and nothing\n * in this ticket touches it. The bureau CONVERTS the row shape at the\n * boundary; it does not inherit it as its read semantics. Per-field selection\n * therefore exists ONLY on the subject-scoped shape this file builds, and\n * `flatRecordFromView` / `fieldProvenanceFromView` (`ihs-processing.ts`,\n * application scope) are untouched by it.\n *\n * FILTER ORDERING — A CALLER CONTRACT THIS FUNCTION CANNOT ENFORCE, stated\n * here so that getting it wrong requires contradicting a written rule.\n *\n *   Every row-level filter must run BEFORE `subjectViewFromRecords`, never\n *   after it. Concretely: the SYS-3448 quarantine gate (is this contributed\n *   row released, or is it quarantined / superseded / retired?) and the\n *   SYS-3462 disclosure class (may THIS subscriber, for THIS purpose, see\n *   this row?) both decide row by row, and `records` must already contain\n *   only the rows that survived both.\n *\n * WHY THE ORDER IS THE WHOLE OF IT. Filtering AFTER the pick lets a newer\n * restricted or quarantined row shadow a readable older one: the newer row\n * wins the field here, the filter then removes it downstream, and the older\n * row's value — which the subscriber was entitled to see — does not come\n * back, because the selection that would have chosen it has already been\n * computed and thrown away. The field is silently ABSENT. For quarantine\n * that is statutorily wrong (data the licensee holds and may disclose is\n * missing from the file); for disclosure it fails CLOSED, which sounds safe\n * and is not, because a missing field and a withheld field are indistinguish-\n * able to the reader. Nothing errors in either case.\n *\n * SYS-3464 makes the invariant STRICTER, not merely inherited: it now binds\n * per FIELD. Under row-latest a late filter dropped one row's worth of\n * fields; under per-field selection a single removed row can change the\n * winner of any subset of the fields in its category, so a post-hoc filter\n * cannot be repaired LOCALLY, field by field — the whole\n * selection has to be recomputed from the filtered record set, which means\n * calling this function again with the correct input.\n *\n * THIS FUNCTION CANNOT CHECK ANY OF IT, and says so rather than implying a\n * guard it does not have. Quarantine state and disclosure class live in\n * finsys-api's own store; neither is on `CanonicalView`, neither is on\n * `SubjectViewRecord`, and this package has no reader for either. A record\n * that should have been filtered is indistinguishable here from one that was\n * correctly released. The enforcement point is the bureau's assembly path in\n * finsys-api (the portal's BFF and sole enforcement point); this is the\n * contract that path owes, written next to the code that depends on it.\n */\nimport type {\n  CanonicalFieldEnvelope,\n  CanonicalView,\n  SubjectCanonicalCategory,\n  SubjectCanonicalView,\n  SubjectFieldSelection,\n  SubjectInstance,\n  SubjectSource,\n} from './canonical-view.js'\n\n/**\n * Discriminator for every way `subjectViewFromRecords` can refuse its input.\n * A `subjectViewFromRecords` caller — or a caller further downstream, like\n * the SYS-3545 denial path this was added for — branches on this, never on\n * the message text. See this file's own \"THE ERROR TYPE\" doc for why.\n *\n *   no-records                  — `records` was empty; there is no subject\n *                                  to describe.\n *   subject-kind-disagreement   — two records named different `subjectKind`s\n *                                  for what is asserted to be one subject.\n *   missing-source-identity     — a record's `source` did not carry a\n *                                  non-empty `furnisherId` AND `recordRef`\n *                                  (SYS-3554).\n *   duplicate-source-record     — the same `(furnisherId, recordRef)` PAIR\n *                                  appeared in more than one record\n *                                  (SYS-3554; renamed from\n *                                  `duplicate-source-ihs-id`, which named a\n *                                  key that no longer exists — and whose\n *                                  meaning was the defect: two DIFFERENT\n *                                  furnishers sharing a record ref used to\n *                                  raise it and must not).\n *   overlay-projection-present  — a record's `CanonicalView` carried\n *                                  `overlay`; this function's input contract\n *                                  is facts-only views.\n */\nexport type SubjectViewErrorCode =\n  | 'no-records'\n  | 'subject-kind-disagreement'\n  | 'missing-source-identity'\n  | 'duplicate-source-record'\n  | 'overlay-projection-present'\n\n/**\n * Typed error thrown by `subjectViewFromRecords` on every input it refuses.\n * The `code` discriminator lets a caller classify the failure (a genuinely\n * empty subject vs a caller bug upstream) without parsing the message —\n * see this file's own \"THE ERROR TYPE\" doc. Structure matches this\n * package's one existing precedent for a typed, caller-branchable error,\n * `AdapterError` (`adapter.ts`); the field is named `code` rather than\n * `AdapterError`'s `reason` because that is the name this error's own\n * reviewer specified, and because it is the more standard idiom for a\n * machine-checked discriminant (Node's own built-in errors use `.code`).\n */\nexport class SubjectViewError extends Error {\n  public readonly code: SubjectViewErrorCode\n\n  constructor(code: SubjectViewErrorCode, message: string) {\n    super(message)\n    this.name = 'SubjectViewError'\n    this.code = code\n  }\n}\n\n/**\n * One furnished record's canonical view, tagged with the two facts\n * `CanonicalView` does not carry on its own (it describes one application, in\n * one producer's world, and knows nothing about the subject behind it or the\n * bureau in front of it).\n *\n * WHY `source` IS SUPPLIED HERE RATHER THAN READ OFF `view.ihsId` (SYS-3554).\n * Until this ticket that is exactly what this function did, on the argument —\n * stated in this doc's previous revision — that \"`CanonicalView` already\n * carries it and a second field would be a second place for the two to\n * disagree.\" That argument is now inverted, and the inversion is the point:\n * `view` IS PAYLOAD. It is a document the bureau pulled from a furnisher, and\n * a furnisher must not be able to say who it is. Furnisher identity derives\n * from the CREDENTIALED CHANNEL — every pull is bureau-initiated against one\n * furnisher's endpoint with that furnisher's credential, so the caller\n * already knows the answer at the moment of authentication, before it has\n * read a byte of the payload. Reading identity out of the payload instead\n * would let any furnisher claim to be another one, and would re-collapse the\n * bureau onto a single id space the moment two furnishers numbered a record\n * the same. `view.ihsId` is now provenance only; this function does not read\n * it for identity, for keying, or for ordering.\n *\n * CALLER CONTRACT: `subjectKind` must be stamped from the SUBJECT's current\n * registry row, not from whatever the individual application recorded at\n * intake time (a per-application snapshot can be stale — an entity type\n * corrected after submission, for instance). `subjectViewFromRecords` can\n * only detect a MISMATCH across the records it is given; it has no way to\n * tell \"every record agrees, and they are all stale\" from \"every record\n * agrees, and they are current\" — that guarantee has to hold before this\n * function is ever called.\n */\nexport interface SubjectViewRecord {\n  subjectKind: string\n  /**\n   * SYS-3554 — the pair that identifies this contributed observation, stamped\n   * by the caller from the credentialed pull channel. REQUIRED: there is no\n   * default and no fallback to `view.ihsId`, deliberately, because a\n   * `furnisherId` this function could invent would be one every furnisher\n   * shared, which is the defect it exists to close.\n   */\n  source: SubjectSource\n  view: CanonicalView\n}\n\n/**\n * The ONE way to ask whether two instances came from the same furnished\n * record. Both members are compared as whole strings, independently — this\n * function exists so that no consumer has to build\n * `` `${furnisherId}#${recordRef}` `` to get a comparable value, because both\n * halves are opaque and any join of them is ambiguous (see `SubjectSource`'s\n * own doc). For a keyed lookup rather than a scan, nest the maps\n * (`Map<furnisherId, Map<recordRef, …>>`) rather than flattening the pair\n * into one key.\n */\nexport function sameSubjectSource(a: SubjectSource, b: SubjectSource): boolean {\n  return a.furnisherId === b.furnisherId && a.recordRef === b.recordRef\n}\n\n/**\n * A source rendered for a HUMAN reading an error message — never for keying,\n * comparing, or storing, and it is deliberately not a round-trippable\n * encoding: it quotes each half separately so that an operator can see where\n * one ends and the other begins, which a joined key could not show them. Every\n * throw below names the pair rather than the `ihsId` the messages used to\n * name, because a foreign tenant's application id identifies nothing to the\n * bureau operator reading the log.\n *\n * Tolerates a malformed source, because `missing-source-identity`'s own\n * message calls it: an error path that threw while describing the thing it was\n * refusing would replace a precise refusal with a TypeError.\n */\nfunction describeSource(source: SubjectSource | undefined): string {\n  const furnisherId = source?.furnisherId\n  const recordRef = source?.recordRef\n  return `furnisher ${JSON.stringify(furnisherId ?? null)} record ${JSON.stringify(recordRef ?? null)}`\n}\n\n/**\n * A deterministic TOTAL order over sources, and nothing more — read\n * `subjectViewFromRecords`'s own doc, section \"WHAT HAPPENS WHEN `observedAt`\n * CANNOT SEPARATE TWO INSTANCES\", before giving this any other meaning. It is\n * not a recency proxy, it is not a priority, and a caller must never render\n * it as one; its entire job is to make the sort order-independent so that the\n * same instance leads regardless of which record the caller listed first.\n *\n * Compared FIELD BY FIELD rather than on a joined string, for the reason\n * `SubjectSource` gives: `('a', 'b#c')` and `('a#b', 'c')` are different\n * sources that any `#`-join maps to one value, so a joined comparison would\n * call them equal — and equal sources are exactly what the duplicate check\n * below rejects and what `contestedLead` is defined not to fire on.\n */\nfunction compareSources(a: SubjectSource, b: SubjectSource): number {\n  if (a.furnisherId !== b.furnisherId) return a.furnisherId < b.furnisherId ? -1 : 1\n  if (a.recordRef !== b.recordRef) return a.recordRef < b.recordRef ? -1 : 1\n  return 0\n}\n\n/**\n * `Date.parse` for a value with no parse; `NaN` and an absent `observedAt`\n * rank identically — see this file's own doc for why. A more negative\n * number ranks OLDER; `sortSubjectInstances` sorts descending by this value.\n */\nfunction timeRank(observedAt: string | undefined): number {\n  if (observedAt === undefined) return Number.NEGATIVE_INFINITY\n  const parsed = Date.parse(observedAt)\n  return Number.isNaN(parsed) ? Number.NEGATIVE_INFINITY : parsed\n}\n\n/**\n * Latest-`observedAt`-first, then a deterministic-but-meaningless source\n * order, stable beyond that — see this file's own doc for the full\n * justification of each key, and in particular for why the second key is NOT\n * a recency signal. Mutates and returns `instances` in place; callers pass a\n * list this function already owns (built fresh in `subjectViewFromRecords`,\n * never the caller's own array).\n */\nfunction sortSubjectInstances(instances: SubjectInstance[]): SubjectInstance[] {\n  return instances.sort((a, b) => {\n    const aRank = timeRank(a.observedAt)\n    const bRank = timeRank(b.observedAt)\n    if (aRank !== bRank) return bRank - aRank\n    return compareSources(a.source, b.source)\n  })\n}\n\n/**\n * The disclosure half of the tie rule: given a category's ALREADY-SORTED\n * instances, report the distinct sources tied at the top when there is more\n * than one of them, and `undefined` otherwise. See\n * `SubjectCanonicalCategory.contestedLead` (`canonical-view.ts`) for why an\n * unresolved lead is surfaced rather than silently resolved.\n *\n * \"Tied at the top\" is measured on `observedAt` RANK, the only evidential key\n * — so a category where nothing carries `observedAt` at all has every\n * instance tied, which is precisely the case the old `sourceIhsId` tie-break\n * was invented for and precisely the case it answered wrongly across\n * furnishers.\n */\nfunction contestedLeadOf(instances: readonly SubjectInstance[]): { sources: SubjectSource[] } | undefined {\n  const lead = instances[0]\n  if (lead === undefined) return undefined\n  const leadRank = timeRank(lead.observedAt)\n  const sources: SubjectSource[] = []\n  for (const instance of instances) {\n    if (timeRank(instance.observedAt) !== leadRank) break\n    if (!sources.some((seen) => sameSubjectSource(seen, instance.source))) sources.push(instance.source)\n  }\n  return sources.length > 1 ? { sources } : undefined\n}\n\n/**\n * One field's winner while it is still being decided. Not exported and not the\n * wire shape: `rank` is a parsed number that must never reach a consumer (it\n * would be a second, subtly different encoding of `observedAt`), and\n * `tiedSources` / `disputed` are the two halves of a `contested` decision that\n * cannot be made until every instance has been seen.\n */\ninterface FieldSelectionInProgress {\n  envelope: CanonicalFieldEnvelope\n  source: SubjectSource\n  instanceKey: string\n  observedAt: string | undefined\n  /** `timeRank` of the winning observation — the rank a later instance must EQUAL to be a tie. */\n  rank: number\n  /** Distinct sources observed at that same rank, in `instances` order, winner first. */\n  tiedSources: SubjectSource[]\n  /** Set once any tied observation carries a different `envelope.value` than the winner's. */\n  disputed: boolean\n}\n\n/**\n * SYS-3464 — the per-field selection, filled into `into` (the category's own\n * `fieldsByInstanceKey`). Read `SubjectFieldSelection` and\n * `SubjectCanonicalCategory.fieldsByInstanceKey` (`canonical-view.ts`) for what\n * this member means and why it is keyed on `instanceKey`; this doc is the HOW.\n *\n * REQUIRES `instances` ALREADY SORTED latest-first by `sortSubjectInstances`,\n * exactly as `contestedLeadOf` does, and for the same reason: sorted input\n * turns \"the most recent observation of this field\" into \"the FIRST instance\n * that carries it\", which is one linear pass instead of a scan per field. It\n * also makes the tie test cheap — because rank descends, the only instances\n * that can tie a claimed field are the ones immediately following it at the\n * same rank, so an instance whose rank differs is strictly older for that\n * field and is skipped without comparison.\n *\n * WHY THE CLAIM IS PER (instanceKey, fieldName) AND NOT PER FIELD NAME ALONE:\n * see the \"chimera\" paragraph on `fieldsByInstanceKey`. Two instance keys are\n * two different things, and fusing their fields fabricates a row nobody\n * attested.\n *\n * `Object.is` RATHER THAN `===` on the value comparison, because the two\n * differ on exactly the inputs a numeric canonical field can produce: `-0`\n * and `0` are `===` but are not the same attested figure, and two `NaN`s are\n * not `===` but are the same (useless) reading, which would otherwise report\n * a source as disagreeing with ITSELF on a re-observation. Only `value` is\n * compared, never the whole envelope: two sources that agree on the figure\n * and differ on `confidence` are not in disagreement about the fact, and\n * reporting them as contested is the \"always on, so ignored\" failure\n * `contestedLead`'s own doc warns about.\n */\nfunction buildFieldSelections(\n  instances: readonly SubjectInstance[],\n  into: Record<string, Record<string, SubjectFieldSelection>>,\n): void {\n  // Object.create(null) at BOTH levels, and not for symmetry: an instanceKey\n  // and a field name are each producer-supplied text off the wire, so either\n  // one spelled '__proto__' would read back Object.prototype from a plain\n  // `{}` accumulator — the \"have I claimed this field yet?\" test below would\n  // answer for a field nobody furnished, and the real observation would be\n  // dropped with no error. Same hazard as the categoryId one above.\n  const inProgress: Record<string, Record<string, FieldSelectionInProgress>> = Object.create(null)\n\n  for (const instance of instances) {\n    const rank = timeRank(instance.observedAt)\n    const { fields, instanceKey, observedAt, source } = instance\n    const claimedForKey = (inProgress[instanceKey] ??= Object.create(null))\n    // `Object.keys` and an index rather than `Object.entries`, which allocates\n    // a two-element array per field on a path that runs once per field of\n    // every instance of every category of every record.\n    for (const fieldName of Object.keys(fields)) {\n      const claimed = claimedForKey[fieldName]\n      if (claimed === undefined) {\n        claimedForKey[fieldName] = {\n          envelope: fields[fieldName]!,\n          source,\n          instanceKey,\n          observedAt,\n          rank,\n          tiedSources: [source],\n          disputed: false,\n        }\n        continue\n      }\n      // Strictly older for THIS field — superseded, and it is superseded per\n      // field rather than per row, which is the whole ticket.\n      if (claimed.rank !== rank) continue\n      if (!claimed.tiedSources.some((seen) => sameSubjectSource(seen, source))) {\n        claimed.tiedSources.push(source)\n      }\n      if (!Object.is(claimed.envelope.value, fields[fieldName]!.value)) claimed.disputed = true\n    }\n  }\n\n  for (const instanceKey of Object.keys(inProgress)) {\n    const claimedForKey = inProgress[instanceKey]!\n    const emitted: Record<string, SubjectFieldSelection> = Object.create(null)\n    for (const fieldName of Object.keys(claimedForKey)) {\n      const claimed = claimedForKey[fieldName]!\n      const selection: SubjectFieldSelection = {\n        envelope: claimed.envelope,\n        source: claimed.source,\n        instanceKey: claimed.instanceKey,\n      }\n      // Assigned only when there IS one, same rule as `contestedLead` and for\n      // the same reason: an always-present `observedAt: undefined` serializes\n      // as an explicit null in some encoders, and a null timestamp reads as a\n      // value rather than as an absence.\n      if (claimed.observedAt !== undefined) selection.observedAt = claimed.observedAt\n      // BOTH conditions, and neither alone: more than one source ties, AND\n      // they do not agree. See `SubjectFieldSelection.contested` for why the\n      // predicate DIFFERS from `contestedLead`'s; neither implies the\n      // other. See that field's own doc.\n      if (claimed.disputed && claimed.tiedSources.length > 1) {\n        selection.contested = { sources: claimed.tiedSources }\n      }\n      emitted[fieldName] = selection\n    }\n    into[instanceKey] = emitted\n  }\n}\n\n/**\n * Merge one subject's contributed records into the one subject-scoped view. See\n * this file's own doc for the ordering rule, the parsing rule, the\n * tie-break, the aliasing contract, and — SYS-3464 — per-field recency plus\n * the filter-ordering contract a caller owes this function.\n *\n * IT RETURNS TWO ANSWERS, NOT ONE, AND THEY ARE FOR DIFFERENT QUESTIONS.\n * `instances` is the ledger, ordered latest-row-first. `fieldsByInstanceKey`\n * is the per-field selection, and it is what a consumer reads to get a FIELD's\n * value; spreading `instances[0].fields` flat is latest-ROW-wins and erases\n * every field the newest partial row did not mention (SYS-3464).\n *\n * `subjectKind` DISAGREEMENT ACROSS RECORDS: every record here is asserted\n * by its caller to describe the SAME subject, so a differing `subjectKind`\n * is not a value to reconcile — a subject's kind does not change between\n * contributed records, so a mismatch means the caller mismatched something\n * upstream (joined the wrong records to a subject, or the subject registry\n * itself is wrong). Silently picking one, or worse, invisibly overriding one\n * value with another, would hide exactly that bug — the same reasoning\n * `applyAggregation` already applies to a numeric operator fed a non-numeric\n * value in `adapter-aggregation.ts` (\"the operator was misused ... and\n * silent zero-coercion would mask the bug\"). So this throws, naming every\n * SOURCE PAIR and kind involved — see `describeSource`, which quotes each\n * half separately precisely so a message can never be parsed back into a\n * pair — rather than guessing.\n *\n * A DUPLICATE SOURCE **PAIR** ACROSS RECORDS (SYS-3542 review's F3, rescoped\n * by SYS-3554): throws, naming the repeated pair. Uniqueness at subject scope\n * is the tuple `(furnisherId, recordRef, instanceKey)`, so two records\n * carrying the SAME pair are two copies of one furnished record and their\n * instances would be indistinguishable from each other in any correctly-keyed\n * lookup — a caller bug this function can see, and it does not let the second\n * copy masquerade as a second observation.\n *\n * WHAT IT MUST NOT DO, AND USED TO (SYS-3554, consequence 1): two DIFFERENT\n * furnishers using the SAME `recordRef` are not a duplicate. They are the\n * ordinary case — a bureau aggregating many finsys-api instances, each with\n * its own auto-increment sequence, so lender A's application 7 and lender B's\n * application 7 are the same number and mean nothing to each other. The\n * previous check keyed on that bare foreign sequence, so those two records\n * raised `duplicate-source-ihs-id` and the subject failed EVERY inquiry. Both\n * halves are compared, and they are compared separately: a check that keyed\n * on a `#`-joined pair would call `('a', 'b#c')` and `('a#b', 'c')` duplicates\n * of each other, reintroducing the same false collision one level up.\n *\n * AN ABSENT OR EMPTY HALF OF THE PAIR (SYS-3554): also throws\n * (`missing-source-identity`), rather than defaulting. An empty `furnisherId`\n * is every furnisher at once — it is the pre-SYS-3554 world spelled with a\n * different character — and an empty `recordRef` collides with every other\n * ref-less record from the same furnisher. Both would fail CLOSED-looking\n * (one subject, plausibly merged) while being the exact conflation this\n * function was rewritten to make impossible, so neither is accepted as a\n * value.\n *\n * OVERLAY PROJECTIONS ARE REJECTED (SYS-3542 review's F2, the most serious\n * finding on the first pass). `CanonicalView.overlay`'s presence is the\n * signal that this view's field `value`s \"may be the calling lender's\n * staged edits rather than attested facts\" (see that member's own doc). A\n * merge that silently dropped `overlay` while passing the staged `value`s\n * through would launder an uncommitted, lender-scoped edit into subject\n * data with the one marker that could have flagged it removed — in a\n * report-assembly path, in a bureau tenant. This function's contract is\n * facts-only inputs; a record carrying `overlay` is a caller passing the\n * wrong projection, and it throws rather than silently disclosing a staged\n * edit as fact.\n *\n * EMPTY `records`: also throws. There is no subject to describe and no\n * `subjectKind` to report — a caller reaching this function needs at least\n * one application to have already resolved which subject it is asking about.\n */\nexport function subjectViewFromRecords(records: readonly SubjectViewRecord[]): SubjectCanonicalView {\n  if (records.length === 0) {\n    throw new SubjectViewError(\n      'no-records',\n      'subjectViewFromRecords: at least one record is required — there is no subjectKind to report for zero applications.',\n    )\n  }\n\n  const subjectKind = records[0]!.subjectKind\n  // NESTED, never a joined key: `Map<furnisherId, Set<recordRef>>` compares\n  // each half of the pair as a whole string, so no `recordRef` containing the\n  // delimiter of the day can be mistaken for part of another furnisher's id.\n  // A `Map` rather than an object because a furnisher id is caller-supplied\n  // text like any other, and '__proto__' is exactly as legal a string here as\n  // it is for a category id below (SYS-3542 review's F10, same hazard).\n  const seenRefsByFurnisher = new Map<string, Set<string>>()\n  for (const record of records) {\n    if (record.subjectKind !== subjectKind) {\n      throw new SubjectViewError(\n        'subject-kind-disagreement',\n        `subjectViewFromRecords: subjectKind disagreement across records for one subject — ` +\n          `${describeSource(records[0]!.source)} says '${subjectKind}', ${describeSource(record.source)} ` +\n          `says '${record.subjectKind}'. Records for one subject must agree; this looks like records for ` +\n          `two different subjects were merged, and guessing a winner would hide that.`,\n      )\n    }\n    if (record.view.overlay !== undefined) {\n      throw new SubjectViewError(\n        'overlay-projection-present',\n        `subjectViewFromRecords: ${describeSource(record.source)} carries a lender-overlay projection ` +\n          `(CanonicalView.overlay is present). This function's input contract is facts-only views; an ` +\n          `overlay-projected view's field values may be a lender's staged, uncommitted edits rather than ` +\n          `attested facts, and merging it in would disclose those edits as subject data with the one ` +\n          `marker that could have flagged them removed. Read the facts-only view for this record ` +\n          `instead of its ?overlay=mine projection.`,\n      )\n    }\n    // Read through an `as` rather than a destructure of the typed member: this\n    // guard exists for the JavaScript caller the type cannot reach (finsys-api\n    // assembles these from a database row), and a purely type-level read would\n    // make the check look present while being unable to fail.\n    const source = record.source as Partial<SubjectSource> | undefined\n    const furnisherId = source?.furnisherId\n    const recordRef = source?.recordRef\n    if (typeof furnisherId !== 'string' || furnisherId === '' || typeof recordRef !== 'string' || recordRef === '') {\n      throw new SubjectViewError(\n        'missing-source-identity',\n        `subjectViewFromRecords: a record carried no usable source identity ` +\n          `(${describeSource(record.source)}). Both halves of the pair are required and neither may be ` +\n          `empty: furnisherId is minted by the bureau and stamped from the credentialed pull channel, ` +\n          `and recordRef is the furnisher's own opaque reference to the record. An empty furnisherId is ` +\n          `every furnisher at once, and an empty recordRef collides with every other ref-less record ` +\n          `from the same furnisher — both silently reconflate the id spaces this pair exists to keep ` +\n          `apart.`,\n      )\n    }\n    const seenRefs = seenRefsByFurnisher.get(furnisherId)\n    if (seenRefs !== undefined && seenRefs.has(recordRef)) {\n      throw new SubjectViewError(\n        'duplicate-source-record',\n        `subjectViewFromRecords: ${describeSource(record.source)} appears more than once in records. ` +\n          `Every record must be a distinct furnished observation — identity at subject scope is the ` +\n          `pair (furnisherId, recordRef), and two records carrying the same pair are two copies of one ` +\n          `record whose instances no correctly-keyed lookup could tell apart. Two DIFFERENT furnishers ` +\n          `sharing a recordRef is NOT this error: each furnisher's refs are local to that furnisher, and ` +\n          `treating them as one keyspace is the SYS-3554 defect.`,\n      )\n    }\n    if (seenRefs === undefined) seenRefsByFurnisher.set(furnisherId, new Set([recordRef]))\n    else seenRefs.add(recordRef)\n  }\n\n  // Object.create(null): categoryId comes off a Record read from the wire,\n  // and a plain `{}` accumulator lets a category literally named\n  // \"__proto__\" read back Object.prototype instead of undefined, so\n  // `??=` silently never assigns it (SYS-3542 review's F10). A null-\n  // prototype object has no such accessor to intercept the assignment.\n  const categories: Record<string, SubjectCanonicalCategory> = Object.create(null)\n\n  for (const record of records) {\n    // Read ONCE per record and shared by reference across every instance it\n    // contributes. Re-deriving it per instance would be the only place a\n    // furnisher axis could drift within one record, and sharing the object is\n    // consistent with the ALIASING contract above: nothing in this package\n    // mutates a source in place, and `sameSubjectSource` compares by value\n    // rather than by identity, so a consumer that builds its own never\n    // behaves differently from one that reads this.\n    const source = record.source\n    for (const [categoryId, category] of Object.entries(record.view.categories)) {\n      // `fieldsByInstanceKey` is created empty HERE and filled by\n      // `buildFieldSelections` below rather than being replaced wholesale, so\n      // there is no sentinel object and no window in which the member is\n      // absent. Null-prototype for the reason its own doc gives.\n      const bucket = (categories[categoryId] ??= {\n        instances: [],\n        fieldsByInstanceKey: Object.create(null),\n      })\n      for (const instance of category.instances) {\n        // F12: legacySlot/periodPosition are deleted from the object, not\n        // only from the type — see this file's own \"PER-APPLICATION MEMBERS\n        // ARE STRIPPED\" doc for why a type-only omission would be worse than\n        // carrying them typed.\n        const { legacySlot: _legacySlot, periodPosition: _periodPosition, ...rest } = instance\n        const subjectInstance: SubjectInstance = {\n          // `instanceKey` is NOT rewritten (SYS-3554) — it passes through RAW,\n          // `''` included. Uniqueness is the tuple (furnisherId, recordRef,\n          // instanceKey), carried structurally in `source` below; the\n          // `${sourceIhsId}#${rawKey}` qualification this line used to perform\n          // is gone rather than re-delimited, because both halves of the pair\n          // are opaque strings and no delimiter is absent from both. See\n          // `SubjectInstance`'s own doc (`canonical-view.ts`).\n          ...rest,\n          // A fresh object, not the source instance's own — see this file's\n          // own \"ALIASING\" section for exactly what this does and does not\n          // protect against.\n          fields: { ...instance.fields },\n          source,\n        }\n        bucket.instances.push(subjectInstance)\n      }\n    }\n  }\n\n  for (const bucket of Object.values(categories)) {\n    sortSubjectInstances(bucket.instances)\n    // Assigned only when there IS one: an always-present `contestedLead:\n    // undefined` would serialize into the wire payload as an explicit null in\n    // some encoders and read as \"contested, sources unknown\".\n    const contestedLead = contestedLeadOf(bucket.instances)\n    if (contestedLead !== undefined) bucket.contestedLead = contestedLead\n    // AFTER the sort, and it depends on it — see `buildFieldSelections`'s own\n    // doc. The row order above decides which instance LEADS; this decides what\n    // each FIELD's value is, and at subject scope those are different answers.\n    buildFieldSelections(bucket.instances, bucket.fieldsByInstanceKey)\n  }\n\n  return { subjectKind, categories }\n}\n"],"mappings":"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,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,OAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR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AAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;A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CT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UA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AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,MACF;AAAA,MACA,UAAY;AAAA,IACd;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,MACR,aAAe;AAAA,MACf,MAAQ;AAAA,MACR,WAAa;AAAA,MACb,UAAY;AAAA,IACd;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,MACR,aAAe;AAAA,MACf,MAAQ;AAAA,MACR,SAAW;AAAA,QACT;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,MACF;AAAA,MACA,UAAY;AAAA,IACd;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,MACR,aAAe;AAAA,MACf,MAAQ;AAAA,MACR,UAAY;AAAA,IACd;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,MACR,aAAe;AAAA,MACf,aAAe;AAAA,MACf,MAAQ;AAAA,MACR,SAAW;AAAA,QACT;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,MACF;AAAA,MACA,UAAY;AAAA,IACd;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,MACR,aAAe;AAAA,MACf,MAAQ;AAAA,MACR,cAAgB;AAAA,MAChB,SAAW;AAAA,QACT;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAA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,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,MACF;AAAA,MACA,UAAY;AAAA,IACd;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,MACR,aAAe;AAAA,MACf,aAAe;AAAA,MACf,MAAQ;AAAA,MACR,SAAW;AAAA,QACT;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA,QACV;AAAA,QACA;AAAA,UACE,OAAS;AAAA,UACT,MAAQ;AAAA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A,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,UAAY;AAAA,MACZ,eAAiB;AAAA,MACjB,gBAAkB;AAAA,MAClB,sBAAwB;AAAA,MACxB,aAAe;AAAA,MACf,eAAiB;AAAA,MACjB,kBAAoB;AAAA,IACtB;AAAA,IACA;AAAA,MACE,MAAQ;AAAA,MACR,aAAe;AAAA,MACf,MAAQ;AAAA,MACR,kBAAoB;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AA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ACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aAAe;AAAA,QACjB;AAAA,QACA;AAAA,UACE,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,MAAQ;AAAA,UACR,aA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","names":["AjvModule","addFormats","FieldType","IncompatibilityReason","semver","map","IhsValueFormat","FileFieldTableType","cached","list","Role","ExtractionJobStatus","IhsStatus","DocExtractionStatus","AdapterExecutionMode"]}