{"version":3,"file":"suntelecoms-ngx-dynamic-form.mjs","sources":["../../../projects/ngx-dynamic-form/src/lib/services/uniqueness-validator.service.ts","../../../projects/ngx-dynamic-form/src/lib/utils/field-compare.ts","../../../projects/ngx-dynamic-form/src/lib/services/dynamic-form-builder.service.ts","../../../projects/ngx-dynamic-form/src/lib/services/condition-evaluator.service.ts","../../../projects/ngx-dynamic-form/src/lib/storage/form-storage.adapter.ts","../../../projects/ngx-dynamic-form/src/lib/storage/local-storage.adapter.ts","../../../projects/ngx-dynamic-form/src/lib/storage/http-storage.adapter.ts","../../../projects/ngx-dynamic-form/src/lib/services/form-config.service.ts","../../../projects/ngx-dynamic-form/src/lib/auth/ngx-forms-auth.service.ts","../../../projects/ngx-dynamic-form/src/lib/providers.ts","../../../projects/ngx-dynamic-form/src/lib/data/phone-countries.ts","../../../projects/ngx-dynamic-form/src/lib/utils/option-label.ts","../../../projects/ngx-dynamic-form/src/lib/utils/number-format.ts","../../../projects/ngx-dynamic-form/src/lib/utils/thousands-input.directive.ts","../../../projects/ngx-dynamic-form/src/lib/components/dynamic-field/dynamic-field.component.ts","../../../projects/ngx-dynamic-form/src/lib/components/dynamic-form/dynamic-form.component.ts","../../../projects/ngx-dynamic-form/src/lib/components/stepper-form/stepper-form.component.ts","../../../projects/ngx-dynamic-form/src/lib/components/form-builder/form-builder.component.ts","../../../projects/ngx-dynamic-form/src/lib/components/form-builder/form-builder.component.html","../../../projects/ngx-dynamic-form/src/lib/components/mes-formulaires/mes-formulaires.component.ts","../../../projects/ngx-dynamic-form/src/lib/components/mes-formulaires/mes-formulaires.component.html","../../../projects/ngx-dynamic-form/src/lib/components/form-loader/form-loader.component.ts","../../../projects/ngx-dynamic-form/src/lib/components/form-loader/form-loader.component.html","../../../projects/ngx-dynamic-form/src/public-api.ts","../../../projects/ngx-dynamic-form/src/suntelecoms-ngx-dynamic-form.ts"],"sourcesContent":["import { inject, Injectable } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { AbstractControl, AsyncValidatorFn, ValidationErrors } from '@angular/forms';\nimport { Observable, of, timer } from 'rxjs';\nimport { catchError, first, map, switchMap } from 'rxjs/operators';\n\n@Injectable({ providedIn: 'root' })\nexport class UniquenessValidatorService {\n  private http = inject(HttpClient, { optional: true });\n\n  build(url: string, message = 'Cette valeur existe déjà.'): AsyncValidatorFn {\n    return (control: AbstractControl): Observable<ValidationErrors | null> => {\n      if (!control.value || !this.http) return of(null);\n\n      // timer(400) : Angular annule l'Observable précédent à chaque frappe → debounce natif\n      return timer(400).pipe(\n        switchMap(() =>\n          this.http!.post<any>(url, { value: control.value }).pipe(\n            map(res => {\n              // Auto-détecte enveloppe SUNTELECOMS { data: boolean } ou boolean direct\n              const taken = typeof res === 'boolean' ? res : res?.data === true;\n              return taken ? { uniqueness: message } : null;\n            }),\n            catchError(() => of(null))\n          )\n        ),\n        first()\n      );\n    };\n  }\n}\n","/** Date → 'YYYY-MM-DD' en heure locale (toISOString passe en UTC et peut décaler d'un jour). */\nexport function toIsoDate(d: Date): string {\n  const m = String(d.getMonth() + 1).padStart(2, '0');\n  const day = String(d.getDate()).padStart(2, '0');\n  return `${d.getFullYear()}-${m}-${day}`;\n}\n\n/** Nombre, ou chaîne triable (une Date du mat-datepicker devient 'YYYY-MM-DD'). null = vide/invalide. */\nfunction toComparable(v: unknown): number | string | null {\n  if (v == null || v === '') return null;\n  if (v instanceof Date) return isNaN(v.getTime()) ? null : toIsoDate(v);\n  const n = Number(v);\n  return isNaN(n) ? String(v) : n;\n}\n\n/**\n * Compare deux valeurs de champ pour maxField/minField : < 0, 0, > 0, ou null si non comparables\n * (valeur vide, types différents). Les chaînes ISO des champs date, datetime-local, month, week\n * et time se trient en ordre lexicographique, sans conversion de fuseau horaire. Elles sont\n * comparées sur leur longueur commune : '2026-01-01' vs '2026-01-01T10:00:00Z' → même jour → 0.\n */\nexport function compareFieldValues(a: unknown, b: unknown): number | null {\n  const x = toComparable(a);\n  const y = toComparable(b);\n  if (x === null || y === null || typeof x !== typeof y) return null;\n  if (typeof x === 'number') return x - (y as number);\n  const len = Math.min(x.length, (y as string).length);\n  const xs = x.slice(0, len);\n  const ys = (y as string).slice(0, len);\n  return xs < ys ? -1 : xs > ys ? 1 : 0;\n}\n","import { inject, Injectable } from '@angular/core';\nimport {\n  AbstractControl,\n  FormControl,\n  FormGroup,\n  ValidationErrors,\n  ValidatorFn,\n  Validators,\n} from '@angular/forms';\nimport { DynamicFormField, FieldType, FieldValidation } from '../models/form-field.model';\nimport { UniquenessValidatorService } from './uniqueness-validator.service';\nimport { compareFieldValues } from '../utils/field-compare';\n\nconst DATE_TYPES: FieldType[] = ['date', 'datetime-local', 'month', 'week', 'time'];\n\n@Injectable({ providedIn: 'root' })\nexport class DynamicFormBuilderService {\n  private uniqueness = inject(UniquenessValidatorService);\n\n  buildFormGroup(fields: DynamicFormField[]): FormGroup {\n    const group: Record<string, AbstractControl> = {};\n\n    for (const field of fields) {\n      if (field.type === 'divider' || field.type === 'heading') continue;\n\n      // iso-country garantit un code à 2 lettres même si l'auteur du formulaire\n      // oublie de le déclarer explicitement (nécessaire pour le rendu du drapeau\n      // dérivé du code — voir DynamicFieldComponent.isoCountryFlag).\n      const effectiveValidation: FieldValidation | undefined =\n        field.type === 'iso-country' && !field.validation?.pattern\n          ? { ...field.validation, pattern: '^[A-Za-z]{2}$' }\n          : field.validation;\n      const validators = this.buildValidators(effectiveValidation);\n      const asyncValidators = field.uniqueCheck\n        ? [this.uniqueness.build(field.uniqueCheck.url, field.uniqueCheck.message)]\n        : [];\n\n      group[field.key] = new FormControl(\n        { value: field.defaultValue ?? null, disabled: field.disabled ?? false },\n        { validators, asyncValidators }\n      );\n    }\n\n    const fg = new FormGroup(group);\n\n    // Apply cross-field group validators\n    const groupValidators = this.buildGroupValidators(fields);\n    if (groupValidators.length > 0) {\n      fg.setValidators(groupValidators);\n      fg.updateValueAndValidity({ emitEvent: false });\n    }\n\n    return fg;\n  }\n\n  /** Build group-level validators for cross-field constraints */\n  buildGroupValidators(fields: DynamicFormField[], atLeastOneOf?: string[], atLeastOneOfMessage?: string): ValidatorFn[] {\n    const validators: ValidatorFn[] = [];\n\n    const labelOf = (key: string) => fields.find(f => f.key === key)?.label ?? key;\n\n    for (const field of fields) {\n      const isDate = DATE_TYPES.includes(field.type);\n      const maxField = field.validation?.maxField;\n      const minField = field.validation?.minField;\n      if (maxField) {\n        validators.push(\n          this.crossFieldBoundValidator(\n            field.key, maxField, 'max',\n            field.validation!.messages?.['maxField'] ?? (isDate\n              ? `Doit être antérieure ou égale à « ${labelOf(maxField)} ».`\n              : `Doit être ≤ « ${labelOf(maxField)} ».`)\n          )\n        );\n      }\n      if (minField) {\n        validators.push(\n          this.crossFieldBoundValidator(\n            field.key, minField, 'min',\n            field.validation!.messages?.['minField'] ?? (isDate\n              ? `Doit être postérieure ou égale à « ${labelOf(minField)} ».`\n              : `Doit être ≥ « ${labelOf(minField)} ».`)\n          )\n        );\n      }\n    }\n\n    if (atLeastOneOf?.length) {\n      validators.push(this.atLeastOneOfValidator(atLeastOneOf, atLeastOneOfMessage));\n    }\n\n    return validators;\n  }\n\n  buildValidators(validation?: FieldValidation): ValidatorFn[] {\n    if (!validation) return [];\n\n    const validators: ValidatorFn[] = [];\n\n    if (validation.required) validators.push(Validators.required);\n    if (validation.email) validators.push(Validators.email);\n    if (validation.minLength != null)\n      validators.push(Validators.minLength(validation.minLength));\n    if (validation.maxLength != null)\n      validators.push(Validators.maxLength(validation.maxLength));\n    if (validation.min != null) validators.push(Validators.min(validation.min));\n    if (validation.max != null) validators.push(Validators.max(validation.max));\n    if (validation.pattern)\n      validators.push(Validators.pattern(validation.pattern));\n\n    if (validation.custom) {\n      const customFn = validation.custom;\n      validators.push((control: AbstractControl) => {\n        const msg = customFn(control.value);\n        return msg ? { custom: msg } : null;\n      });\n    }\n\n    return validators;\n  }\n\n  getErrorMessage(\n    control: AbstractControl,\n    validation?: FieldValidation\n  ): string | null {\n    if (!control.errors || !control.touched) return null;\n\n    const msgs = validation?.messages ?? {};\n\n    if (control.errors['required'])\n      return msgs['required'] ?? 'Ce champ est requis.';\n    if (control.errors['email'])\n      return msgs['email'] ?? 'Adresse e-mail invalide.';\n    if (control.errors['minlength'])\n      return (\n        msgs['minLength'] ??\n        `Minimum ${control.errors['minlength'].requiredLength} caractères.`\n      );\n    if (control.errors['maxlength'])\n      return (\n        msgs['maxLength'] ??\n        `Maximum ${control.errors['maxlength'].requiredLength} caractères.`\n      );\n    if (control.errors['min'])\n      return msgs['min'] ?? `Valeur minimum : ${control.errors['min'].min}.`;\n    if (control.errors['max'])\n      return msgs['max'] ?? `Valeur maximum : ${control.errors['max'].max}.`;\n    if (control.errors['pattern'])\n      return msgs['pattern'] ?? 'Format invalide.';\n    // Avant matDatepickerMin/Max : quand maxField/minField borne aussi le calendrier,\n    // le datepicker lève sa propre erreur — le message maxField/minField (personnalisable) prime.\n    if (control.errors['maxField'])\n      return typeof control.errors['maxField'] === 'string'\n        ? control.errors['maxField']\n        : (msgs['maxField'] ?? 'La valeur dépasse le maximum autorisé.');\n    if (control.errors['minField'])\n      return typeof control.errors['minField'] === 'string'\n        ? control.errors['minField']\n        : (msgs['minField'] ?? 'La valeur est inférieure au minimum autorisé.');\n    if (control.errors['matDatepickerMin'])\n      return (\n        msgs['minDate'] ??\n        `La date doit être à partir du ${this.formatDateFr(control.errors['matDatepickerMin'].min)}.`\n      );\n    if (control.errors['matDatepickerMax'])\n      return (\n        msgs['maxDate'] ??\n        `La date doit être au plus tard le ${this.formatDateFr(control.errors['matDatepickerMax'].max)}.`\n      );\n    if (control.errors['custom']) return control.errors['custom'];\n    if (control.errors['uniqueness']) return control.errors['uniqueness'];\n    if (control.errors['atLeastOneOf'])\n      return typeof control.errors['atLeastOneOf'] === 'string'\n        ? control.errors['atLeastOneOf']\n        : 'Au moins un des champs doit être renseigné.';\n\n    return 'Valeur invalide.';\n  }\n\n  private formatDateFr(d: Date): string {\n    return d.toLocaleDateString('fr-FR');\n  }\n\n  /**\n   * Cross-field bound validator: sets an error on `fieldKey` when:\n   *   mode 'max': field value > other field value\n   *   mode 'min': field value < other field value\n   * Numbers and dates (Date from mat-datepicker or ISO string) — see compareFieldValues.\n   *\n   * Error is set directly on the FormControl so the existing per-field\n   * error display in DynamicFieldComponent picks it up automatically.\n   */\n  private crossFieldBoundValidator(\n    fieldKey: string,\n    otherFieldKey: string,\n    mode: 'max' | 'min',\n    errMsg: string\n  ): ValidatorFn {\n    return (group: AbstractControl): ValidationErrors | null => {\n      const fg = group as FormGroup;\n      const control = fg.get(fieldKey);\n      const otherControl = fg.get(otherFieldKey);\n      if (!control || !otherControl) return null;\n\n      const cmp = compareFieldValues(control.value, otherControl.value);\n      const errorKey = mode === 'max' ? 'maxField' : 'minField';\n      const violated = cmp !== null && (mode === 'max' ? cmp > 0 : cmp < 0);\n\n      if (violated) {\n        const current = { ...(control.errors ?? {}) };\n        current[errorKey] = errMsg;\n        control.setErrors(current);\n        return { [errorKey]: errMsg };\n      }\n\n      // Clear the error if it was previously set by this validator (also when the\n      // other field is emptied — before, an early return left a stale error).\n      if (control.errors?.[errorKey]) {\n        const errors = { ...control.errors };\n        delete errors[errorKey];\n        control.setErrors(Object.keys(errors).length ? errors : null);\n      }\n      return null;\n    };\n  }\n\n  /** Group-level validator: at least one of the listed field keys must have a non-empty value */\n  atLeastOneOfValidator(keys: string[], msg?: string): ValidatorFn {\n    return (group: AbstractControl): ValidationErrors | null => {\n      const fg = group as FormGroup;\n      const anyFilled = keys.some(k => {\n        const v = fg.get(k)?.value;\n        return v !== null && v !== undefined && v !== '' && v !== false;\n      });\n\n      if (!anyFilled) {\n        const errMsg = msg ?? 'Au moins un des champs suivants doit être renseigné.';\n        // Set error on the first control so the existing field error display shows it\n        const firstCtrl = fg.get(keys[0]);\n        if (firstCtrl) {\n          const current = { ...(firstCtrl.errors ?? {}) };\n          current['atLeastOneOf'] = errMsg;\n          firstCtrl.setErrors(current);\n        }\n        return { atLeastOneOf: { keys, msg: errMsg } };\n      }\n\n      // Clear atLeastOneOf error from the first control\n      const firstCtrl = fg.get(keys[0]);\n      if (firstCtrl?.errors?.['atLeastOneOf']) {\n        const errors = { ...firstCtrl.errors };\n        delete errors['atLeastOneOf'];\n        firstCtrl.setErrors(Object.keys(errors).length ? errors : null);\n      }\n      return null;\n    };\n  }\n}\n","import { Injectable } from '@angular/core';\nimport { FormGroup } from '@angular/forms';\nimport { FieldCondition, DynamicFormField } from '../models/form-field.model';\n\n@Injectable({ providedIn: 'root' })\nexport class ConditionEvaluatorService {\n  isVisible(field: DynamicFormField, form: FormGroup): boolean {\n    if (field.hidden) return false;\n    if (!field.showWhen) return true;\n\n    const conditions = Array.isArray(field.showWhen) ? field.showWhen : [field.showWhen];\n    const logic = field.conditionLogic ?? 'AND';\n\n    return logic === 'OR'\n      ? conditions.some(c => this.evaluate(c, form))\n      : conditions.every(c => this.evaluate(c, form));\n  }\n\n  evaluate(condition: FieldCondition, form: FormGroup): boolean {\n    return this.compare(condition.operator, form.get(condition.field)?.value, condition.value);\n  }\n\n  /** Comme evaluate(), mais contre les propriétés d'un objet brut (ex: un item de réponse API)\n   *  plutôt que les valeurs d'un FormGroup — utilisé par optionsFilter. */\n  evaluateItem(condition: FieldCondition, item: Record<string, any>): boolean {\n    return this.compare(condition.operator, item?.[condition.field], condition.value);\n  }\n\n  /** condition(s) + logique ET/OU, contre un item brut — voir optionsFilter sur DynamicFormField. */\n  matchesItem(\n    conditions: FieldCondition | FieldCondition[],\n    logic: 'AND' | 'OR' | undefined,\n    item: Record<string, any>\n  ): boolean {\n    const list = Array.isArray(conditions) ? conditions : [conditions];\n    return logic === 'OR'\n      ? list.some(c => this.evaluateItem(c, item))\n      : list.every(c => this.evaluateItem(c, item));\n  }\n\n  private compare(operator: FieldCondition['operator'], value: any, conditionValue: any): boolean {\n    switch (operator) {\n      case 'equals':      return value === conditionValue;\n      case 'notEquals':   return value !== conditionValue;\n      case 'contains':\n        return Array.isArray(value)\n          ? value.includes(conditionValue)\n          : String(value ?? '').includes(String(conditionValue));\n      case 'greaterThan': return Number(value) > Number(conditionValue);\n      case 'lessThan':    return Number(value) < Number(conditionValue);\n      case 'exists':      return value !== null && value !== undefined && value !== '';\n      case 'notExists':   return value === null || value === undefined || value === '';\n      default:            return true;\n    }\n  }\n}\n","import { Observable } from 'rxjs';\nimport type { SavedFormSchema } from '../models/saved-form.model';\n\nexport abstract class FormStorageAdapter {\n  abstract list(): Observable<SavedFormSchema[]>;\n  abstract get(id: string): Observable<SavedFormSchema | null>;\n  abstract getByCode(code: string): Observable<SavedFormSchema | null>;\n  abstract create(schema: Omit<SavedFormSchema, 'id'>): Observable<SavedFormSchema>;\n  abstract update(schema: SavedFormSchema): Observable<SavedFormSchema>;\n  abstract delete(id: string): Observable<void>;\n\n  generateId(): string {\n    return Date.now().toString(36) + Math.random().toString(36).slice(2, 7);\n  }\n}\n","import { Injectable } from '@angular/core';\nimport { Observable, of } from 'rxjs';\nimport { FormStorageAdapter } from './form-storage.adapter';\nimport type { SavedFormSchema } from '../models/saved-form.model';\n\nconst KEY = 'ngx-dynamic-form__schemas';\n\n@Injectable()\nexport class LocalStorageAdapter extends FormStorageAdapter {\n\n  list(): Observable<SavedFormSchema[]> {\n    return of(this._read());\n  }\n\n  get(id: string): Observable<SavedFormSchema | null> {\n    return of(this._read().find(s => s.id === id) ?? null);\n  }\n\n  getByCode(code: string): Observable<SavedFormSchema | null> {\n    return of(this._read().find(s => s.code === code) ?? null);\n  }\n\n  create(schema: Omit<SavedFormSchema, 'id'>): Observable<SavedFormSchema> {\n    const now = new Date().toISOString();\n    const full: SavedFormSchema = {\n      ...schema,\n      id: this.generateId(),\n      createdAt: schema.createdAt ?? now,\n      updatedAt: now,\n    };\n    this._write([...this._read(), full]);\n    return of(full);\n  }\n\n  update(schema: SavedFormSchema): Observable<SavedFormSchema> {\n    const updated = { ...schema, updatedAt: new Date().toISOString() };\n    this._write(this._read().map(s => s.id === updated.id ? updated : s));\n    return of(updated);\n  }\n\n  delete(id: string): Observable<void> {\n    this._write(this._read().filter(s => s.id !== id));\n    return of(undefined);\n  }\n\n  private _read(): SavedFormSchema[] {\n    try {\n      const raw = localStorage.getItem(KEY);\n      return raw ? JSON.parse(raw) : [];\n    } catch {\n      return [];\n    }\n  }\n\n  private _write(schemas: SavedFormSchema[]): void {\n    try {\n      localStorage.setItem(KEY, JSON.stringify(schemas));\n    } catch {\n      console.warn('[LocalStorageAdapter] Cannot write to localStorage');\n    }\n  }\n}\n","import { inject, Injectable, InjectionToken } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { map, Observable } from 'rxjs';\nimport { FormStorageAdapter } from './form-storage.adapter';\nimport type { SavedFormSchema } from '../models/saved-form.model';\n\nexport const FORM_API_URL = new InjectionToken<string>('FORM_API_URL');\n\n/**\n * Taille de page pour `list()` (`GET {apiUrl}?page=0&size=...`).\n * Configurable via `listPageSize` dans `provideNgxForms()` — @default 1000.\n */\nexport const NGX_FORMS_LIST_PAGE_SIZE = new InjectionToken<number>('NGX_FORMS_LIST_PAGE_SIZE', {\n  factory: () => 1000,\n});\n\n/** Enveloppe générique retournée par l'API */\ninterface ApiResponse<T> {\n  data: T;\n  status: string;\n  errorMessage: string | null;\n  message: string | null;\n}\n\n/** Forme brute d'un schéma renvoyé par l'API */\ninterface ApiFormSchema {\n  id: string;\n  code: string;\n  title: string;\n  config: any;\n  lastUpdatedAt: string;\n  lastUpdatedBy?: string;\n  createdAt?: string;\n}\n\n@Injectable()\nexport class HttpStorageAdapter extends FormStorageAdapter {\n  private http     = inject(HttpClient);\n  private apiUrl   = inject(FORM_API_URL);\n  private pageSize = inject(NGX_FORMS_LIST_PAGE_SIZE);\n\n  /** Mappe le format API vers SavedFormSchema */\n  private toSchema(raw: ApiFormSchema): SavedFormSchema {\n    return {\n      id:        raw.id,\n      code:      raw.code,\n      title:     raw.title,\n      config:    raw.config,\n      createdAt: raw.createdAt ?? raw.lastUpdatedAt,\n      updatedAt: raw.lastUpdatedAt,\n    };\n  }\n\n  list(): Observable<SavedFormSchema[]> {\n    return this.http\n      .get<ApiResponse<ApiFormSchema[]>>(`${this.apiUrl}?page=0&size=${this.pageSize}`)\n      .pipe(map(r => r.data.map(s => this.toSchema(s))));\n  }\n\n  get(id: string): Observable<SavedFormSchema | null> {\n    return this.http\n      .get<ApiResponse<ApiFormSchema>>(`${this.apiUrl}/${id}`)\n      .pipe(map(r => r.data ? this.toSchema(r.data) : null));\n  }\n\n  getByCode(code: string): Observable<SavedFormSchema | null> {\n    return this.http\n      .get<ApiResponse<ApiFormSchema>>(`${this.apiUrl}/code/${code}`)\n      .pipe(map(r => r.data ? this.toSchema(r.data) : null));\n  }\n\n  create(schema: Omit<SavedFormSchema, 'id'>): Observable<SavedFormSchema> {\n    const body = { code: schema.code, title: schema.title, config: schema.config };\n    return this.http\n      .post<ApiResponse<ApiFormSchema>>(this.apiUrl, body)\n      .pipe(map(r => this.toSchema(r.data)));\n  }\n\n  update(schema: SavedFormSchema): Observable<SavedFormSchema> {\n    const body = { code: schema.code, title: schema.title, config: schema.config };\n    return this.http\n      .put<ApiResponse<ApiFormSchema>>(`${this.apiUrl}/${schema.id}`, body)\n      .pipe(map(r => this.toSchema(r.data)));\n  }\n\n  delete(id: string): Observable<void> {\n    return this.http.delete<unknown>(`${this.apiUrl}/${id}`).pipe(map(() => undefined));\n  }\n}\n","import { inject, Injectable, signal } from '@angular/core';\nimport { catchError, Observable, of, tap } from 'rxjs';\nimport { HttpErrorResponse } from '@angular/common/http';\nimport { FormStorageAdapter } from '../storage/form-storage.adapter';\nimport type { SavedFormSchema, AnyFormConfig } from '../models/saved-form.model';\n\nfunction apiErrorMessage(err: unknown): string {\n  if (err instanceof HttpErrorResponse) {\n    if (err.status === 0)   return 'Impossible de joindre le serveur';\n    if (err.status === 401) return 'Authentification requise (401)';\n    if (err.status === 403) return 'Accès refusé (403)';\n    const body = err.error;\n    if (body?.errorMessage) return body.errorMessage;\n    if (body?.message)      return body.message;\n    return `Erreur serveur (${err.status})`;\n  }\n  return 'Erreur inconnue';\n}\n\n@Injectable()\nexport class FormConfigService {\n  private adapter  = inject(FormStorageAdapter);\n  private _schemas = signal<SavedFormSchema[]>([]);\n\n  readonly schemas   = this._schemas.asReadonly();\n  readonly loadError = signal<string | null>(null);\n\n  constructor() {\n    this._load();\n  }\n\n  reload(): void {\n    this.loadError.set(null);\n    this._load();\n  }\n\n  private _load(): void {\n    this.adapter.list().pipe(\n      catchError(err => { this.loadError.set(apiErrorMessage(err)); return of([]); }),\n    ).subscribe(list => this._schemas.set(list));\n  }\n\n  get(id: string): SavedFormSchema | null {\n    return this._schemas().find(s => s.id === id) ?? null;\n  }\n\n  getByCode(code: string): SavedFormSchema | null {\n    return this._schemas().find(s => s.code === code) ?? null;\n  }\n\n  /**\n   * Charge un seul formulaire directement depuis l'API (GET {apiUrl}/{id}),\n   * sans dépendre de la liste complète chargée en mémoire — à utiliser à la\n   * place de `get()` dès qu'on n'a besoin que d'un seul formulaire (au-delà\n   * d'une poignée de dizaines de formulaires, tout charger pour n'en lire\n   * qu'un devient inutilement coûteux). Met aussi à jour le cache local\n   * (`schemas()`) au passage, pour que les lectures synchrones ultérieures\n   * en bénéficient également.\n   */\n  fetchById(id: string): Observable<SavedFormSchema | null> {\n    return this.adapter.get(id).pipe(\n      tap(schema => { if (schema) this.cacheOne(schema); }),\n      catchError(err => { this.loadError.set(apiErrorMessage(err)); return of(null); }),\n    );\n  }\n\n  /** Équivalent de `fetchById`, mais par `code` (GET {apiUrl}/code/{code}). */\n  fetchByCode(code: string): Observable<SavedFormSchema | null> {\n    return this.adapter.getByCode(code).pipe(\n      tap(schema => { if (schema) this.cacheOne(schema); }),\n      catchError(err => { this.loadError.set(apiErrorMessage(err)); return of(null); }),\n    );\n  }\n\n  private cacheOne(schema: SavedFormSchema): void {\n    this._schemas.update(list =>\n      list.some(s => s.id === schema.id)\n        ? list.map(s => s.id === schema.id ? schema : s)\n        : [...list, schema]\n    );\n  }\n\n  create(code: string, title: string, config: AnyFormConfig): Observable<SavedFormSchema> {\n    const now = new Date().toISOString();\n    const schema: Omit<SavedFormSchema, 'id'> = {\n      code: code.trim(),\n      title: title.trim() || 'Sans titre',\n      config,\n      createdAt: now,\n      updatedAt: now,\n    };\n    return this.adapter.create(schema).pipe(\n      tap(saved => this._schemas.update(list => [...list, saved])),\n    );\n  }\n\n  update(schema: SavedFormSchema, title: string, config: AnyFormConfig): Observable<SavedFormSchema> {\n    const updated: SavedFormSchema = {\n      ...schema,\n      title: title.trim() || 'Sans titre',\n      config,\n      updatedAt: new Date().toISOString(),\n    };\n    return this.adapter.update(updated).pipe(\n      tap(saved => this._schemas.update(list => list.map(s => s.id === saved.id ? saved : s))),\n    );\n  }\n\n  delete(id: string): Observable<void> {\n    return this.adapter.delete(id).pipe(\n      tap(() => this._schemas.update(list => list.filter(s => s.id !== id))),\n    );\n  }\n\n  generateId(): string {\n    return this.adapter.generateId();\n  }\n}\n","import { inject, Injectable, InjectionToken } from '@angular/core';\nimport { HttpBackend, HttpClient } from '@angular/common/http';\nimport { map, Observable, of } from 'rxjs';\n\nexport interface NgxFormsAuthOptions {\n  /** URL du endpoint de login, ex : 'https://api.example.com/security-service/api/login' */\n  loginUrl: string;\n  /** Identifiant utilisateur */\n  username: string;\n  /** Mot de passe */\n  password: string;\n}\n\nexport const NGX_FORMS_AUTH = new InjectionToken<NgxFormsAuthOptions>('NGX_FORMS_AUTH');\n\ninterface LoginResponse {\n  data: {\n    accessToken: string;\n    refreshToken?: string;\n    expiresIn: number;\n  };\n}\n\n@Injectable()\nexport class NgxFormsAuthService {\n  // HttpBackend bypass tous les intercepteurs → évite la boucle infinie\n  // (l'intercepteur auth intercepterait sinon la requête de login elle-même)\n  private http   = new HttpClient(inject(HttpBackend));\n  private config = inject(NGX_FORMS_AUTH);\n\n  private token    : string | null = null;\n  private expiresAt: number        = 0;\n\n  /** Retourne un token valide — se connecte si absent ou expiré */\n  getToken(): Observable<string> {\n    if (this.token && Date.now() < this.expiresAt) {\n      return of(this.token);\n    }\n    return this.http\n      .post<LoginResponse>(this.config.loginUrl, {\n        username: this.config.username,\n        password: this.config.password,\n      })\n      .pipe(\n        map(r => {\n          this.token     = r.data.accessToken;\n          this.expiresAt = Date.now() + (r.data.expiresIn - 10) * 1000;\n          return this.token;\n        }),\n      );\n  }\n\n  /** Force une ré-authentification au prochain appel */\n  clearToken(): void {\n    this.token     = null;\n    this.expiresAt = 0;\n  }\n}\n","import { EnvironmentProviders, inject, InjectionToken, makeEnvironmentProviders } from '@angular/core';\nimport { HttpInterceptorFn } from '@angular/common/http';\nimport { switchMap } from 'rxjs';\nimport { FormStorageAdapter } from './storage/form-storage.adapter';\nimport { LocalStorageAdapter } from './storage/local-storage.adapter';\nimport { HttpStorageAdapter, FORM_API_URL, NGX_FORMS_LIST_PAGE_SIZE } from './storage/http-storage.adapter';\nimport { FormConfigService } from './services/form-config.service';\nimport { NgxFormsAuthService, NgxFormsAuthOptions, NGX_FORMS_AUTH } from './auth/ngx-forms-auth.service';\n\nexport { NgxFormsAuthService, NgxFormsAuthOptions, NGX_FORMS_AUTH };\n\n/**\n * URL de base utilisée pour charger les options des champs select/multiselect/radio\n * via la propriété `url` d'un DynamicFormField.\n */\nexport const NGX_DATA_API_URL = new InjectionToken<string>('NGX_DATA_API_URL', {\n  factory: () => '',\n});\n\n/**\n * Locale utilisée par le DateAdapter natif pour l'affichage des champs `type: 'date'`\n * (format du texte tapé/affiché + noms de mois/jours du calendrier). Une locale plutôt\n * qu'un motif de format arbitraire : réutilise le formatage Intl natif du navigateur,\n * pas de nouveau parseur de format à maintenir. Surchargeable par champ via\n * `DynamicFormField.dateLocale`.\n */\nexport const NGX_DATE_LOCALE = new InjectionToken<string>('NGX_DATE_LOCALE', {\n  factory: () => 'fr-FR',\n});\n\nexport { NGX_FORMS_LIST_PAGE_SIZE };\n\n/**\n * Intercepteur HTTP fonctionnel — ajoute `Authorization: Bearer <token>` si\n * NgxFormsAuthService est fourni (via `auth` dans provideNgxForms).\n * No-op si l'auth n'est pas configurée.\n *\n * À ajouter dans `provideHttpClient(withInterceptors([ngxFormsAuthInterceptor]))`.\n */\nexport const ngxFormsAuthInterceptor: HttpInterceptorFn = (req, next) => {\n  const authService = inject(NgxFormsAuthService, { optional: true });\n  if (!authService) return next(req);\n  return authService.getToken().pipe(\n    switchMap(token =>\n      next(req.clone({ setHeaders: { Authorization: `Bearer ${token}` } }))\n    ),\n  );\n};\n\n// ── Options ───────────────────────────────────────────────────────────────────\n\nexport interface NgxFormsLocalOptions {\n  storage: 'local';\n  /** URL de base pour le chargement dynamique des options de champs */\n  dataUrl?: string;\n  /** Configuration d'authentification par token (optionnel) */\n  auth?: NgxFormsAuthOptions;\n  /** Locale par défaut des champs `type: 'date'` (ex: 'fr-FR', 'en-US'). @default 'fr-FR' */\n  dateLocale?: string;\n}\n\nexport interface NgxFormsHttpOptions {\n  storage: 'http';\n  /** URL de base de l'API de stockage des formulaires */\n  apiUrl: string;\n  /** URL de base pour le chargement dynamique des options de champs */\n  dataUrl?: string;\n  /** Configuration d'authentification par token (optionnel) */\n  auth?: NgxFormsAuthOptions;\n  /** Locale par défaut des champs `type: 'date'` (ex: 'fr-FR', 'en-US'). @default 'fr-FR' */\n  dateLocale?: string;\n  /**\n   * Taille de page pour charger le catalogue de formulaires sauvegardés\n   * (`GET {apiUrl}?page=0&size=...`). @default 1000\n   */\n  listPageSize?: number;\n}\n\nexport type NgxFormsOptions = NgxFormsLocalOptions | NgxFormsHttpOptions;\n\n// ── Provider ──────────────────────────────────────────────────────────────────\n\nexport function provideNgxForms(options: NgxFormsOptions): EnvironmentProviders {\n  const dataUrlProvider = { provide: NGX_DATA_API_URL, useValue: options.dataUrl ?? '' };\n  const dateLocaleProvider = { provide: NGX_DATE_LOCALE, useValue: options.dateLocale ?? 'fr-FR' };\n  const authProviders   = options.auth\n    ? [\n        { provide: NGX_FORMS_AUTH, useValue: options.auth },\n        NgxFormsAuthService,\n      ]\n    : [];\n\n  if (options.storage === 'http') {\n    return makeEnvironmentProviders([\n      { provide: FORM_API_URL, useValue: options.apiUrl },\n      { provide: NGX_FORMS_LIST_PAGE_SIZE, useValue: options.listPageSize ?? 1000 },\n      { provide: FormStorageAdapter, useClass: HttpStorageAdapter },\n      FormConfigService,\n      dataUrlProvider,\n      dateLocaleProvider,\n      ...authProviders,\n    ]);\n  }\n\n  return makeEnvironmentProviders([\n    { provide: FormStorageAdapter, useClass: LocalStorageAdapter },\n    FormConfigService,\n    dataUrlProvider,\n    dateLocaleProvider,\n    ...authProviders,\n  ]);\n}\n","export interface PhoneCountry {\n  code: string;\n  name: string;\n  dialCode: string;\n  flag: string;\n  mask: string;\n}\n\nexport const PHONE_COUNTRIES: PhoneCountry[] = [\n  // ── Afrique ─────────────────────────────────────────────────────────────────\n  { code: 'ZA', name: 'Afrique du Sud',           dialCode: '+27',  flag: '🇿🇦', mask: '## ### ####' },\n  { code: 'DZ', name: 'Algérie',                  dialCode: '+213', flag: '🇩🇿', mask: '## ## ## ##' },\n  { code: 'AO', name: 'Angola',                   dialCode: '+244', flag: '🇦🇴', mask: '### ### ###' },\n  { code: 'BJ', name: 'Bénin',                    dialCode: '+229', flag: '🇧🇯', mask: '## ## ## ##' },\n  { code: 'BW', name: 'Botswana',                 dialCode: '+267', flag: '🇧🇼', mask: '## ### ###' },\n  { code: 'BF', name: 'Burkina Faso',             dialCode: '+226', flag: '🇧🇫', mask: '## ## ## ##' },\n  { code: 'BI', name: 'Burundi',                  dialCode: '+257', flag: '🇧🇮', mask: '## ## ## ##' },\n  { code: 'CM', name: 'Cameroun',                 dialCode: '+237', flag: '🇨🇲', mask: '# ## ## ## ##' },\n  { code: 'CV', name: 'Cap-Vert',                 dialCode: '+238', flag: '🇨🇻', mask: '### ## ##' },\n  { code: 'CF', name: 'Centrafrique',             dialCode: '+236', flag: '🇨🇫', mask: '## ## ## ##' },\n  { code: 'KM', name: 'Comores',                  dialCode: '+269', flag: '🇰🇲', mask: '## ## ###' },\n  { code: 'CG', name: 'Congo',                    dialCode: '+242', flag: '🇨🇬', mask: '## ## ## ##' },\n  { code: 'CD', name: 'Congo (RDC)',              dialCode: '+243', flag: '🇨🇩', mask: '## ### ####' },\n  { code: 'CI', name: \"Côte d'Ivoire\",            dialCode: '+225', flag: '🇨🇮', mask: '## ## ## ## ##' },\n  { code: 'DJ', name: 'Djibouti',                 dialCode: '+253', flag: '🇩🇯', mask: '## ## ## ##' },\n  { code: 'EG', name: 'Égypte',                   dialCode: '+20',  flag: '🇪🇬', mask: '### ### ####' },\n  { code: 'ER', name: 'Érythrée',                 dialCode: '+291', flag: '🇪🇷', mask: '# ### ###' },\n  { code: 'ET', name: 'Éthiopie',                 dialCode: '+251', flag: '🇪🇹', mask: '## ### ####' },\n  { code: 'GA', name: 'Gabon',                    dialCode: '+241', flag: '🇬🇦', mask: '# ## ## ## ##' },\n  { code: 'GM', name: 'Gambie',                   dialCode: '+220', flag: '🇬🇲', mask: '### ####' },\n  { code: 'GH', name: 'Ghana',                    dialCode: '+233', flag: '🇬🇭', mask: '## ### ####' },\n  { code: 'GN', name: 'Guinée',                   dialCode: '+224', flag: '🇬🇳', mask: '### ## ## ##' },\n  { code: 'GW', name: 'Guinée-Bissau',            dialCode: '+245', flag: '🇬🇼', mask: '# ### ###' },\n  { code: 'GQ', name: 'Guinée Équatoriale',       dialCode: '+240', flag: '🇬🇶', mask: '## ### ####' },\n  { code: 'KE', name: 'Kenya',                    dialCode: '+254', flag: '🇰🇪', mask: '### ### ###' },\n  { code: 'LS', name: 'Lesotho',                  dialCode: '+266', flag: '🇱🇸', mask: '## ### ###' },\n  { code: 'LR', name: 'Libéria',                  dialCode: '+231', flag: '🇱🇷', mask: '## ### ####' },\n  { code: 'LY', name: 'Libye',                    dialCode: '+218', flag: '🇱🇾', mask: '## ### ####' },\n  { code: 'MG', name: 'Madagascar',               dialCode: '+261', flag: '🇲🇬', mask: '## ## ### ##' },\n  { code: 'MW', name: 'Malawi',                   dialCode: '+265', flag: '🇲🇼', mask: '## ### ####' },\n  { code: 'ML', name: 'Mali',                     dialCode: '+223', flag: '🇲🇱', mask: '## ## ## ##' },\n  { code: 'MA', name: 'Maroc',                    dialCode: '+212', flag: '🇲🇦', mask: '## ## ## ## ##' },\n  { code: 'MU', name: 'Maurice',                  dialCode: '+230', flag: '🇲🇺', mask: '#### ####' },\n  { code: 'MR', name: 'Mauritanie',               dialCode: '+222', flag: '🇲🇷', mask: '## ## ## ##' },\n  { code: 'MZ', name: 'Mozambique',               dialCode: '+258', flag: '🇲🇿', mask: '## ### ####' },\n  { code: 'NA', name: 'Namibie',                  dialCode: '+264', flag: '🇳🇦', mask: '## ### ####' },\n  { code: 'NE', name: 'Niger',                    dialCode: '+227', flag: '🇳🇪', mask: '## ## ## ##' },\n  { code: 'NG', name: 'Nigeria',                  dialCode: '+234', flag: '🇳🇬', mask: '### ### ####' },\n  { code: 'RW', name: 'Rwanda',                   dialCode: '+250', flag: '🇷🇼', mask: '### ### ###' },\n  { code: 'ST', name: 'São Tomé-et-Príncipe',    dialCode: '+239', flag: '🇸🇹', mask: '## #####' },\n  { code: 'SN', name: 'Sénégal',                  dialCode: '+221', flag: '🇸🇳', mask: '## ### ## ##' },\n  { code: 'SC', name: 'Seychelles',               dialCode: '+248', flag: '🇸🇨', mask: '# ### ###' },\n  { code: 'SL', name: 'Sierra Leone',             dialCode: '+232', flag: '🇸🇱', mask: '## ######' },\n  { code: 'SO', name: 'Somalie',                  dialCode: '+252', flag: '🇸🇴', mask: '## ### ###' },\n  { code: 'SD', name: 'Soudan',                   dialCode: '+249', flag: '🇸🇩', mask: '## ### ####' },\n  { code: 'SS', name: 'Soudan du Sud',            dialCode: '+211', flag: '🇸🇸', mask: '## ### ####' },\n  { code: 'SZ', name: 'Eswatini',                 dialCode: '+268', flag: '🇸🇿', mask: '## ## ####' },\n  { code: 'TZ', name: 'Tanzanie',                 dialCode: '+255', flag: '🇹🇿', mask: '## ### ####' },\n  { code: 'TD', name: 'Tchad',                    dialCode: '+235', flag: '🇹🇩', mask: '## ## ## ##' },\n  { code: 'TG', name: 'Togo',                     dialCode: '+228', flag: '🇹🇬', mask: '## ## ## ##' },\n  { code: 'TN', name: 'Tunisie',                  dialCode: '+216', flag: '🇹🇳', mask: '## ### ###' },\n  { code: 'UG', name: 'Ouganda',                  dialCode: '+256', flag: '🇺🇬', mask: '## ### ####' },\n  { code: 'ZM', name: 'Zambie',                   dialCode: '+260', flag: '🇿🇲', mask: '## ### ####' },\n  { code: 'ZW', name: 'Zimbabwe',                 dialCode: '+263', flag: '🇿🇼', mask: '## ### ####' },\n\n  // ── Amériques ────────────────────────────────────────────────────────────────\n  { code: 'AR', name: 'Argentine',                dialCode: '+54',  flag: '🇦🇷', mask: '## #### ####' },\n  { code: 'BO', name: 'Bolivie',                  dialCode: '+591', flag: '🇧🇴', mask: '# ### ####' },\n  { code: 'BR', name: 'Brésil',                   dialCode: '+55',  flag: '🇧🇷', mask: '## ##### ####' },\n  { code: 'CA', name: 'Canada',                   dialCode: '+1',   flag: '🇨🇦', mask: '### ### ####' },\n  { code: 'CL', name: 'Chili',                    dialCode: '+56',  flag: '🇨🇱', mask: '# #### ####' },\n  { code: 'CO', name: 'Colombie',                 dialCode: '+57',  flag: '🇨🇴', mask: '### ### ####' },\n  { code: 'EC', name: 'Équateur',                 dialCode: '+593', flag: '🇪🇨', mask: '## ### ####' },\n  { code: 'MX', name: 'Mexique',                  dialCode: '+52',  flag: '🇲🇽', mask: '## #### ####' },\n  { code: 'PE', name: 'Pérou',                    dialCode: '+51',  flag: '🇵🇪', mask: '## ### ####' },\n  { code: 'US', name: 'États-Unis',               dialCode: '+1',   flag: '🇺🇸', mask: '### ### ####' },\n  { code: 'VE', name: 'Venezuela',                dialCode: '+58',  flag: '🇻🇪', mask: '### ### ####' },\n\n  // ── Asie ─────────────────────────────────────────────────────────────────────\n  { code: 'AF', name: 'Afghanistan',              dialCode: '+93',  flag: '🇦🇫', mask: '## ### ####' },\n  { code: 'SA', name: 'Arabie Saoudite',          dialCode: '+966', flag: '🇸🇦', mask: '## ### ####' },\n  { code: 'AM', name: 'Arménie',                  dialCode: '+374', flag: '🇦🇲', mask: '## ### ###' },\n  { code: 'AZ', name: 'Azerbaïdjan',              dialCode: '+994', flag: '🇦🇿', mask: '## ### ## ##' },\n  { code: 'BH', name: 'Bahreïn',                  dialCode: '+973', flag: '🇧🇭', mask: '#### ####' },\n  { code: 'BD', name: 'Bangladesh',               dialCode: '+880', flag: '🇧🇩', mask: '### ### ####' },\n  { code: 'KH', name: 'Cambodge',                 dialCode: '+855', flag: '🇰🇭', mask: '## ### ###' },\n  { code: 'CN', name: 'Chine',                    dialCode: '+86',  flag: '🇨🇳', mask: '### #### ####' },\n  { code: 'KR', name: 'Corée du Sud',             dialCode: '+82',  flag: '🇰🇷', mask: '## #### ####' },\n  { code: 'AE', name: 'Émirats Arabes Unis',      dialCode: '+971', flag: '🇦🇪', mask: '## ### ####' },\n  { code: 'GE', name: 'Géorgie',                  dialCode: '+995', flag: '🇬🇪', mask: '### ### ###' },\n  { code: 'IN', name: 'Inde',                     dialCode: '+91',  flag: '🇮🇳', mask: '##### #####' },\n  { code: 'ID', name: 'Indonésie',                dialCode: '+62',  flag: '🇮🇩', mask: '### ### ####' },\n  { code: 'IQ', name: 'Irak',                     dialCode: '+964', flag: '🇮🇶', mask: '### ### ####' },\n  { code: 'IR', name: 'Iran',                     dialCode: '+98',  flag: '🇮🇷', mask: '### ### ####' },\n  { code: 'IL', name: 'Israël',                   dialCode: '+972', flag: '🇮🇱', mask: '## ### ####' },\n  { code: 'JP', name: 'Japon',                    dialCode: '+81',  flag: '🇯🇵', mask: '## #### ####' },\n  { code: 'JO', name: 'Jordanie',                 dialCode: '+962', flag: '🇯🇴', mask: '# #### ####' },\n  { code: 'KZ', name: 'Kazakhstan',               dialCode: '+7',   flag: '🇰🇿', mask: '### ### ## ##' },\n  { code: 'KW', name: 'Koweït',                   dialCode: '+965', flag: '🇰🇼', mask: '#### ####' },\n  { code: 'KG', name: 'Kirghizistan',             dialCode: '+996', flag: '🇰🇬', mask: '### ### ###' },\n  { code: 'LA', name: 'Laos',                     dialCode: '+856', flag: '🇱🇦', mask: '## ### ###' },\n  { code: 'LB', name: 'Liban',                    dialCode: '+961', flag: '🇱🇧', mask: '## ### ###' },\n  { code: 'MY', name: 'Malaisie',                 dialCode: '+60',  flag: '🇲🇾', mask: '## ### ####' },\n  { code: 'MN', name: 'Mongolie',                 dialCode: '+976', flag: '🇲🇳', mask: '## ## ####' },\n  { code: 'MM', name: 'Myanmar',                  dialCode: '+95',  flag: '🇲🇲', mask: '# ### ####' },\n  { code: 'NP', name: 'Népal',                    dialCode: '+977', flag: '🇳🇵', mask: '## ### ####' },\n  { code: 'OM', name: 'Oman',                     dialCode: '+968', flag: '🇴🇲', mask: '#### ####' },\n  { code: 'PK', name: 'Pakistan',                 dialCode: '+92',  flag: '🇵🇰', mask: '### ### ####' },\n  { code: 'PH', name: 'Philippines',              dialCode: '+63',  flag: '🇵🇭', mask: '### ### ####' },\n  { code: 'QA', name: 'Qatar',                    dialCode: '+974', flag: '🇶🇦', mask: '#### ####' },\n  { code: 'SG', name: 'Singapour',                dialCode: '+65',  flag: '🇸🇬', mask: '#### ####' },\n  { code: 'LK', name: 'Sri Lanka',                dialCode: '+94',  flag: '🇱🇰', mask: '## ### ####' },\n  { code: 'SY', name: 'Syrie',                    dialCode: '+963', flag: '🇸🇾', mask: '## ### ####' },\n  { code: 'TJ', name: 'Tadjikistan',              dialCode: '+992', flag: '🇹🇯', mask: '## ### ####' },\n  { code: 'TW', name: 'Taïwan',                   dialCode: '+886', flag: '🇹🇼', mask: '### ### ###' },\n  { code: 'TH', name: 'Thaïlande',               dialCode: '+66',  flag: '🇹🇭', mask: '## ### ####' },\n  { code: 'TR', name: 'Turquie',                  dialCode: '+90',  flag: '🇹🇷', mask: '### ### ####' },\n  { code: 'TM', name: 'Turkménistan',             dialCode: '+993', flag: '🇹🇲', mask: '## ### ####' },\n  { code: 'UZ', name: 'Ouzbékistan',              dialCode: '+998', flag: '🇺🇿', mask: '## ### ## ##' },\n  { code: 'VN', name: 'Vietnam',                  dialCode: '+84',  flag: '🇻🇳', mask: '### ### ####' },\n  { code: 'YE', name: 'Yémen',                    dialCode: '+967', flag: '🇾🇪', mask: '### ### ###' },\n\n  // ── Europe ───────────────────────────────────────────────────────────────────\n  { code: 'AT', name: 'Autriche',                 dialCode: '+43',  flag: '🇦🇹', mask: '### ### ####' },\n  { code: 'BE', name: 'Belgique',                 dialCode: '+32',  flag: '🇧🇪', mask: '### ## ## ##' },\n  { code: 'CH', name: 'Suisse',                   dialCode: '+41',  flag: '🇨🇭', mask: '## ### ## ##' },\n  { code: 'CZ', name: 'République Tchèque',       dialCode: '+420', flag: '🇨🇿', mask: '### ### ###' },\n  { code: 'DE', name: 'Allemagne',                dialCode: '+49',  flag: '🇩🇪', mask: '### ## ## ## ##' },\n  { code: 'DK', name: 'Danemark',                 dialCode: '+45',  flag: '🇩🇰', mask: '## ## ## ##' },\n  { code: 'ES', name: 'Espagne',                  dialCode: '+34',  flag: '🇪🇸', mask: '### ## ## ##' },\n  { code: 'FI', name: 'Finlande',                 dialCode: '+358', flag: '🇫🇮', mask: '## ### ## ##' },\n  { code: 'FR', name: 'France',                   dialCode: '+33',  flag: '🇫🇷', mask: '# ## ## ## ##' },\n  { code: 'GB', name: 'Royaume-Uni',              dialCode: '+44',  flag: '🇬🇧', mask: '#### ### ####' },\n  { code: 'GR', name: 'Grèce',                    dialCode: '+30',  flag: '🇬🇷', mask: '## #### ####' },\n  { code: 'HR', name: 'Croatie',                  dialCode: '+385', flag: '🇭🇷', mask: '## ### ####' },\n  { code: 'HU', name: 'Hongrie',                  dialCode: '+36',  flag: '🇭🇺', mask: '## ### ####' },\n  { code: 'IE', name: 'Irlande',                  dialCode: '+353', flag: '🇮🇪', mask: '## ### ####' },\n  { code: 'IT', name: 'Italie',                   dialCode: '+39',  flag: '🇮🇹', mask: '## #### ####' },\n  { code: 'LU', name: 'Luxembourg',               dialCode: '+352', flag: '🇱🇺', mask: '### ### ###' },\n  { code: 'NL', name: 'Pays-Bas',                 dialCode: '+31',  flag: '🇳🇱', mask: '# ## ## ## ##' },\n  { code: 'NO', name: 'Norvège',                  dialCode: '+47',  flag: '🇳🇴', mask: '### ## ###' },\n  { code: 'PL', name: 'Pologne',                  dialCode: '+48',  flag: '🇵🇱', mask: '### ### ###' },\n  { code: 'PT', name: 'Portugal',                 dialCode: '+351', flag: '🇵🇹', mask: '### ### ###' },\n  { code: 'RO', name: 'Roumanie',                 dialCode: '+40',  flag: '🇷🇴', mask: '## ### ####' },\n  { code: 'RS', name: 'Serbie',                   dialCode: '+381', flag: '🇷🇸', mask: '## ### ####' },\n  { code: 'RU', name: 'Russie',                   dialCode: '+7',   flag: '🇷🇺', mask: '### ### ## ##' },\n  { code: 'SE', name: 'Suède',                    dialCode: '+46',  flag: '🇸🇪', mask: '## ### ## ##' },\n  { code: 'SK', name: 'Slovaquie',                dialCode: '+421', flag: '🇸🇰', mask: '### ### ###' },\n  { code: 'UA', name: 'Ukraine',                  dialCode: '+380', flag: '🇺🇦', mask: '## ### ## ##' },\n\n  // ── Océanie ──────────────────────────────────────────────────────────────────\n  { code: 'AU', name: 'Australie',                dialCode: '+61',  flag: '🇦🇺', mask: '# #### ####' },\n  { code: 'NZ', name: 'Nouvelle-Zélande',         dialCode: '+64',  flag: '🇳🇿', mask: '## ### ####' },\n];\n","/** Lit une valeur via un chemin pointé : getPath(item, 'personnePhysique.nom'). */\nexport function getPath(obj: any, path: string): any {\n  return path.split('.').reduce((o, k) => o?.[k], obj);\n}\n\n/**\n * Libellé d'une option chargée depuis une API. `displayName` accepte :\n *  - une clé ou un chemin pointé : 'codeClient', 'personnePhysique.nom'\n *  - un modèle de concaténation : '{{codeClient}} - {{telephone}}',\n *    '{{personnePhysique.nom}} {{personnePhysique.prenom}}'\n * Dans un modèle, une valeur absente (null/undefined) est remplacée par '' et\n * les espaces en trop sont réduits — on peut donc enchaîner des alternatives :\n * '{{personnePhysique.nom}} {{personnePhysique.prenom}}{{personneMorale.raisonSociale}}'.\n */\nexport function optionLabel(item: any, displayName: string): string {\n  if (!displayName.includes('{{')) {\n    return String(getPath(item, displayName) ?? item);\n  }\n  return displayName\n    .replace(/\\{\\{\\s*([\\w.]+)\\s*\\}\\}/g, (_m, path) => String(getPath(item, path) ?? ''))\n    .replace(/\\s+/g, ' ')\n    .trim();\n}\n","/**\n * Montants avec séparateur de milliers (propriété `thousandSeparator` d'un champ `number`) :\n * affichage « 1 250 000,5 », valeur numérique 1250000.5 dans le FormControl.\n * Fonctions pures, testées par number-format.spec.ts.\n */\n\n/** Séparateur décimal affiché (saisie : virgule ou point acceptés). */\nexport const DECIMAL_SEPARATOR = ',';\n\n/** Groupe la partie entière par milliers : '1250000' -> '1 250 000'. */\nfunction grouper(entier: string, separateur: string): string {\n  return entier.replace(/\\B(?=(\\d{3})+(?!\\d))/g, separateur);\n}\n\n/**\n * Nettoie une saisie : garde les chiffres, un séparateur décimal (virgule ou point) et un\n * signe moins en tête. Renvoie le texte à afficher et la valeur numérique (null si vide ou\n * incomplète, ex. '-').\n */\nexport function parseMontant(\n  saisie: string,\n  separateur: string,\n): { texte: string; valeur: number | null } {\n  const brut = String(saisie ?? '').split(separateur).join('').replace(/\\s/g, '');\n  const negatif = brut.trim().startsWith('-');\n  const sansSigne = brut.replace(/-/g, '').replace(/\\./g, ',');\n  const [entierBrut, ...decimales] = sansSigne.split(',');\n  const entier = entierBrut.replace(/\\D/g, '').replace(/^0+(?=\\d)/, '');\n  const aDecimale = decimales.length > 0;\n  const decimal = decimales.join('').replace(/\\D/g, '');\n\n  let texte = (negatif ? '-' : '') + grouper(entier, separateur);\n  if (aDecimale) texte += DECIMAL_SEPARATOR + decimal;\n\n  const nombre = `${negatif ? '-' : ''}${entier || (aDecimale ? '0' : '')}${decimal ? '.' + decimal : ''}`;\n  const valeur = entier || decimal ? Number(nombre) : null;\n  return { texte, valeur: valeur !== null && Number.isFinite(valeur) ? valeur : null };\n}\n\n/** Valeur du FormControl -> texte affiché : 20000 -> '20 000', '1250000.5' -> '1 250 000,5'. */\nexport function formatMontant(valeur: unknown, separateur: string): string {\n  if (valeur === null || valeur === undefined || valeur === '') return '';\n  const nombre = typeof valeur === 'number' ? valeur : Number(String(valeur).replace(',', '.'));\n  if (!Number.isFinite(nombre)) return String(valeur);\n  return parseMontant(String(nombre), separateur).texte;\n}\n\n/** Nombre de caractères « significatifs » (chiffres, signe, décimale) avant une position. */\nexport function significatifsAvant(texte: string, position: number): number {\n  return texte.slice(0, position).replace(/[^\\d,.\\-]/g, '').length;\n}\n\n/** Position dans `texte` après `n` caractères significatifs (replacement du curseur). */\nexport function positionApres(texte: string, n: number): number {\n  if (n <= 0) return 0;\n  let vus = 0;\n  for (let i = 0; i < texte.length; i++) {\n    if (/[\\d,.\\-]/.test(texte[i]) && ++vus === n) return i + 1;\n  }\n  return texte.length;\n}\n","import { Directive, ElementRef, Input, forwardRef, inject } from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { formatMontant, parseMontant, positionApres, significatifsAvant } from './number-format';\n\n/**\n * Saisie d'un montant avec séparateur de milliers (`thousandSeparator` d'un champ `number`).\n * L'input affiche « 20 000 » ; le FormControl reçoit le nombre 20000 — validateurs min/max,\n * maxField et payload restent numériques. Reformaté à chaque frappe, curseur conservé.\n * C'est l'accesseur de valeur du champ : mat-form-field garde ses états d'erreur.\n */\n@Directive({\n  selector: 'input[ngxThousands]',\n  standalone: true,\n  providers: [\n    { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ThousandsInputDirective), multi: true },\n  ],\n  host: {\n    '(input)': 'onInput()',\n    '(blur)': 'onBlur()',\n    inputmode: 'decimal',\n    autocomplete: 'off',\n  },\n})\nexport class ThousandsInputDirective implements ControlValueAccessor {\n  /** Séparateur de milliers affiché (défaut : espace). */\n  @Input('ngxThousands') set separateur(valeur: string | boolean | '' | undefined) {\n    this.sep = typeof valeur === 'string' && valeur.length ? valeur : ' ';\n  }\n\n  private sep = ' ';\n  private readonly el = inject<ElementRef<HTMLInputElement>>(ElementRef).nativeElement;\n  private onChange: (valeur: number | null) => void = () => {};\n  private onTouched: () => void = () => {};\n\n  writeValue(valeur: unknown): void {\n    this.el.value = formatMontant(valeur, this.sep);\n  }\n\n  registerOnChange(fn: (valeur: number | null) => void): void {\n    this.onChange = fn;\n  }\n\n  registerOnTouched(fn: () => void): void {\n    this.onTouched = fn;\n  }\n\n  setDisabledState(desactive: boolean): void {\n    this.el.disabled = desactive;\n  }\n\n  onInput(): void {\n    const saisie = this.el.value;\n    const curseur = this.el.selectionStart ?? saisie.length;\n    const avant = significatifsAvant(saisie, curseur);\n    const { texte, valeur } = parseMontant(saisie, this.sep);\n    this.el.value = texte;\n    const position = positionApres(texte, avant);\n    this.el.setSelectionRange(position, position);\n    this.onChange(valeur);\n  }\n\n  onBlur(): void {\n    // Une décimale laissée en suspens (« 12, ») est retirée en quittant le champ.\n    const { valeur } = parseMontant(this.el.value, this.sep);\n    this.el.value = formatMontant(valeur, this.sep);\n    this.onTouched();\n  }\n}\n","import {\n  ChangeDetectorRef,\n  Component,\n  EventEmitter,\n  HostBinding,\n  inject,\n  Input,\n  OnInit,\n  Output,\n} from '@angular/core';\nimport { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';\nimport { HttpClient, HttpParams } from '@angular/common/http';\nimport { MatFormField, MatLabel, MatError, MatHint, MatPrefix, MatSuffix } from '@angular/material/form-field';\nimport { MatInput } from '@angular/material/input';\nimport { MatSelect } from '@angular/material/select';\nimport { DateAdapter, MatOption, provideNativeDateAdapter } from '@angular/material/core';\nimport { MatAutocompleteModule, MatAutocompleteSelectedEvent } from '@angular/material/autocomplete';\nimport { MatRadioGroup, MatRadioButton } from '@angular/material/radio';\nimport { MatCheckbox } from '@angular/material/checkbox';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatProgressSpinner } from '@angular/material/progress-spinner';\nimport { MatDatepickerModule } from '@angular/material/datepicker';\nimport { MatSliderModule } from '@angular/material/slider';\nimport { MatSlideToggleModule } from '@angular/material/slide-toggle';\nimport { MatIconButton } from '@angular/material/button';\nimport { MatMenuModule } from '@angular/material/menu';\nimport { Subject, of } from 'rxjs';\nimport { debounceTime, distinctUntilChanged, filter, switchMap, tap, catchError, map } from 'rxjs/operators';\nimport { DynamicFormField, FieldCondition, SelectOption } from '../../models/form-field.model';\nimport { DynamicFormBuilderService } from '../../services/dynamic-form-builder.service';\nimport { ConditionEvaluatorService } from '../../services/condition-evaluator.service';\nimport { NGX_DATA_API_URL, NGX_DATE_LOCALE } from '../../providers';\nimport { PHONE_COUNTRIES, PhoneCountry } from '../../data/phone-countries';\nimport { getPath, optionLabel } from '../../utils/option-label';\nimport { toIsoDate } from '../../utils/field-compare';\nimport { ThousandsInputDirective } from '../../utils/thousands-input.directive';\n\n@Component({\n  selector: 'ngx-dynamic-field',\n  standalone: true,\n  providers: [provideNativeDateAdapter()],\n  imports: [\n    ReactiveFormsModule,\n    MatFormField, MatLabel, MatError, MatHint, MatPrefix, MatSuffix,\n    MatInput,\n    MatSelect, MatOption,\n    MatAutocompleteModule,\n    MatRadioGroup, MatRadioButton,\n    MatCheckbox,\n    MatIcon,\n    MatProgressSpinner,\n    MatDatepickerModule,\n    MatSliderModule,\n    MatSlideToggleModule,\n    MatIconButton,\n    MatMenuModule,\n    ThousandsInputDirective,\n  ],\n  template: `\n    @if (field.type === 'divider') {\n      <hr class=\"ngx-divider\"\n          [style.borderTopWidth]=\"field.dividerHeight || null\"\n          [style.borderTopColor]=\"field.dividerColor || null\"\n          [style.width]=\"field.dividerWidth || null\" />\n    }\n\n    @if (field.type === 'heading') {\n      @switch (field.level || 2) {\n        @case (1) { <h1 class=\"ngx-heading\">{{ field.text || field.label }}</h1> }\n        @case (2) { <h2 class=\"ngx-heading\">{{ field.text || field.label }}</h2> }\n        @case (3) { <h3 class=\"ngx-heading\">{{ field.text || field.label }}</h3> }\n        @case (4) { <h4 class=\"ngx-heading\">{{ field.text || field.label }}</h4> }\n        @case (5) { <h5 class=\"ngx-heading\">{{ field.text || field.label }}</h5> }\n        @case (6) { <h6 class=\"ngx-heading\">{{ field.text || field.label }}</h6> }\n        @default   { <h2 class=\"ngx-heading\">{{ field.text || field.label }}</h2> }\n      }\n    }\n\n    @if (isInputField) {\n      @if (field.type === 'checkbox') {\n        <div class=\"ngx-checkbox-wrapper\">\n          <mat-checkbox color=\"primary\" [formControl]=\"formControl\">\n            {{ field.placeholder || field.label }}\n          </mat-checkbox>\n          @if (hasError) {\n            <small class=\"ngx-mat-standalone-error\">{{ errorMessage }}</small>\n          }\n        </div>\n\n      } @else if (field.type === 'radio') {\n        <div class=\"ngx-radio-wrapper\">\n          @if (field.label) {\n            <label class=\"ngx-radio-label\">{{ field.label }}</label>\n          }\n          <mat-radio-group [formControl]=\"formControl\" class=\"ngx-radio-group\">\n            @if (loadingOptions) {\n              <span class=\"ngx-options-loading\">\n                <mat-spinner diameter=\"16\" />\n                Chargement…\n              </span>\n            } @else {\n              @for (opt of resolvedOptions; track opt.value) {\n                <mat-radio-button [value]=\"opt.value\" color=\"primary\">\n                  {{ opt.label }}\n                </mat-radio-button>\n              }\n            }\n          </mat-radio-group>\n          @if (hasError) {\n            <small class=\"ngx-mat-standalone-error\">{{ errorMessage }}</small>\n          }\n        </div>\n\n      } @else if (field.type === 'textarea') {\n        @if (isSimple) {\n          <div class=\"ngx-simple-field\">\n            @if (field.label) {\n              <label class=\"ngx-simple-label\" [for]=\"field.key\">\n                {{ field.label }}@if (field.validation?.required) { <span class=\"ngx-simple-required\"> *</span> }\n              </label>\n            }\n            <textarea\n              [id]=\"field.key\"\n              class=\"ngx-simple-input\"\n              [class.ngx-simple-error-border]=\"hasError\"\n              [formControl]=\"formControl\"\n              [placeholder]=\"field.placeholder || ''\"\n              [rows]=\"field.rows || 3\"\n              [readonly]=\"field.readonly || false\"\n            ></textarea>\n            @if (field.hint && !hasError) { <small class=\"ngx-simple-hint\">{{ field.hint }}</small> }\n            @if (hasError) { <small class=\"ngx-simple-error-msg\">{{ errorMessage }}</small> }\n          </div>\n        } @else {\n          <mat-form-field [appearance]=\"matAppearance\" [floatLabel]=\"resolvedFloatLabel\" class=\"ngx-mat-field\">\n            @if (field.label) { <mat-label>{{ field.label }}</mat-label> }\n            @if (field.icon) { <mat-icon matPrefix>{{ field.icon }}</mat-icon> }\n            @if (field.prefix) { <span matPrefix class=\"ngx-affix-text\">{{ field.prefix }}</span> }\n            <textarea\n              matInput\n              [id]=\"field.key\"\n              [formControl]=\"formControl\"\n              [placeholder]=\"field.placeholder || ''\"\n              [rows]=\"field.rows || 3\"\n              [readonly]=\"field.readonly || false\"\n            ></textarea>\n            @if (field.suffix) { <span matSuffix class=\"ngx-affix-text\">{{ field.suffix }}</span> }\n            @if (field.iconSuffix) { <mat-icon matSuffix>{{ field.iconSuffix }}</mat-icon> }\n            @if (field.hint) { <mat-hint>{{ field.hint }}</mat-hint> }\n            <mat-error>{{ errorMessage }}</mat-error>\n          </mat-form-field>\n        }\n\n      } @else if (field.type === 'select' || field.type === 'multiselect') {\n        @if (isSimple) {\n          <div class=\"ngx-simple-field\">\n            @if (field.label) {\n              <label class=\"ngx-simple-label\" [for]=\"field.key\">\n                {{ field.label }}@if (field.validation?.required) { <span class=\"ngx-simple-required\"> *</span> }\n              </label>\n            }\n            @if (loadingOptions) {\n              <div class=\"ngx-simple-loading\">\n                <mat-spinner diameter=\"16\" />\n                <span>Chargement…</span>\n              </div>\n            } @else {\n              <select\n                [id]=\"field.key\"\n                class=\"ngx-simple-select\"\n                [class.ngx-simple-error-border]=\"hasError\"\n                [formControl]=\"formControl\"\n                [multiple]=\"field.type === 'multiselect'\"\n              >\n                @if (field.placeholder) { <option value=\"\">{{ field.placeholder }}</option> }\n                @for (opt of resolvedOptions; track opt.value) {\n                  <option [value]=\"opt.value\" [disabled]=\"opt.disabled || false\">{{ opt.label }}</option>\n                }\n              </select>\n            }\n            @if (field.hint && !hasError) { <small class=\"ngx-simple-hint\">{{ field.hint }}</small> }\n            @if (hasError) { <small class=\"ngx-simple-error-msg\">{{ errorMessage }}</small> }\n          </div>\n        } @else if (field.remoteSearch) {\n          <mat-form-field [appearance]=\"matAppearance\" [floatLabel]=\"resolvedFloatLabel\" class=\"ngx-mat-field\">\n            @if (field.label) { <mat-label>{{ field.label }}</mat-label> }\n            @if (field.icon) { <mat-icon matPrefix>{{ field.icon }}</mat-icon> }\n            <input matInput\n              [formControl]=\"searchDisplayControl\"\n              [matAutocomplete]=\"remoteAuto\"\n              [placeholder]=\"field.placeholder || ''\"\n              [readonly]=\"field.readonly || false\" />\n            @if (loadingOptions) { <mat-spinner matSuffix diameter=\"16\" /> }\n            <mat-autocomplete #remoteAuto=\"matAutocomplete\" [displayWith]=\"displayRemoteOption\" (optionSelected)=\"onRemoteOptionSelected($event)\">\n              @if (!loadingOptions && resolvedOptions.length === 0 && remoteSearchHasEnoughChars) {\n                <mat-option disabled>Aucun résultat</mat-option>\n              }\n              @for (opt of resolvedOptions; track opt.value) {\n                <mat-option [value]=\"opt\" [disabled]=\"opt.disabled || false\">{{ opt.label }}</mat-option>\n              }\n            </mat-autocomplete>\n            @if (field.hint) { <mat-hint>{{ field.hint }}</mat-hint> }\n            <mat-error>{{ errorMessage }}</mat-error>\n          </mat-form-field>\n\n        } @else {\n          <mat-form-field [appearance]=\"matAppearance\" [floatLabel]=\"resolvedFloatLabel\" class=\"ngx-mat-field\">\n            @if (field.label) { <mat-label>{{ field.label }}</mat-label> }\n            @if (field.icon) { <mat-icon matPrefix>{{ field.icon }}</mat-icon> }\n            @if (field.prefix) { <span matPrefix class=\"ngx-affix-text\">{{ field.prefix }}</span> }\n            <mat-select [formControl]=\"formControl\" [multiple]=\"field.type === 'multiselect'\">\n              @if (loadingOptions) {\n                <mat-option disabled>\n                  <span class=\"ngx-options-loading-inline\">\n                    <mat-spinner diameter=\"14\" />\n                    Chargement…\n                  </span>\n                </mat-option>\n              } @else {\n                @if (field.placeholder) {\n                  <mat-option value=\"\">{{ field.placeholder }}</mat-option>\n                }\n                @for (opt of resolvedOptions; track opt.value) {\n                  <mat-option [value]=\"opt.value\" [disabled]=\"opt.disabled || false\">\n                    {{ opt.label }}\n                  </mat-option>\n                }\n              }\n            </mat-select>\n            @if (field.suffix) { <span matSuffix class=\"ngx-affix-text\">{{ field.suffix }}</span> }\n            @if (field.iconSuffix) { <mat-icon matSuffix>{{ field.iconSuffix }}</mat-icon> }\n            @if (field.hint) { <mat-hint>{{ field.hint }}</mat-hint> }\n            <mat-error>{{ errorMessage }}</mat-error>\n          </mat-form-field>\n        }\n\n      } @else if (field.type === 'switch') {\n        <div class=\"ngx-switch-wrapper\">\n          <mat-slide-toggle color=\"primary\" [formControl]=\"formControl\">\n            {{ field.label || field.placeholder }}\n          </mat-slide-toggle>\n          @if (field.hint) { <small class=\"ngx-hint\">{{ field.hint }}</small> }\n        </div>\n\n      } @else if (field.type === 'date') {\n        @if (isSimple) {\n          <div class=\"ngx-simple-field\">\n            @if (field.label) {\n              <label class=\"ngx-simple-label\" [for]=\"field.key\">\n                {{ field.label }}@if (field.validation?.required) { <span class=\"ngx-simple-required\"> *</span> }\n              </label>\n            }\n            <div class=\"ngx-simple-input-row\" [class.ngx-simple-error-border]=\"hasError\">\n              <!-- Sélection au calendrier uniquement : saisie clavier bloquée, clic = sélecteur natif -->\n              <input [id]=\"field.key\" class=\"ngx-simple-input\" type=\"date\"\n                [formControl]=\"formControl\"\n                [readonly]=\"field.readonly || false\"\n                (keydown)=\"onNativeDateKeydown($event)\"\n                (click)=\"openNativeDatePicker($event)\"\n                [attr.min]=\"minDateAttr\" [attr.max]=\"maxDateAttr\" />\n            </div>\n            @if (field.hint && !hasError) { <small class=\"ngx-simple-hint\">{{ field.hint }}</small> }\n            @if (hasError) { <small class=\"ngx-simple-error-msg\">{{ errorMessage }}</small> }\n          </div>\n        } @else {\n          <mat-form-field [appearance]=\"matAppearance\" [floatLabel]=\"resolvedFloatLabel\" class=\"ngx-mat-field\">\n            @if (field.label) { <mat-label>{{ field.label }}</mat-label> }\n            @if (field.icon) { <mat-icon matPrefix>{{ field.icon }}</mat-icon> }\n            <!-- Sélection au calendrier uniquement : input toujours readonly (pas de saisie\n                 clavier, pas de parsing MM/JJ du NativeDateAdapter), un clic ouvre le calendrier.\n                 Accès clavier : le bouton mat-datepicker-toggle. -->\n            <input matInput [matDatepicker]=\"datepicker\" [id]=\"field.key\"\n              [formControl]=\"formControl\"\n              [placeholder]=\"field.placeholder || ''\"\n              readonly\n              (click)=\"field.readonly || datepicker.open()\"\n              [style.cursor]=\"field.readonly ? null : 'pointer'\"\n              [min]=\"minDate\" [max]=\"maxDate\" />\n            <mat-datepicker-toggle matIconSuffix [for]=\"datepicker\" />\n            <mat-datepicker #datepicker />\n            @if (field.hint) { <mat-hint>{{ field.hint }}</mat-hint> }\n            <mat-error>{{ errorMessage }}</mat-error>\n          </mat-form-field>\n        }\n\n      } @else if (field.type === 'range') {\n        <div class=\"ngx-range-wrapper\">\n          @if (field.label) {\n            <div class=\"ngx-range-header\">\n              <label class=\"ngx-range-label\">\n                {{ field.label }}@if (field.validation?.required) { <span class=\"ngx-simple-required\"> *</span> }\n              </label>\n              @if (field.showValue !== false) {\n                <span class=\"ngx-range-value\">{{ formControl.value ?? field.min ?? 0 }}</span>\n              }\n            </div>\n          }\n          <mat-slider class=\"ngx-slider\"\n            [min]=\"field.min ?? 0\" [max]=\"field.max ?? 100\" [step]=\"field.step ?? 1\"\n            [disabled]=\"formControl.disabled\">\n            <input matSliderThumb [formControl]=\"formControl\" />\n          </mat-slider>\n          <div class=\"ngx-range-limits\">\n            <span>{{ field.min ?? 0 }}</span>\n            <span>{{ field.max ?? 100 }}</span>\n          </div>\n          @if (field.hint) { <small class=\"ngx-hint\">{{ field.hint }}</small> }\n        </div>\n\n      } @else if (field.type === 'color') {\n        <div class=\"ngx-color-field\">\n          @if (field.label) {\n            <label class=\"ngx-color-label\" [for]=\"field.key\">\n              {{ field.label }}@if (field.validation?.required) { <span class=\"ngx-simple-required\"> *</span> }\n            </label>\n          }\n          <div class=\"ngx-color-row\">\n            <input type=\"color\" [id]=\"field.key\" class=\"ngx-color-input\" [formControl]=\"formControl\" />\n            <span class=\"ngx-color-hex\">{{ formControl.value || '#000000' }}</span>\n          </div>\n          @if (field.hint) { <small class=\"ngx-hint\">{{ field.hint }}</small> }\n          @if (hasError) { <small class=\"ngx-mat-standalone-error\">{{ errorMessage }}</small> }\n        </div>\n\n      } @else if (field.type === 'location') {\n        @if (isSimple) {\n          <div class=\"ngx-simple-field\">\n            @if (field.label) {\n              <label class=\"ngx-simple-label\" [for]=\"field.key\">\n                {{ field.label }}@if (field.validation?.required) { <span class=\"ngx-simple-required\"> *</span> }\n              </label>\n            }\n            <div class=\"ngx-simple-input-row\" [class.ngx-simple-error-border]=\"hasError || !!locationError\">\n              <mat-icon class=\"ngx-simple-icon\">location_on</mat-icon>\n              <input [id]=\"field.key\" class=\"ngx-simple-input\" type=\"text\"\n                [formControl]=\"formControl\"\n                [placeholder]=\"field.placeholder || 'Adresse ou coordonnées GPS'\"\n                [readonly]=\"field.readonly || false\" />\n              @if (!field.readonly) {\n                <button type=\"button\" class=\"ngx-geo-btn\" (click)=\"getLocation()\" [disabled]=\"locating\" title=\"Ma position\">\n                  @if (locating) { <mat-progress-spinner diameter=\"16\" mode=\"indeterminate\" /> }\n                  @else { <mat-icon>my_location</mat-icon> }\n                </button>\n              }\n            </div>\n            @if (locationError) { <small class=\"ngx-simple-error-msg\">{{ locationError }}</small> }\n            @else if (field.hint && !hasError) { <small class=\"ngx-simple-hint\">{{ field.hint }}</small> }\n            @else if (hasError) { <small class=\"ngx-simple-error-msg\">{{ errorMessage }}</small> }\n          </div>\n        } @else {\n          <mat-form-field [appearance]=\"matAppearance\" [floatLabel]=\"resolvedFloatLabel\" class=\"ngx-mat-field\">\n            @if (field.label) { <mat-label>{{ field.label }}</mat-label> }\n            <mat-icon matPrefix>location_on</mat-icon>\n            <input matInput [id]=\"field.key\" type=\"text\"\n              [formControl]=\"formControl\"\n              [placeholder]=\"field.placeholder || 'Adresse ou coordonnées GPS'\"\n              [readonly]=\"field.readonly || false\" />\n            @if (!field.readonly) {\n              <button matSuffix mat-icon-button type=\"button\" (click)=\"getLocation()\" [disabled]=\"locating\" title=\"Ma position\">\n                @if (locating) { <mat-progress-spinner diameter=\"18\" mode=\"indeterminate\" /> }\n                @else { <mat-icon>my_location</mat-icon> }\n              </button>\n            }\n            @if (field.hint) { <mat-hint>{{ field.hint }}</mat-hint> }\n            <mat-error>{{ errorMessage }}</mat-error>\n          </mat-form-field>\n          @if (locationError) { <small class=\"ngx-mat-standalone-error\" style=\"margin-top:-.5rem\">{{ locationError }}</small> }\n        }\n\n      } @else if (field.type === 'file') {\n        <div class=\"ngx-file-wrapper\">\n          @if (field.label) {\n            <label class=\"ngx-file-label\">\n              {{ field.label }}\n              @if (field.validation?.required) {\n                <span class=\"ngx-required\" aria-hidden=\"true\"> *</span>\n              }\n            </label>\n          }\n\n          <input #fileInput\n            type=\"file\"\n            [id]=\"field.key\"\n            [accept]=\"field.accept || '*'\"\n            [multiple]=\"field.multiple || false\"\n            [disabled]=\"field.disabled || field.readonly || false\"\n            (change)=\"onFileInputChange($event)\"\n            class=\"ngx-file-input-native\" />\n\n          @if (selectedFiles.length === 0) {\n            <button type=\"button\"\n              class=\"ngx-file-dropzone\"\n              [class.ngx-file-dropzone-active]=\"fileDragging\"\n              [disabled]=\"field.disabled || field.readonly || false\"\n              (click)=\"fileInput.click()\"\n              (dragover)=\"onFileDragOver($event)\"\n              (dragleave)=\"onFileDragLeave($event)\"\n              (drop)=\"onFileDrop($event)\"\n            >\n              <mat-icon>cloud_upload</mat-icon>\n              <span><strong>Cliquez pour choisir</strong> ou glissez-déposez{{ field.multiple ? ' un ou plusieurs fichiers' : ' un fichier' }}</span>\n            </button>\n          } @else {\n            <div class=\"ngx-file-list\">\n              @for (file of selectedFiles; track file.name + file.size; let fi = $index) {\n                <div class=\"ngx-file-chip\">\n                  <mat-icon>description</mat-icon>\n                  <span class=\"ngx-file-chip-name\">{{ file.name }}</span>\n                  <span class=\"ngx-file-chip-size\">{{ formatFileSize(file.size) }}</span>\n                  @if (!field.disabled && !field.readonly) {\n                    <button type=\"button\" class=\"ngx-file-chip-remove\" (click)=\"removeFile(fi, fileInput)\" title=\"Retirer\">\n                      <mat-icon>close</mat-icon>\n                    </button>\n                  }\n                </div>\n              }\n              @if (field.multiple && !field.disabled && !field.readonly) {\n                <button type=\"button\" class=\"ngx-file-add-more\" (click)=\"fileInput.click()\">\n                  <mat-icon>add</mat-icon> Ajouter un fichier\n                </button>\n              }\n            </div>\n          }\n\n          @if (field.hint && !hasError) { <small class=\"ngx-hint\">{{ field.hint }}</small> }\n          @if (hasError) { <small class=\"ngx-mat-standalone-error\">{{ errorMessage }}</small> }\n        </div>\n\n      } @else if (field.type === 'phone') {\n        @if (isSimple) {\n          <div class=\"ngx-phone-wrapper\">\n            @if (field.label) {\n              <label class=\"ngx-phone-label\" [for]=\"field.key\">\n                {{ field.label }}@if (field.validation?.required) { <span class=\"ngx-simple-required\"> *</span> }\n              </label>\n            }\n            <div class=\"ngx-phone-row\" [class.ngx-phone-error]=\"hasError\">\n              <select class=\"ngx-phone-country\"\n                [value]=\"selectedPhoneCountry.code\"\n                (change)=\"onPhoneSelectChange($event)\">\n                @for (c of phoneCountries; track c.code) {\n                  <option [value]=\"c.code\">{{ c.flag }} {{ c.dialCode }}</option>\n                }\n              </select>\n              <input [id]=\"field.key\"\n                class=\"ngx-phone-input\"\n                type=\"tel\"\n                [value]=\"phoneDisplay\"\n                [placeholder]=\"field.placeholder || ''\"\n                [readonly]=\"field.readonly || false\"\n                (input)=\"applyPhoneMask($event)\" />\n            </div>\n            @if (field.hint && !hasError) { <small class=\"ngx-simple-hint\">{{ field.hint }}</small> }\n            @if (hasError) { <small class=\"ngx-mat-standalone-error\">{{ errorMessage }}</small> }\n          </div>\n        } @else {\n          <mat-form-field [appearance]=\"matAppearance\" [floatLabel]=\"resolvedFloatLabel\" class=\"ngx-mat-field ngx-phone-field\">\n            @if (field.label) {\n              <mat-label>{{ field.label }}@if (field.validation?.required) { <span class=\"ngx-simple-required\"> *</span> }</mat-label>\n            }\n            <button type=\"button\" matPrefix class=\"ngx-phone-flag-trigger\"\n              [matMenuTriggerFor]=\"countryMenu\"\n              [attr.aria-label]=\"'Indicatif téléphonique : ' + selectedPhoneCountry.name\">\n              <span class=\"fi fi-{{ selectedPhoneCountry.code.toLowerCase() }} ngx-phone-flag\"></span>\n              <span class=\"ngx-phone-dial-code\">{{ selectedPhoneCountry.dialCode }}</span>\n              <mat-icon class=\"ngx-phone-caret\">arrow_drop_down</mat-icon>\n            </button>\n            <input matInput\n              [id]=\"field.key\"\n              type=\"tel\"\n              [value]=\"phoneDisplay\"\n              [placeholder]=\"field.placeholder || ''\"\n              [readonly]=\"field.readonly || false\"\n              (input)=\"applyPhoneMask($event)\" />\n            @if (field.hint && !hasError) { <mat-hint>{{ field.hint }}</mat-hint> }\n            @if (hasError) { <mat-error>{{ errorMessage }}</mat-error> }\n          </mat-form-field>\n\n          <mat-menu #countryMenu=\"matMenu\" class=\"ngx-phone-menu\">\n            <div class=\"ngx-phone-menu-search\" (click)=\"$event.stopPropagation()\" (keydown)=\"$event.stopPropagation()\">\n              <mat-icon class=\"ngx-phone-menu-search-icon\">search</mat-icon>\n              <input type=\"text\" placeholder=\"Rechercher un pays…\" autocomplete=\"off\"\n                [value]=\"phoneSearch\"\n                (input)=\"phoneSearch = $any($event.target).value\" />\n            </div>\n            <div class=\"ngx-phone-menu-list\">\n              @for (c of filteredPhoneCountries; track c.code) {\n                <button mat-menu-item type=\"button\" (click)=\"selectPhoneCountry(c)\">\n                  <span class=\"fi fi-{{ c.code.toLowerCase() }} ngx-phone-flag\"></span>\n                  <span class=\"ngx-phone-menu-name\">{{ c.name }}</span>\n                  <span class=\"ngx-phone-menu-dial\">{{ c.dialCode }}</span>\n                </button>\n              } @empty {\n                <div class=\"ngx-phone-menu-empty\">Aucun pays trouvé</div>\n              }\n            </div>\n          </mat-menu>\n        }\n\n      } @else if (field.type === 'hidden') {\n        <input type=\"hidden\" [formControl]=\"formControl\" />\n\n      } @else if (field.type === 'iso-country') {\n        @if (isSimple) {\n          <div class=\"ngx-simple-field\">\n            @if (field.label) {\n              <label class=\"ngx-simple-label\" [for]=\"field.key\">\n                {{ field.label }}@if (field.validation?.required) { <span class=\"ngx-simple-required\"> *</span> }\n              </label>\n            }\n            <input [id]=\"field.key\" class=\"ngx-simple-input\"\n              type=\"text\"\n              [formControl]=\"isoCountrySearchCtrl\"\n              [matAutocomplete]=\"isoCountryAutoSimple\"\n              [placeholder]=\"field.placeholder || 'Nom du pays ou code…'\"\n              [readonly]=\"field.readonly || false\" />\n            <mat-autocomplete #isoCountryAutoSimple=\"matAutocomplete\" [displayWith]=\"displayIsoCountry\" (optionSelected)=\"onIsoCountrySelected($event)\">\n              @for (c of filteredIsoCountries; track c.code) {\n                <mat-option [value]=\"c\"><span class=\"fi fi-{{ c.code.toLowerCase() }} ngx-phone-flag\"></span> {{ c.name }} ({{ c.code }})</mat-option>\n              }\n            </mat-autocomplete>\n            @if (field.hint && !hasError) { <small class=\"ngx-simple-hint\">{{ field.hint }}</small> }\n            @if (hasError) { <small class=\"ngx-simple-error-msg\">{{ errorMessage }}</small> }\n          </div>\n        } @else {\n          <mat-form-field [appearance]=\"matAppearance\" [floatLabel]=\"resolvedFloatLabel\" class=\"ngx-mat-field\">\n            @if (field.label) { <mat-label>{{ field.label }}</mat-label> }\n            <input matInput [id]=\"field.key\"\n              type=\"text\"\n              [formControl]=\"isoCountrySearchCtrl\"\n              [matAutocomplete]=\"isoCountryAuto\"\n              [placeholder]=\"field.placeholder || 'Nom du pays ou code…'\"\n              [readonly]=\"field.readonly || false\" />\n            <mat-autocomplete #isoCountryAuto=\"matAutocomplete\" [displayWith]=\"displayIsoCountry\" (optionSelected)=\"onIsoCountrySelected($event)\">\n              @for (c of filteredIsoCountries; track c.code) {\n                <mat-option [value]=\"c\"><span class=\"fi fi-{{ c.code.toLowerCase() }} ngx-phone-flag\"></span> {{ c.name }} ({{ c.code }})</mat-option>\n              }\n            </mat-autocomplete>\n            @if (field.hint) { <mat-hint>{{ field.hint }}</mat-hint> }\n            <mat-error>{{ errorMessage }}</mat-error>\n          </mat-form-field>\n        }\n\n      } @else if (field.type === 'country-dial-code') {\n        @if (isSimple) {\n          <div class=\"ngx-simple-field\">\n            @if (field.label) {\n              <label class=\"ngx-simple-label\" [for]=\"field.key\">\n                {{ field.label }}@if (field.validation?.required) { <span class=\"ngx-simple-required\"> *</span> }\n              </label>\n            }\n            <input [id]=\"field.key\" class=\"ngx-simple-input\"\n              type=\"text\"\n              [formControl]=\"dialCodeSearchCtrl\"\n              [matAutocomplete]=\"dialCodeAutoSimple\"\n              [placeholder]=\"field.placeholder || 'Nom du pays, indicatif ou code…'\"\n              [readonly]=\"field.readonly || false\" />\n            <mat-autocomplete #dialCodeAutoSimple=\"matAutocomplete\" [displayWith]=\"displayDialCode\" (optionSelected)=\"onDialCodeSelected($event)\">\n              @for (c of filteredDialCodeCountries; track c.code) {\n                <mat-option [value]=\"c\"><span class=\"fi fi-{{ c.code.toLowerCase() }} ngx-phone-flag\"></span> {{ c.name }} ({{ c.dialCode }})</mat-option>\n              }\n            </mat-autocomplete>\n            @if (field.hint && !hasError) { <small class=\"ngx-simple-hint\">{{ field.hint }}</small> }\n            @if (hasError) { <small class=\"ngx-simple-error-msg\">{{ errorMessage }}</small> }\n          </div>\n        } @else {\n          <mat-form-field [appearance]=\"matAppearance\" [floatLabel]=\"resolvedFloatLabel\" class=\"ngx-mat-field\">\n            @if (field.label) { <mat-label>{{ field.label }}</mat-label> }\n            <input matInput [id]=\"field.key\"\n              type=\"text\"\n              [formControl]=\"dialCodeSearchCtrl\"\n              [matAutocomplete]=\"dialCodeAuto\"\n              [placeholder]=\"field.placeholder || 'Nom du pays, indicatif ou code…'\"\n              [readonly]=\"field.readonly || false\" />\n            <mat-autocomplete #dialCodeAuto=\"matAutocomplete\" [displayWith]=\"displayDialCode\" (optionSelected)=\"onDialCodeSelected($event)\">\n              @for (c of filteredDialCodeCountries; track c.code) {\n                <mat-option [value]=\"c\"><span class=\"fi fi-{{ c.code.toLowerCase() }} ngx-phone-flag\"></span> {{ c.name }} ({{ c.dialCode }})</mat-option>\n              }\n            </mat-autocomplete>\n            @if (field.hint) { <mat-hint>{{ field.hint }}</mat-hint> }\n            <mat-error>{{ errorMessage }}</mat-error>\n          </mat-form-field>\n        }\n\n      } @else if (field.type === 'number' && field.thousandSeparator) {\n        <!-- Montant avec séparateur de milliers (v1.7.21) : input texte + ThousandsInputDirective,\n             le FormControl reste numérique. -->\n        @if (isSimple) {\n          <div class=\"ngx-simple-field\">\n            @if (field.label) {\n              <label class=\"ngx-simple-label\" [for]=\"field.key\">\n                {{ field.label }}@if (field.validation?.required) { <span class=\"ngx-simple-required\"> *</span> }\n              </label>\n            }\n            <div class=\"ngx-simple-input-row\" [class.ngx-simple-error-border]=\"hasError\">\n              @if (field.icon) { <mat-icon class=\"ngx-simple-icon\">{{ field.icon }}</mat-icon> }\n              @if (field.prefix) { <span class=\"ngx-simple-affix ngx-simple-prefix\">{{ field.prefix }}</span> }\n              <input\n                [id]=\"field.key\"\n                class=\"ngx-simple-input ngx-amount-input\"\n                type=\"text\"\n                [ngxThousands]=\"field.thousandSeparator\"\n                [formControl]=\"formControl\"\n                [placeholder]=\"field.placeholder || ''\"\n                [readonly]=\"field.readonly || false\"\n                (blur)=\"onLookupBlur()\"\n              />\n              @if (field.suffix) { <span class=\"ngx-simple-affix ngx-simple-suffix\">{{ field.suffix }}</span> }\n              @if (field.iconSuffix) { <mat-icon class=\"ngx-simple-icon\">{{ field.iconSuffix }}</mat-icon> }\n            </div>\n            @if (field.hint && !hasError) { <small class=\"ngx-simple-hint\">{{ field.hint }}</small> }\n            @if (hasError) { <small class=\"ngx-simple-error-msg\">{{ errorMessage }}</small> }\n          </div>\n        } @else {\n          <mat-form-field [appearance]=\"matAppearance\" [floatLabel]=\"resolvedFloatLabel\" class=\"ngx-mat-field\">\n            @if (field.label) { <mat-label>{{ field.label }}</mat-label> }\n            @if (field.icon) { <mat-icon matPrefix>{{ field.icon }}</mat-icon> }\n            @if (field.prefix) { <span matPrefix class=\"ngx-affix-text\">{{ field.prefix }}</span> }\n            <input\n              matInput\n              [id]=\"field.key\"\n              class=\"ngx-amount-input\"\n              type=\"text\"\n              [ngxThousands]=\"field.thousandSeparator\"\n              [formControl]=\"formControl\"\n              [placeholder]=\"field.placeholder || ''\"\n              [readonly]=\"field.readonly || false\"\n              (blur)=\"onLookupBlur()\"\n            />\n            @if (field.suffix) { <span matSuffix class=\"ngx-affix-text\">{{ field.suffix }}</span> }\n            @if (field.iconSuffix) { <mat-icon matSuffix>{{ field.iconSuffix }}</mat-icon> }\n            @if (field.hint) { <mat-hint>{{ field.hint }}</mat-hint> }\n            <mat-error>{{ errorMessage }}</mat-error>\n          </mat-form-field>\n        }\n      } @else {\n        @if (isSimple) {\n          <div class=\"ngx-simple-field\">\n            @if (field.label) {\n              <label class=\"ngx-simple-label\" [for]=\"field.key\">\n                {{ field.label }}@if (field.validation?.required) { <span class=\"ngx-simple-required\"> *</span> }\n              </label>\n            }\n            <div class=\"ngx-simple-input-row\" [class.ngx-simple-error-border]=\"hasError\">\n              @if (field.icon) { <mat-icon class=\"ngx-simple-icon\">{{ field.icon }}</mat-icon> }\n              @if (field.prefix) { <span class=\"ngx-simple-affix ngx-simple-prefix\">{{ field.prefix }}</span> }\n              <input\n                [id]=\"field.key\"\n                class=\"ngx-simple-input\"\n                [type]=\"field.type\"\n                [formControl]=\"formControl\"\n                [placeholder]=\"field.placeholder || ''\"\n                [readonly]=\"field.readonly || false\"\n                [attr.min]=\"field.validation?.min\"\n                [attr.max]=\"field.validation?.max\"\n                [attr.minlength]=\"field.validation?.minLength\"\n                [attr.maxlength]=\"field.validation?.maxLength\"\n                (input)=\"applyMask($event)\"\n                (blur)=\"onLookupBlur()\"\n              />\n              @if (field.suffix) { <span class=\"ngx-simple-affix ngx-simple-suffix\">{{ field.suffix }}</span> }\n              @if (field.iconSuffix) { <mat-icon class=\"ngx-simple-icon\">{{ field.iconSuffix }}</mat-icon> }\n            </div>\n            @if (field.hint && !hasError) { <small class=\"ngx-simple-hint\">{{ field.hint }}</small> }\n            @if (hasError) { <small class=\"ngx-simple-error-msg\">{{ errorMessage }}</small> }\n            @if (lookupLoading) {\n              <small class=\"ngx-simple-hint\">\n                <mat-spinner diameter=\"12\" style=\"display:inline-block\" />\n                Chargement…\n              </small>\n            }\n          </div>\n        } @else {\n          <mat-form-field [appearance]=\"matAppearance\" [floatLabel]=\"resolvedFloatLabel\" class=\"ngx-mat-field\">\n            @if (field.label) { <mat-label>{{ field.label }}</mat-label> }\n            @if (field.icon) { <mat-icon matPrefix>{{ field.icon }}</mat-icon> }\n            @if (field.prefix) { <span matPrefix class=\"ngx-affix-text\">{{ field.prefix }}</span> }\n            <input\n              matInput\n              [id]=\"field.key\"\n              [type]=\"field.type\"\n              [formControl]=\"formControl\"\n              [placeholder]=\"field.placeholder || ''\"\n              [readonly]=\"field.readonly || false\"\n              [attr.min]=\"field.validation?.min\"\n              [attr.max]=\"field.validation?.max\"\n              [attr.minlength]=\"field.validation?.minLength\"\n              [attr.maxlength]=\"field.validation?.maxLength\"\n              (input)=\"applyMask($event)\"\n              (blur)=\"onLookupBlur()\"\n            />\n            @if (field.suffix) { <span matSuffix class=\"ngx-affix-text\">{{ field.suffix }}</span> }\n            @if (field.iconSuffix) { <mat-icon matSuffix>{{ field.iconSuffix }}</mat-icon> }\n            @if (field.hint) { <mat-hint>{{ field.hint }}</mat-hint> }\n            <mat-error>{{ errorMessage }}</mat-error>\n            @if (lookupLoading) {\n              <mat-hint>\n                <mat-spinner diameter=\"12\" style=\"display:inline-block\" />\n                Chargement…\n              </mat-hint>\n            }\n          </mat-form-field>\n        }\n      }\n    }\n  `,\n  styles: [`\n    :host {\n      display: flex;\n      flex-direction: column;\n      width: 100%;\n      --ngx-field-color: inherit;\n      --ngx-field-bg: transparent;\n      --ngx-field-align: left;\n    }\n\n    /* Applique les variables de style sur les inputs Material */\n    :host ::ng-deep .mat-mdc-input-element {\n      color: var(--ngx-field-color) !important;\n      text-align: var(--ngx-field-align) !important;\n    }\n    :host ::ng-deep .mat-mdc-text-field-wrapper {\n      background-color: var(--ngx-field-bg) !important;\n    }\n\n    /* Couleur de bordure personnalisée — uniquement quand --ngx-border-color est défini */\n    :host[style*=\"--ngx-border-color\"] ::ng-deep .mdc-notched-outline__leading,\n    :host[style*=\"--ngx-border-color\"] ::ng-deep .mdc-notched-outline__notch,\n    :host[style*=\"--ngx-border-color\"] ::ng-deep .mdc-notched-outline__trailing {\n      border-color: var(--ngx-border-color) !important;\n    }\n    /* Fill mode: underline */\n    :host[style*=\"--ngx-border-color\"] ::ng-deep .mdc-line-ripple::before,\n    :host[style*=\"--ngx-border-color\"] ::ng-deep .mdc-line-ripple::after {\n      border-bottom-color: var(--ngx-border-color) !important;\n    }\n\n    /* Couleur du label personnalisée — uniquement quand --ngx-label-color est défini */\n    :host[style*=\"--ngx-label-color\"] ::ng-deep .mdc-floating-label,\n    :host[style*=\"--ngx-label-color\"] ::ng-deep .mat-mdc-floating-label {\n      color: var(--ngx-label-color) !important;\n    }\n\n    /* Le panneau du sélecteur de pays est monté via CDK Overlay, hors de\n       :host — pas de préfixe :host ici, sinon la règle ne l'atteint jamais. */\n    ::ng-deep .ngx-phone-menu {\n      min-width: 280px;\n    }\n\n    .ngx-affix-text {\n      font-size: 0.9em;\n      color: rgba(0,0,0,0.54);\n      padding: 0 2px;\n    }\n    .ngx-mat-field { width: 100%; }\n\n    /* ── Mode simple (label au-dessus, input borduré) ─────────── */\n    .ngx-simple-field {\n      display: flex;\n      flex-direction: column;\n      gap: 0.375rem;\n      width: 100%;\n      padding-bottom: 0.75rem;\n    }\n    .ngx-simple-label {\n      font-size: 0.875rem;\n      font-weight: 500;\n      color: var(--ngx-label-color, #374151);\n      line-height: 1.25;\n    }\n    .ngx-simple-required { color: #ef4444; }\n\n    .ngx-simple-input-row {\n      display: flex;\n      align-items: center;\n      border: 1px solid var(--ngx-border-color, #d1d5db);\n      border-radius: 8px;\n      background: #ffffff;\n      transition: border-color 0.15s, box-shadow 0.15s;\n      overflow: hidden;\n\n      &:focus-within {\n        border-color: var(--ngx-border-color, #6366f1);\n        box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.12);\n      }\n      &.ngx-simple-error-border {\n        border-color: #ef4444 !important;\n        box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.1);\n      }\n    }\n\n    .ngx-simple-input,\n    .ngx-simple-select,\n    textarea.ngx-simple-input {\n      flex: 1;\n      min-width: 0;\n      padding: 0.625rem 0.875rem;\n      border: none;\n      outline: none;\n      background: transparent;\n      font-size: 0.9375rem;\n      color: #111827;\n      font-family: inherit;\n      resize: vertical;\n\n      &::placeholder { color: #9ca3af; }\n      &:disabled { background: #f9fafb; cursor: not-allowed; color: #6b7280; }\n    }\n\n    textarea.ngx-simple-input {\n      border: 1px solid var(--ngx-border-color, #d1d5db);\n      border-radius: 8px;\n      padding: 0.625rem 0.875rem;\n      transition: border-color 0.15s, box-shadow 0.15s;\n      width: 100%;\n      box-sizing: border-box;\n\n      &:focus {\n        border-color: var(--ngx-border-color, #6366f1);\n        box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.12);\n        outline: none;\n      }\n      &.ngx-simple-error-border {\n        border-color: #ef4444 !important;\n      }\n    }\n\n    .ngx-simple-select {\n      border: 1px solid var(--ngx-border-color, #d1d5db);\n      border-radius: 8px;\n      padding: 0.625rem 0.875rem;\n      width: 100%;\n      box-sizing: border-box;\n      transition: border-color 0.15s, box-shadow 0.15s;\n      background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e\");\n      background-repeat: no-repeat;\n      background-position: right 0.75rem center;\n      background-size: 1.25em;\n      appearance: none;\n      -webkit-appearance: none;\n\n      &:focus {\n        border-color: var(--ngx-border-color, #6366f1);\n        box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.12);\n        outline: none;\n      }\n      &.ngx-simple-error-border { border-color: #ef4444 !important; }\n    }\n\n    .ngx-simple-icon {\n      font-size: 1.1rem;\n      width: 1.1rem;\n      height: 1.1rem;\n      color: #9ca3af;\n      padding: 0 0 0 0.75rem;\n      flex-shrink: 0;\n    }\n    .ngx-simple-affix {\n      font-size: 0.9rem;\n      color: #6b7280;\n      flex-shrink: 0;\n      white-space: nowrap;\n    }\n    .ngx-simple-prefix { padding-left: 0.75rem; }\n    .ngx-simple-suffix  { padding-right: 0.75rem; }\n\n    .ngx-simple-hint {\n      font-size: 0.75rem;\n      color: #6b7280;\n    }\n    .ngx-simple-error-msg {\n      font-size: 0.75rem;\n      color: #ef4444;\n    }\n    .ngx-simple-loading {\n      display: flex;\n      align-items: center;\n      gap: 0.5rem;\n      padding: 0.5rem 0;\n      font-size: 0.8125rem;\n      color: #9ca3af;\n    }\n    .ngx-radio-wrapper {\n      display: flex;\n      flex-direction: column;\n      gap: 0.5rem;\n      padding: 0.25rem 0 0.75rem;\n    }\n    .ngx-radio-label {\n      font-size: 0.875rem;\n      font-weight: 500;\n      color: rgba(0, 0, 0, 0.6);\n    }\n    .ngx-radio-group { display: flex; flex-wrap: wrap; gap: 0.75rem; }\n    .ngx-checkbox-wrapper {\n      display: flex;\n      flex-direction: column;\n      gap: 0.25rem;\n      padding: 0.25rem 0;\n    }\n    .ngx-file-wrapper {\n      display: flex;\n      flex-direction: column;\n      gap: 0.375rem;\n      padding-bottom: 0.75rem;\n    }\n    .ngx-file-label {\n      font-size: 0.875rem;\n      font-weight: 500;\n      color: rgba(0, 0, 0, 0.87);\n    }\n    .ngx-file-input-native { display: none; }\n    .ngx-file-dropzone {\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      gap: 0.375rem;\n      width: 100%;\n      border: 1.5px dashed rgba(0, 0, 0, 0.23);\n      border-radius: 6px;\n      padding: 1.25rem 1rem;\n      font-size: 0.8125rem;\n      color: rgba(0, 0, 0, 0.6);\n      text-align: center;\n      cursor: pointer;\n      background: rgba(0, 0, 0, 0.015);\n      transition: border-color 0.15s, background-color 0.15s;\n    }\n    .ngx-file-dropzone:hover:not(:disabled) { border-color: #6366f1; background: rgba(99, 102, 241, 0.04); }\n    .ngx-file-dropzone-active { border-color: #6366f1; background: rgba(99, 102, 241, 0.06); }\n    .ngx-file-dropzone:disabled { cursor: not-allowed; opacity: 0.6; }\n    .ngx-file-dropzone mat-icon { color: rgba(0, 0, 0, 0.4); }\n    .ngx-file-list { display: flex; flex-direction: column; gap: 0.375rem; }\n    .ngx-file-chip {\n      display: flex;\n      align-items: center;\n      gap: 0.5rem;\n      border: 1px solid rgba(0, 0, 0, 0.12);\n      border-radius: 6px;\n      padding: 0.5rem 0.625rem;\n      background: rgba(0, 0, 0, 0.015);\n    }\n    .ngx-file-chip mat-icon { color: #6366f1; flex-shrink: 0; }\n    .ngx-file-chip-name { flex: 1; font-size: 0.8125rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n    .ngx-file-chip-size { font-size: 0.75rem; color: rgba(0, 0, 0, 0.5); flex-shrink: 0; }\n    .ngx-file-chip-remove {\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      border: none;\n      background: transparent;\n      cursor: pointer;\n      color: rgba(0, 0, 0, 0.4);\n      flex-shrink: 0;\n    }\n    .ngx-file-chip-remove:hover { color: #dc2626; }\n    .ngx-file-chip-remove mat-icon { font-size: 18px; width: 18px; height: 18px; }\n    .ngx-file-add-more {\n      display: flex;\n      align-items: center;\n      gap: 0.25rem;\n      align-self: flex-start;\n      border: none;\n      background: transparent;\n      color: #6366f1;\n      font-size: 0.8125rem;\n      cursor: pointer;\n      padding: 0.25rem 0;\n    }\n\n    /* ── Bouton GPS (champ location) ───────────────────────── */\n    .ngx-geo-btn {\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      width: 38px;\n      height: 38px;\n      border: none;\n      background: transparent;\n      cursor: pointer;\n      color: #6366f1;\n      border-radius: 0 7px 7px 0;\n      flex-shrink: 0;\n      transition: background 0.15s;\n\n      mat-icon { font-size: 1.1rem; width: 1.1rem; height: 1.1rem; }\n      &:hover:not(:disabled) { background: rgba(99, 102, 241, 0.1); }\n      &:disabled { color: #9ca3af; cursor: not-allowed; }\n    }\n\n    /* ── Switch (slide-toggle) ──────────────────────────────── */\n    .ngx-switch-wrapper {\n      display: flex;\n      flex-direction: column;\n      gap: 0.25rem;\n      padding: 0.375rem 0 0.75rem;\n    }\n\n    /* ── Range slider ───────────────────────────────────────── */\n    .ngx-range-wrapper {\n      display: flex;\n      flex-direction: column;\n      gap: 0.25rem;\n      padding-bottom: 0.75rem;\n      width: 100%;\n    }\n    .ngx-range-header {\n      display: flex;\n      align-items: center;\n      justify-content: space-between;\n    }\n    .ngx-range-label {\n      font-size: 0.875rem;\n      font-weight: 500;\n      color: rgba(0, 0, 0, 0.6);\n    }\n    .ngx-range-value {\n      font-size: 0.875rem;\n      font-weight: 600;\n      color: #6366f1;\n      min-width: 2.5rem;\n      text-align: right;\n    }\n    .ngx-slider { width: 100%; }\n    .ngx-range-limits {\n      display: flex;\n      justify-content: space-between;\n      font-size: 0.7rem;\n      color: rgba(0, 0, 0, 0.38);\n      margin-top: -0.25rem;\n    }\n\n    /* ── Color picker ───────────────────────────────────────── */\n    .ngx-color-field {\n      display: flex;\n      flex-direction: column;\n      gap: 0.375rem;\n      padding-bottom: 0.75rem;\n    }\n    .ngx-color-label {\n      font-size: 0.875rem;\n      font-weight: 500;\n      color: rgba(0, 0, 0, 0.6);\n    }\n    .ngx-color-row {\n      display: flex;\n      align-items: center;\n      gap: 0.75rem;\n    }\n    .ngx-color-input {\n      width: 48px;\n      height: 40px;\n      border: 1px solid rgba(0, 0, 0, 0.23);\n      border-radius: 6px;\n      padding: 2px;\n      cursor: pointer;\n      background: transparent;\n    }\n    .ngx-color-hex {\n      font-size: 0.875rem;\n      color: rgba(0, 0, 0, 0.6);\n      font-family: monospace;\n    }\n\n    .ngx-mat-standalone-error {\n      font-size: 0.75rem;\n      color: var(--mat-sys-error, #b00020);\n    }\n\n    /* ── Montant (thousandSeparator) : chiffres à chasse fixe, colonnes alignées ── */\n    .ngx-amount-input {\n      font-variant-numeric: tabular-nums;\n    }\n\n    /* ── Champ téléphone ────────────────────────────────────────── */\n    .ngx-phone-wrapper {\n      display: flex;\n      flex-direction: column;\n      gap: 0.375rem;\n      padding-bottom: 0.75rem;\n      width: 100%;\n    }\n    .ngx-phone-label {\n      font-size: 0.875rem;\n      font-weight: 500;\n      color: var(--ngx-label-color, #374151);\n    }\n    .ngx-phone-row {\n      display: flex;\n      border: 1px solid var(--ngx-border-color, #d1d5db);\n      border-radius: 8px;\n      overflow: hidden;\n      background: #fff;\n      transition: border-color 0.15s, box-shadow 0.15s;\n\n      &:focus-within {\n        border-color: var(--ngx-border-color, #6366f1);\n        box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.12);\n      }\n      &.ngx-phone-error {\n        border-color: #ef4444 !important;\n        box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.1);\n      }\n    }\n    .ngx-phone-country {\n      border: none;\n      border-right: 1px solid #e5e7eb;\n      background: #f9fafb;\n      padding: 0 8px;\n      font-size: 0.875rem;\n      cursor: pointer;\n      outline: none;\n      min-width: 90px;\n      color: #374151;\n      appearance: none;\n      -webkit-appearance: none;\n      &:focus { background: #f3f4f6; }\n    }\n    .ngx-phone-input {\n      flex: 1;\n      min-width: 0;\n      padding: 0.625rem 0.875rem;\n      border: none;\n      outline: none;\n      background: transparent;\n      font-size: 0.9375rem;\n      color: #111827;\n      font-family: inherit;\n      &::placeholder { color: #9ca3af; }\n      &:disabled { background: #f9fafb; cursor: not-allowed; color: #6b7280; }\n    }\n\n    /* Champ téléphone — variante Material (apparence outline/fill, ni simple) */\n    .ngx-phone-flag-trigger {\n      display: flex;\n      align-items: center;\n      gap: 0.375rem;\n      border: none;\n      background: transparent;\n      padding: 0 0.375rem;\n      margin-right: 0.375rem;\n      cursor: pointer;\n      border-radius: 4px;\n      &:hover { background: rgba(0, 0, 0, 0.04); }\n      &:focus-visible { outline: 2px solid rgba(99, 102, 241, 0.5); outline-offset: 1px; }\n    }\n    .ngx-phone-flag {\n      /* Icônes SVG (package flag-icons) plutôt que l'emoji Unicode : rendu\n         identique partout — les drapeaux emoji tombent en repli sur deux\n         lettres nues sur Windows/webviews sans police couleur adéquate. */\n      font-size: 1.25rem; /* la largeur de .fi est relative à cette taille (1.333em) */\n      vertical-align: middle;\n      border-radius: 2px;\n      box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08);\n    }\n    .ngx-phone-menu-list .ngx-phone-flag {\n      font-size: 1.125rem;\n    }\n    .ngx-phone-dial-code {\n      font-size: 0.875rem;\n      color: rgba(0, 0, 0, 0.6);\n    }\n    .ngx-phone-caret {\n      width: 1.125rem;\n      height: 1.125rem;\n      font-size: 1.125rem;\n      color: rgba(0, 0, 0, 0.45);\n    }\n    .ngx-phone-menu-search {\n      display: flex;\n      align-items: center;\n      gap: 0.5rem;\n      padding: 0.5rem 0.75rem;\n      border-bottom: 1px solid rgba(0, 0, 0, 0.08);\n\n      .ngx-phone-menu-search-icon {\n        width: 1.125rem;\n        height: 1.125rem;\n        font-size: 1.125rem;\n        color: rgba(0, 0, 0, 0.4);\n      }\n      input {\n        flex: 1;\n        min-width: 0;\n        border: none;\n        outline: none;\n        font-size: 0.875rem;\n        background: transparent;\n        &::placeholder { color: rgba(0, 0, 0, 0.4); }\n      }\n    }\n    .ngx-phone-menu-list {\n      max-height: 260px;\n      overflow-y: auto;\n    }\n    /* MatMenuItem projette tout contenu non-icône dans son propre\n       <span class=\"mat-mdc-menu-item-text\"> interne — le gap doit donc\n       viser CE span (contenu Material, hors encapsulation, d'où ::ng-deep),\n       pas le <button> lui-même : il n'a aucun effet sur ses petits-enfants. */\n    .ngx-phone-menu-list ::ng-deep .mat-mdc-menu-item-text {\n      display: flex;\n      align-items: center;\n      gap: 0.625rem;\n      width: 100%;\n    }\n    .ngx-phone-menu-name {\n      flex: 1;\n      min-width: 0;\n      overflow: hidden;\n      text-overflow: ellipsis;\n      white-space: nowrap;\n      font-size: 0.875rem;\n    }\n    .ngx-phone-menu-dial {\n      font-size: 0.8125rem;\n      color: rgba(0, 0, 0, 0.5);\n    }\n    .ngx-phone-menu-empty {\n      padding: 0.75rem;\n      text-align: center;\n      font-size: 0.8125rem;\n      color: rgba(0, 0, 0, 0.45);\n    }\n\n    .ngx-options-loading {\n      display: flex;\n      align-items: center;\n      gap: 0.5rem;\n      font-size: 0.8125rem;\n      color: rgba(0, 0, 0, 0.45);\n    }\n    .ngx-options-loading-inline {\n      display: flex;\n      align-items: center;\n      gap: 0.5rem;\n      font-size: 0.8125rem;\n      color: rgba(0, 0, 0, 0.45);\n    }\n  `],\n})\nexport class DynamicFieldComponent implements OnInit {\n  @Input({ required: true }) field!: DynamicFormField;\n  @Input({ required: true }) form!: FormGroup;\n  /** Apparence héritée du formulaire parent — surchargeable par field.appearance */\n  @Input() formAppearance: 'outline' | 'fill' | 'simple' = 'outline';\n  /** Comportement du label hérité du parent — surchargeable par field.floatLabel */\n  @Input() formFloatLabel: 'auto' | 'always' = 'auto';\n\n  get resolvedAppearance(): 'outline' | 'fill' | 'simple' {\n    return this.field.appearance ?? this.formAppearance;\n  }\n  /** Apparence passée à mat-form-field : 'simple' est géré côté template, ne jamais le passer à Material */\n  get matAppearance(): 'outline' | 'fill' {\n    const a = this.resolvedAppearance;\n    return a === 'simple' ? 'outline' : a;\n  }\n  get isSimple(): boolean {\n    return this.resolvedAppearance === 'simple';\n  }\n  get resolvedFloatLabel(): 'auto' | 'always' {\n    return this.field.floatLabel ?? this.formFloatLabel;\n  }\n\n  private builder     = inject(DynamicFormBuilderService);\n  private evaluator   = inject(ConditionEvaluatorService);\n  private http        = inject(HttpClient, { optional: true });\n  private dataApiUrl  = inject(NGX_DATA_API_URL, { optional: true }) ?? '';\n  private globalDateLocale = inject(NGX_DATE_LOCALE, { optional: true }) ?? 'fr-FR';\n  private dateAdapter  = inject(DateAdapter);\n  private cdr          = inject(ChangeDetectorRef);\n\n  resolvedOptions: SelectOption[] = [];\n  loadingOptions = false;\n  lookupLoading = false;\n\n  // ── Select à recherche distante (field.remoteSearch) ────────────────────────\n  /** Texte affiché/tapé dans le champ — distinct de `formControl`, qui reçoit\n   *  la valeur sélectionnée (opt.value) plutôt que le texte de recherche. */\n  searchDisplayControl = new FormControl('');\n  private remoteSearch$ = new Subject<string>();\n\n  get remoteSearchHasEnoughChars(): boolean {\n    const text = this.searchDisplayControl.value;\n    const min = this.field.remoteSearch?.minChars ?? 3;\n    return typeof text === 'string' && text.length >= min;\n  }\n\n  displayRemoteOption = (value: SelectOption | string | null): string => {\n    if (value == null) return '';\n    return typeof value === 'string' ? value : value.label;\n  };\n\n  onRemoteOptionSelected(event: MatAutocompleteSelectedEvent): void {\n    const opt = event.option.value as SelectOption;\n    this.formControl.setValue(opt.value, { emitEvent: true });\n  }\n\n  /** Emitted on every value change of this field */\n  @Output() fieldChange = new EventEmitter<{ key: string; value: any }>();\n\n  // ── Code ISO pays (type: 'iso-country') ──────────────────────────────────────\n  // Sélection dans une liste déroulante recherchable plutôt que saisie libre —\n  // garantit un code toujours valide (pas de faute de frappe type 'ZZ'), même\n  // pattern que 'country-dial-code' et même référentiel PHONE_COUNTRIES (dont\n  // le champ .code EST le code ISO 3166-1 alpha-2). Le pattern ^[A-Za-z]{2}$\n  // reste ajouté par défaut dans DynamicFormBuilderService.buildFormGroup() —\n  // filet de sécurité si une valeur est posée par programmation hors du picker.\n  isoCountrySearchCtrl = new FormControl('');\n\n  get filteredIsoCountries(): PhoneCountry[] {\n    const term = (this.isoCountrySearchCtrl.value ?? '').toString().trim().toLowerCase();\n    if (!term) return PHONE_COUNTRIES;\n    return PHONE_COUNTRIES.filter(c =>\n      c.name.toLowerCase().includes(term) || c.code.toLowerCase().includes(term)\n    );\n  }\n\n  displayIsoCountry = (value: PhoneCountry | string | null): string => {\n    if (value == null || value === '') return '';\n    if (typeof value === 'string') {\n      const match = PHONE_COUNTRIES.find(c => c.code === value.toUpperCase());\n      return match ? `${match.flag} ${match.name} (${match.code})` : value;\n    }\n    return `${value.flag} ${value.name} (${value.code})`;\n  };\n\n  onIsoCountrySelected(event: MatAutocompleteSelectedEvent): void {\n    const country = event.option.value as PhoneCountry;\n    this.formControl.setValue(country.code, { emitEvent: true });\n  }\n\n  // ── Indicatif téléphonique pays (type: 'country-dial-code') ──────────────────\n  // Distinct de 'phone' (qui saisit un NUMÉRO complet E.164) : ici on choisit\n  // uniquement l'indicatif d'un pays comme attribut autonome (ex: Pays.indicatifTel\n  // = '+221'). Réutilise le même référentiel PHONE_COUNTRIES (avec drapeau déjà\n  // inclus) que le sélecteur de pays du champ 'phone'.\n  dialCodeSearchCtrl = new FormControl('');\n\n  get filteredDialCodeCountries(): PhoneCountry[] {\n    const term = (this.dialCodeSearchCtrl.value ?? '').toString().trim().toLowerCase();\n    if (!term) return PHONE_COUNTRIES;\n    return PHONE_COUNTRIES.filter(c =>\n      c.name.toLowerCase().includes(term) ||\n      c.dialCode.includes(term) ||\n      c.code.toLowerCase().includes(term)\n    );\n  }\n\n  displayDialCode = (value: PhoneCountry | string | null): string => {\n    if (value == null || value === '') return '';\n    if (typeof value === 'string') {\n      const match = PHONE_COUNTRIES.find(c => c.dialCode === value);\n      return match ? `${match.flag} ${match.name} (${match.dialCode})` : value;\n    }\n    return `${value.flag} ${value.name} (${value.dialCode})`;\n  };\n\n  onDialCodeSelected(event: MatAutocompleteSelectedEvent): void {\n    const country = event.option.value as PhoneCountry;\n    this.formControl.setValue(country.dialCode, { emitEvent: true });\n  }\n\n  // ── Fichier (type: 'file') ───────────────────────────────────────────────────\n  // formControl.value contient directement le/les File choisi(s) (File si\n  // field.multiple est faux, File[] sinon) — c'est au consommateur (onSubmit)\n  // de construire le FormData ; le plugin ne fait aucun appel HTTP lui-même.\n  fileDragging = false;\n\n  get selectedFiles(): File[] {\n    const v = this.formControl.value;\n    if (!v) return [];\n    return Array.isArray(v) ? v : [v];\n  }\n\n  onFileInputChange(event: Event): void {\n    const input = event.target as HTMLInputElement;\n    if (input.files) this.setFiles(input.files);\n  }\n\n  onFileDragOver(event: DragEvent): void {\n    event.preventDefault();\n    this.fileDragging = true;\n  }\n\n  onFileDragLeave(event: DragEvent): void {\n    event.preventDefault();\n    this.fileDragging = false;\n  }\n\n  onFileDrop(event: DragEvent): void {\n    event.preventDefault();\n    this.fileDragging = false;\n    if (event.dataTransfer?.files) this.setFiles(event.dataTransfer.files);\n  }\n\n  removeFile(index: number, input: HTMLInputElement): void {\n    const remaining = this.selectedFiles.filter((_, i) => i !== index);\n    this.formControl.setValue(this.field.multiple ? remaining : null, { emitEvent: true });\n    input.value = ''; // permet de resélectionner le même fichier après suppression\n  }\n\n  formatFileSize(bytes: number): string {\n    if (bytes < 1024) return `${bytes} o`;\n    if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)} Ko`;\n    return `${(bytes / (1024 * 1024)).toFixed(1)} Mo`;\n  }\n\n  private setFiles(fileList: FileList): void {\n    const files = Array.from(fileList);\n    if (!files.length) return;\n    this.formControl.setValue(this.field.multiple ? [...this.selectedFiles, ...files] : files[0], { emitEvent: true });\n  }\n\n  // ── Géolocalisation ────────────────────────────────────────────────────────\n  locating = false;\n  locationError = '';\n\n  // ── Téléphone ──────────────────────────────────────────────────────────────\n  readonly phoneCountries = PHONE_COUNTRIES;\n  selectedPhoneCountry: PhoneCountry = PHONE_COUNTRIES[0];\n  phoneSearch = '';\n  /** Chiffres locaux courants (hors indicatif), tenus à jour par `applyPhoneMask` — évite de les re-dériver de la valeur E.164 complète du formControl (qui contient déjà l'ancien indicatif). */\n  private phoneLocalDigits = '';\n  /** Texte affiché dans la saisie (chiffres locaux masqués). Suit aussi la valeur posée de\n   *  l'extérieur (initialValues en mode édition, patchValue) — sans lui, la saisie restait vide. */\n  phoneDisplay = '';\n\n  get filteredPhoneCountries(): PhoneCountry[] {\n    const term = this.phoneSearch.trim().toLowerCase();\n    if (!term) return PHONE_COUNTRIES;\n    return PHONE_COUNTRIES.filter(c =>\n      c.name.toLowerCase().includes(term) || c.dialCode.includes(term)\n    );\n  }\n\n  selectPhoneCountry(country: PhoneCountry): void {\n    this.selectedPhoneCountry = country;\n    this.formControl.setValue(`${country.dialCode}${this.phoneLocalDigits}`, { emitEvent: true });\n    this.phoneSearch = '';\n  }\n\n  getLocation(): void {\n    if (!navigator.geolocation) {\n      this.locationError = 'Géolocalisation non supportée par ce navigateur';\n      return;\n    }\n    this.locating = true;\n    this.locationError = '';\n    navigator.geolocation.getCurrentPosition(\n      (pos) => {\n        const lat = pos.coords.latitude.toFixed(6);\n        const lng = pos.coords.longitude.toFixed(6);\n        this.formControl.setValue(`${lat},${lng}`);\n        this.locating = false;\n      },\n      (err) => {\n        this.locationError = this._geoError(err.code);\n        this.locating = false;\n      },\n      { timeout: 10000, maximumAge: 60000 },\n    );\n  }\n\n  private _geoError(code: number): string {\n    if (code === 1) return 'Accès à la localisation refusé';\n    if (code === 2) return 'Position indisponible';\n    if (code === 3) return 'Délai dépassé';\n    return 'Erreur de géolocalisation';\n  }\n\n  onPhoneSelectChange(event: Event): void {\n    const code = (event.target as HTMLSelectElement).value;\n    this.selectedPhoneCountry = PHONE_COUNTRIES.find(c => c.code === code) ?? PHONE_COUNTRIES[0];\n    this.formControl.setValue(`${this.selectedPhoneCountry.dialCode}${this.phoneLocalDigits}`);\n  }\n\n  applyPhoneMask(event: Event): void {\n    const el = event.target as HTMLInputElement;\n    const digits = el.value.replace(/\\D/g, '');\n    this.phoneLocalDigits = digits;\n    this.phoneDisplay = this.maskPhone(digits);\n    el.value = this.phoneDisplay;\n    this.formControl.setValue(`${this.selectedPhoneCountry.dialCode}${digits}`, { emitEvent: true });\n  }\n\n  private maskPhone(digits: string): string {\n    let result = '';\n    let di = 0;\n    for (const ch of this.selectedPhoneCountry.mask) {\n      if (di >= digits.length) break;\n      result += ch === '#' ? digits[di++] : ch;\n    }\n    return result;\n  }\n\n  /**\n   * Répercute une valeur du formControl sur le pays et la saisie affichée : '+222 22 12 34 56'\n   * ou '0022222123456' -> Mauritanie + '22 12 34 56' ; un numéro sans indicatif ('774127793')\n   * garde le pays courant. Ignore les valeurs produites par la saisie elle-même.\n   */\n  private syncPhoneFromValue(value: unknown): void {\n    const brut = String(value ?? '').replace(/[\\s.\\-()]/g, '');\n    if (brut === `${this.selectedPhoneCountry.dialCode}${this.phoneLocalDigits}`) return;\n    const international = brut.startsWith('00') ? `+${brut.slice(2)}` : brut;\n    let local = brut;\n    if (international.startsWith('+')) {\n      const candidats = PHONE_COUNTRIES.filter(c => international.startsWith(c.dialCode));\n      if (candidats.length) {\n        // Indicatif le plus long (+1 vs +1242…) ; à égalité, le pays déjà choisi l'emporte.\n        const longueur = Math.max(...candidats.map(c => c.dialCode.length));\n        const meilleurs = candidats.filter(c => c.dialCode.length === longueur);\n        this.selectedPhoneCountry =\n          meilleurs.find(c => c.code === this.selectedPhoneCountry.code) ?? meilleurs[0];\n        local = international.slice(longueur);\n      }\n    }\n    this.phoneLocalDigits = local.replace(/\\D/g, '');\n    this.phoneDisplay = this.maskPhone(this.phoneLocalDigits);\n    this.cdr.markForCheck();\n  }\n\n  // ── Style appliqué sur l'hôte ──────────────────────────────────────────────\n\n  @HostBinding('style')\n  get hostStyle(): Record<string, string> {\n    const s: Record<string, string> = { ...(this.field.styles ?? {}) };\n    if (this.field.fontSize)         s['font-size']            = this.field.fontSize;\n    if (this.field.fontWeight)       s['font-weight']          = this.field.fontWeight;\n    if (this.field.fontStyle)        s['font-style']           = this.field.fontStyle;\n    if (this.field.color)            s['--ngx-field-color']    = this.field.color;\n    if (this.field.backgroundColor)  s['--ngx-field-bg']       = this.field.backgroundColor;\n    if (this.field.textAlign)        s['--ngx-field-align']    = this.field.textAlign;\n    if (this.field.borderColor)      s['--ngx-border-color']   = this.field.borderColor;\n    if (this.field.labelColor)       s['--ngx-label-color']    = this.field.labelColor;\n    return s;\n  }\n\n  @HostBinding('class')\n  get hostClass(): string {\n    return this.field.cssClass ?? '';\n  }\n\n  ngOnInit(): void {\n    // Convertit une valeur string \"YYYY-MM-DD\" en Date pour le mat-datepicker\n    if (this.field.type === 'date' && !this.isSimple) {\n      this.dateAdapter.setLocale(this.field.dateLocale ?? this.globalDateLocale);\n\n      const val = this.formControl.value;\n      if (typeof val === 'string' && val) {\n        const d = new Date(val + 'T12:00:00');\n        if (!isNaN(d.getTime())) {\n          this.formControl.setValue(d, { emitEvent: false });\n        }\n      }\n    }\n\n    // Initialise le range à la valeur min si null\n    if (this.field.type === 'range' && this.formControl.value == null) {\n      this.formControl.setValue(this.field.min ?? 0, { emitEvent: false });\n    }\n\n    // Initialise le pays par défaut pour le champ phone\n    if (this.field.type === 'phone') {\n      this.selectedPhoneCountry =\n        PHONE_COUNTRIES.find(c => c.code === (this.field.defaultCountry ?? 'FR'))\n        ?? PHONE_COUNTRIES[0];\n      // Mode édition : la valeur déjà posée (ou patchée plus tard) s'affiche dans la saisie.\n      this.syncPhoneFromValue(this.formControl.value);\n      this.formControl.valueChanges.subscribe(value => this.syncPhoneFromValue(value));\n    }\n\n    // Pré-remplit le texte affiché du sélecteur d'indicatif en mode édition\n    // (valeur déjà présente sur le formControl, ex: '+221').\n    if (this.field.type === 'country-dial-code') {\n      const initial = this.formControl.value;\n      if (initial) {\n        this.dialCodeSearchCtrl.setValue(this.displayDialCode(initial), { emitEvent: false });\n      }\n    }\n\n    // Idem pour le sélecteur de code ISO pays en mode édition (ex: 'SN' déjà posé).\n    if (this.field.type === 'iso-country') {\n      const initial = this.formControl.value;\n      if (initial) {\n        this.isoCountrySearchCtrl.setValue(this.displayIsoCountry(initial), { emitEvent: false });\n      }\n    }\n\n    // requiredWhen: dynamic Validators.required based on sibling field conditions\n    if (this.field.validation?.requiredWhen) {\n      this.setupRequiredWhen();\n    }\n\n    // lookup: subscribe to value changes for triggerOn:'change'\n    if (this.field.lookup?.triggerOn === 'change') {\n      this.formControl.valueChanges.subscribe(() => this.onLookupBlur());\n    }\n\n    // emit fieldChange on every value change\n    this.formControl.valueChanges.subscribe(value => {\n      this.fieldChange.emit({ key: this.field.key, value });\n    });\n\n    // copyFrom: mirror source field value into this field whenever source changes\n    if (this.field.copyFrom) {\n      this.form.get(this.field.copyFrom)?.valueChanges.subscribe(v =>\n        this.formControl.setValue(v, { emitEvent: false })\n      );\n    }\n\n    if (!this.hasOptions) return;\n\n    if (this.field.remoteSearch) {\n      this.setupRemoteSearch();\n      return;\n    }\n\n    if (this.field.dependsOn) {\n      const parentControl = this.form.get(this.field.dependsOn);\n      if (!parentControl) {\n        console.warn(\n          `[ngx-dynamic-form] Le champ \"${this.field.key}\" a dependsOn=\"${this.field.dependsOn}\"` +\n          ` mais ce champ n'existe pas dans ce formulaire.`\n        );\n        this.resolveOptions();\n        return;\n      }\n\n      if (this.field.url && this.field.dependsOnMode === 'client') {\n        // L'API ne filtre pas côté serveur : on charge la liste complète une\n        // seule fois (comme le ferait un `ngOnInit` classique) et on la\n        // refiltre localement à chaque changement du champ dont on dépend —\n        // reproduit le pattern « fetch once + filter(p => p.x === value) »\n        // qu'on trouve dans les formulaires écrits à la main.\n        this.loadRemoteOptions(true);\n        parentControl.valueChanges.subscribe(() => this.applyClientFilter());\n        return;\n      }\n\n      parentControl.valueChanges.subscribe(() => this.resolveOptions());\n    }\n\n    this.resolveOptions();\n  }\n\n  private resolveOptions(): void {\n    if (this.field.dependsOn) {\n      const parentValue = this.form.get(this.field.dependsOn)?.value;\n      const hasParentValue = parentValue !== null && parentValue !== undefined && parentValue !== '';\n      if (!hasParentValue) {\n        this.resolvedOptions = [];\n        return;\n      }\n    }\n\n    if (this.field.url) {\n      this.loadRemoteOptions();\n    } else {\n      this.resolveStaticOptions();\n    }\n  }\n\n  private resolveStaticOptions(): void {\n    const opts = this.field.options;\n    if (!opts || !Array.isArray(opts)) return;\n\n    const mapped = opts.map(o =>\n      typeof o === 'string' ? { label: o, value: o } : o\n    );\n\n    if (!this.field.dependsOn) {\n      this.resolvedOptions = mapped;\n      return;\n    }\n\n    const parentValue = this.form.get(this.field.dependsOn)?.value;\n    // Comparaison en texte : l'éditeur enregistre dependsOnValue en chaîne, le champ parent\n    // peut valoir un nombre ou un booléen.\n    this.resolvedOptions = mapped.filter(\n      o => o.dependsOnValue != null && parentValue != null && String(o.dependsOnValue) === String(parentValue)\n    );\n    // Valeur choisie absente de la nouvelle liste (ex: « 12 mois » après passage en « jours ») :\n    // effacée, pour ne pas soumettre une option invisible.\n    const current = this.formControl?.value;\n    const permises = new Set(this.resolvedOptions.map(o => String(o.value)));\n    if (Array.isArray(current)) {\n      // multiselect : on ne garde que les valeurs encore proposées.\n      const gardees = current.filter(v => permises.has(String(v)));\n      if (gardees.length !== current.length) this.formControl.setValue(gardees);\n    } else if (current != null && current !== '' && !permises.has(String(current))) {\n      this.formControl.setValue(null);\n    }\n  }\n\n  /** Liste brute (non filtrée) mise en cache pour `dependsOnMode: 'client'`. */\n  private rawRemoteItems: any[] | null = null;\n\n  /** Refiltre localement `rawRemoteItems` (mode `dependsOnMode: 'client'`) selon la valeur courante du champ `dependsOn`. */\n  private applyClientFilter(): void {\n    if (!this.rawRemoteItems) return;\n\n    const parentValue = this.form.get(this.field.dependsOn!)?.value;\n    const hasParentValue = parentValue !== null && parentValue !== undefined && parentValue !== '';\n    if (!hasParentValue) {\n      this.resolvedOptions = [];\n      return;\n    }\n\n    const nameKey  = this.field.displayName  ?? 'label';\n    const valueKey = this.field.displayValue ?? 'value';\n    const itemKey  = this.field.dependsOnItemKey ?? this.field.dependsOn!;\n    const offset   = this.field.dependsOnOffset;\n\n    const matches = offset !== undefined\n      ? (item: any) => Number(item[itemKey]) === Number(parentValue) + offset\n      : (item: any) => item[itemKey] === parentValue;\n\n    this.resolvedOptions = this.rawRemoteItems\n      .filter(matches)\n      .map(item => ({ label: optionLabel(item, nameKey), value: item[valueKey] ?? item }));\n  }\n\n  /** Remplace les `{{cléDeChamp}}` d'une URL par la valeur courante du champ correspondant dans ce formulaire. */\n  private interpolateUrl(url: string): string {\n    return url.replace(/\\{\\{(\\w+)\\}\\}/g, (_match, key) => {\n      const value = this.form.get(key)?.value;\n      return value != null ? encodeURIComponent(value) : '';\n    });\n  }\n\n  /** Câble la recherche distante debouncée (field.remoteSearch) : ne charge rien\n   *  tant que l'utilisateur ne tape pas, contrairement à `resolveOptions()`. */\n  private setupRemoteSearch(): void {\n    if (this.formControl.disabled) {\n      this.searchDisplayControl.disable({ emitEvent: false });\n    }\n\n    // Pré-remplit le texte affiché en mode édition (valeur déjà présente) — faute\n    // de mieux on affiche l'id brut, on n'a pas de label sans un appel de plus.\n    // ponytail: pas de lookup-par-id pour résoudre le label initial, ajouter si\n    // le besoin d'édition avec label pré-rempli se confirme.\n    const initial = this.formControl.value;\n    if (initial != null && initial !== '') {\n      this.searchDisplayControl.setValue(String(initial), { emitEvent: false });\n    }\n\n    const cfg = this.field.remoteSearch!;\n    this.remoteSearch$.pipe(\n      debounceTime(cfg.debounceMs ?? 300),\n      distinctUntilChanged(),\n      filter(q => q.length >= (cfg.minChars ?? 3)),\n      tap(() => { this.loadingOptions = true; this.cdr.markForCheck(); }),\n      switchMap(q => this.fetchRemoteSearch(q)),\n    ).subscribe(options => {\n      this.resolvedOptions = options;\n      this.loadingOptions = false;\n      // La réponse HTTP arrive dans un callback async : sans ça, le panneau\n      // mat-autocomplete (déjà ouvert, focus sur l'input) n'était mis à jour\n      // qu'au prochain cycle de détection de changements déclenché par autre\n      // chose (ex: un clic ailleurs) — d'où le \"je dois cliquer pour voir le résultat\".\n      this.cdr.markForCheck();\n    });\n\n    this.searchDisplayControl.valueChanges.subscribe(value => {\n      // Une sélection dans le panneau pousse l'objet {label,value} entier via\n      // displayWith — seule une saisie texte doit relancer une recherche.\n      if (typeof value !== 'string') return;\n      if (value.length < (cfg.minChars ?? 3)) {\n        this.resolvedOptions = [];\n        this.cdr.markForCheck();\n      }\n      this.remoteSearch$.next(value);\n    });\n  }\n\n  private fetchRemoteSearch(query: string) {\n    if (!this.http) {\n      console.warn(\n        `[ngx-dynamic-form] Le champ \"${this.field.key}\" a remoteSearch mais HttpClient n'est pas disponible.` +\n        ` Ajoutez provideHttpClient() dans votre app.config.ts.`\n      );\n      return of([] as SelectOption[]);\n    }\n\n    const cfg = this.field.remoteSearch!;\n    const base = this.dataApiUrl.replace(/\\/$/, '');\n    const endpoint = this.interpolateUrl(this.field.url!);\n    const isComplete = endpoint.startsWith('http') || endpoint.startsWith('/');\n    const url = isComplete ? endpoint : `${base}/${endpoint}`;\n\n    let params = new HttpParams().set(cfg.paramName ?? 'q', query);\n    for (const [key, value] of Object.entries(cfg.params ?? {})) {\n      params = params.set(key, String(value));\n    }\n\n    const nameKey  = this.field.displayName  ?? 'label';\n    const valueKey = this.field.displayValue ?? 'value';\n    const dataKey  = this.field.responseDataKey;\n\n    return this.http.get<any>(url, { params }).pipe(\n      map(response => this.filterItems(this.extractOptionsArray(response, dataKey, url)).map(item => ({\n        label: optionLabel(item, nameKey),\n        value: item[valueKey] ?? item,\n      }))),\n      catchError(err => {\n        console.error(`[ngx-dynamic-form] Échec de la recherche pour \"${this.field.key}\" (${url}):`, err);\n        return of([] as SelectOption[]);\n      }),\n    );\n  }\n\n  /** Applique field.optionsFilter (ex: ne garder que status === 'ACTIF') aux items bruts\n   *  reçus de l'API, avant leur mapping en {label, value}. No-op si non configuré. */\n  private filterItems(items: any[]): any[] {\n    const filter = this.field.optionsFilter;\n    if (!filter) return items;\n    return items.filter(item => this.evaluator.matchesItem(filter, this.field.optionsFilterLogic, item));\n  }\n\n  /** @param cacheRaw Conserve la réponse brute dans `rawRemoteItems` pour un filtrage local ultérieur, au lieu de la mapper directement dans `resolvedOptions`. */\n  private loadRemoteOptions(cacheRaw = false): void {\n    if (!this.http) {\n      console.warn(\n        `[ngx-dynamic-form] Le champ \"${this.field.key}\" a une url mais HttpClient n'est pas disponible.` +\n        ` Ajoutez provideHttpClient() dans votre app.config.ts.`\n      );\n      return;\n    }\n\n    const base    = this.dataApiUrl.replace(/\\/$/, '');\n    const endpoint = this.interpolateUrl(this.field.url!);\n    // 'http...' (absolute) or a leading '/' (root-relative, resolved by the\n    // browser against the app's own origin — lets one field reach a\n    // different backend than dataApiUrl through whatever same-origin proxy\n    // the app already has configured, instead of hardcoding a full host).\n    const isComplete = endpoint.startsWith('http') || endpoint.startsWith('/');\n    const url = isComplete ? endpoint : `${base}/${endpoint}`;\n\n    const nameKey  = this.field.displayName  ?? 'label';\n    const valueKey = this.field.displayValue ?? 'value';\n\n    this.loadingOptions = true;\n    const dataKey = this.field.responseDataKey;\n\n    this.http.get<any>(url).subscribe({\n      next: (response) => {\n        const data = this.filterItems(this.extractOptionsArray(response, dataKey, url));\n        if (cacheRaw) {\n          this.rawRemoteItems = data;\n          this.applyClientFilter();\n        } else {\n          this.resolvedOptions = data.map(item => ({\n            label: optionLabel(item, nameKey),\n            value: item[valueKey] ?? item,\n          }));\n        }\n        this.loadingOptions = false;\n        // Réponse HTTP arrivée dans un callback async : sans ça, mat-select n'affiche le\n        // libellé de la valeur déjà pré-remplie (mode édition) qu'au prochain cycle de\n        // détection de changements déclenché par autre chose (ex: cliquer sur le select).\n        this.cdr.markForCheck();\n      },\n      error: (err) => {\n        console.error(`[ngx-dynamic-form] Échec du chargement des options pour \"${this.field.key}\" (${url}):`, err);\n        this.resolvedOptions = [];\n        this.loadingOptions = false;\n        this.cdr.markForCheck();\n      },\n    });\n  }\n\n  /**\n   * Une réponse d'API select-options peut déjà être un tableau brut, ou\n   * être enveloppée (ex: { data: [...], total: N }). `responseDataKey`\n   * force explicitement la clé à utiliser ; sinon 'data' est essayé en\n   * repli automatique, la convention la plus courante.\n   */\n  private extractOptionsArray(response: unknown, dataKey: string | undefined, url: string): any[] {\n    if (Array.isArray(response)) {\n      return response;\n    }\n    const key = dataKey ?? 'data';\n    const nested = (response as Record<string, unknown> | null | undefined)?.[key];\n    if (Array.isArray(nested)) {\n      return nested;\n    }\n    console.warn(\n      `[ngx-dynamic-form] Le champ \"${this.field.key}\" attendait un tableau (ou une clé \"${key}\" contenant un tableau)` +\n      ` dans la réponse de ${url}, mais a reçu autre chose. Options vides.`\n    );\n    return [];\n  }\n\n  get formControl(): FormControl {\n    return this.form.get(this.field.key) as FormControl;\n  }\n\n  /**\n   * Masque de saisie : # = chiffre, tout autre caractère = séparateur littéral.\n   * Ex : '## ## ## ## ##' → téléphone, '##/##/####' → date.\n   */\n  applyMask(event: Event): void {\n    if (!this.field.mask) return;\n    const el     = event.target as HTMLInputElement;\n    const digits = el.value.replace(/\\D/g, '');\n    let result   = '';\n    let dIdx     = 0;\n    for (let i = 0; i < this.field.mask.length && dIdx < digits.length; i++) {\n      result += this.field.mask[i] === '#' ? digits[dIdx++] : this.field.mask[i];\n    }\n    el.value = result;\n    this.formControl.setValue(result, { emitEvent: true });\n  }\n\n  get isInputField(): boolean {\n    return this.field.type !== 'divider' && this.field.type !== 'heading';\n  }\n\n  get hasOptions(): boolean {\n    return ['select', 'multiselect', 'radio'].includes(this.field.type);\n  }\n\n  get hasError(): boolean {\n    const ctrl = this.formControl;\n    return !!(ctrl && ctrl.invalid && ctrl.touched);\n  }\n\n  get errorMessage(): string | null {\n    const ctrl = this.formControl;\n    if (!ctrl) return null;\n    return this.builder.getErrorMessage(ctrl, this.field.validation);\n  }\n\n  /** Bornes du mat-datepicker [min]/[max] : la plus stricte entre field.minDate/maxDate\n   *  ('today' ou ISO 'YYYY-MM-DD') et la valeur courante du champ validation.minField/maxField\n   *  — une période début/fin grise ainsi les dates invalides dans le calendrier. */\n  get minDate(): Date | undefined {\n    return this.stricterDate('min', this.resolveFieldDate(this.field.minDate), this.siblingDate(this.field.validation?.minField));\n  }\n\n  get maxDate(): Date | undefined {\n    return this.stricterDate('max', this.resolveFieldDate(this.field.maxDate), this.siblingDate(this.field.validation?.maxField));\n  }\n\n  /** Same bound, as 'YYYY-MM-DD' for the native <input type=\"date\"> min/max attributes (simple appearance). */\n  get minDateAttr(): string | undefined {\n    const d = this.minDate;\n    return d && toIsoDate(d);\n  }\n\n  get maxDateAttr(): string | undefined {\n    const d = this.maxDate;\n    return d && toIsoDate(d);\n  }\n\n  private resolveFieldDate(value: string | undefined): Date | undefined {\n    if (!value) return undefined;\n    if (value === 'today') return new Date();\n    const d = new Date(value + 'T12:00:00');\n    return isNaN(d.getTime()) ? undefined : d;\n  }\n\n  /** type 'date', apparence simple : bloque la saisie (Tab reste libre), Entrée/Espace ouvrent le sélecteur. */\n  onNativeDateKeydown(e: KeyboardEvent): void {\n    if (e.key === 'Tab') return;\n    e.preventDefault();\n    if (e.key === 'Enter' || e.key === ' ') this.openNativeDatePicker(e);\n  }\n\n  openNativeDatePicker(e: Event): void {\n    try {\n      (e.target as HTMLInputElement).showPicker();\n    } catch {\n      // champ readonly/désactivé, ou navigateur sans showPicker() : rien à ouvrir\n    }\n  }\n\n  /** Valeur courante d'un autre champ date du formulaire (Date du datepicker ou chaîne ISO). */\n  private siblingDate(key: string | undefined): Date | undefined {\n    const v = key ? this.form.get(key)?.value : null;\n    if (v instanceof Date) return isNaN(v.getTime()) ? undefined : v;\n    return typeof v === 'string' ? this.resolveFieldDate(v.slice(0, 10)) : undefined;\n  }\n\n  private stricterDate(mode: 'min' | 'max', a?: Date, b?: Date): Date | undefined {\n    if (!a || !b) return a ?? b;\n    return (mode === 'max') === (a < b) ? a : b;\n  }\n\n  private setupRequiredWhen(): void {\n    const rw = this.field.validation!.requiredWhen!;\n    const conditions = Array.isArray(rw) ? rw : [rw];\n    const fieldKeys = [...new Set(conditions.map((c: FieldCondition) => c.field))];\n    fieldKeys.forEach(key => {\n      this.form.get(key)?.valueChanges.subscribe(() => {\n        this.updateRequiredFromConditions(conditions);\n      });\n    });\n    this.updateRequiredFromConditions(conditions);\n  }\n\n  private updateRequiredFromConditions(conditions: FieldCondition[]): void {\n    const logic = this.field.conditionLogic ?? 'AND';\n    const isRequired = logic === 'OR'\n      ? conditions.some(c => this.evaluator.evaluate(c, this.form))\n      : conditions.every(c => this.evaluator.evaluate(c, this.form));\n\n    if (isRequired) {\n      this.formControl.addValidators(Validators.required);\n    } else {\n      this.formControl.removeValidators(Validators.required);\n    }\n    this.formControl.updateValueAndValidity({ emitEvent: false });\n  }\n\n  onLookupBlur(): void {\n    if (!this.field.lookup || !this.http) return;\n    const url = this.interpolateUrl(this.field.lookup.url);\n    this.lookupLoading = true;\n    const method = this.field.lookup.method ?? 'GET';\n    const req$ = method === 'POST'\n      ? this.http.post<any>(url, {})\n      : this.http.get<any>(url);\n\n    req$.subscribe({\n      next: (response) => {\n        this.lookupLoading = false;\n        Object.entries(this.field.lookup!.populate).forEach(([targetKey, apiPath]) => {\n          const value = getPath(response, apiPath as string);\n          this.form.get(targetKey)?.setValue(value ?? null, { emitEvent: true });\n        });\n      },\n      error: () => { this.lookupLoading = false; },\n    });\n  }\n}\n","import {\n  Component,\n  Input,\n  Output,\n  EventEmitter,\n  OnInit,\n  OnChanges,\n  SimpleChanges,\n  ChangeDetectorRef,\n} from '@angular/core';\nimport { JsonPipe } from '@angular/common';\nimport { ReactiveFormsModule, FormGroup } from '@angular/forms';\nimport { MatButton } from '@angular/material/button';\nimport {\n  DynamicFormConfig,\n  DynamicFormField,\n  DynamicFormSubmitEvent,\n} from '../../models/form-field.model';\nimport { DynamicFormBuilderService } from '../../services/dynamic-form-builder.service';\nimport { ConditionEvaluatorService } from '../../services/condition-evaluator.service';\nimport { DynamicFieldComponent } from '../dynamic-field/dynamic-field.component';\n\n@Component({\n  selector: 'ngx-dynamic-form',\n  standalone: true,\n  imports: [JsonPipe, ReactiveFormsModule, DynamicFieldComponent, MatButton],\n  template: `\n    <form\n      [formGroup]=\"form\"\n      (ngSubmit)=\"onSubmit()\"\n      [class]=\"'ngx-form ngx-form--' + (config.layout || 'vertical') + ' ' + (config.cssClass || '')\"\n      novalidate\n    >\n      <div class=\"ngx-form-grid\">\n        @for (field of config.fields; track field.key) {\n          @if (isVisible(field)) {\n            <div [style.grid-column]=\"'span ' + (field.col ?? 12)\">\n              <ngx-dynamic-field\n                [field]=\"field\"\n                [form]=\"form\"\n                [formAppearance]=\"config.appearance ?? 'outline'\"\n                [formFloatLabel]=\"config.floatLabel ?? 'auto'\"\n              />\n            </div>\n          }\n        }\n      </div>\n\n      @if (config.debug) {\n        <pre class=\"ngx-debug\">{{ form.value | json }}</pre>\n      }\n\n      <div class=\"ngx-form-actions\">\n        @if (config.showReset) {\n          <button type=\"button\" mat-stroked-button (click)=\"onReset()\">\n            {{ config.resetLabel || 'Réinitialiser' }}\n          </button>\n        }\n        @if (config.showSubmit !== false) {\n          <button\n            type=\"submit\"\n            mat-flat-button\n            color=\"primary\"\n            [disabled]=\"form.invalid && form.touched\"\n          >\n            {{ config.submitLabel || 'Envoyer' }}\n          </button>\n        }\n      </div>\n    </form>\n  `,\n  styles: [`\n    .ngx-form-grid {\n      display: grid;\n      grid-template-columns: repeat(12, 1fr);\n      gap: 1rem;\n      align-items: start;\n    }\n    .ngx-form-actions {\n      display: flex;\n      gap: 0.75rem;\n      justify-content: flex-end;\n      margin-top: 1rem;\n      flex-wrap: wrap;\n    }\n    @media (max-width: 600px) {\n      .ngx-form-grid { grid-template-columns: 1fr; }\n      .ngx-form-actions { flex-direction: column-reverse; }\n    }\n  `],\n})\nexport class DynamicFormComponent implements OnInit, OnChanges {\n  @Input({ required: true }) config!: DynamicFormConfig;\n\n  /** Pre-fill the form with values (e.g. in edit mode) */\n  @Input() initialValues?: Record<string, any>;\n\n  /** Emitted on valid form submit */\n  @Output() formSubmit = new EventEmitter<DynamicFormSubmitEvent>();\n\n  /** Emitted on every value change */\n  @Output() formChange = new EventEmitter<Record<string, any>>();\n\n  /** Emitted on every individual field value change */\n  @Output() fieldChange = new EventEmitter<{ key: string; value: any }>();\n\n  /** Emitted when form is reset */\n  @Output() formReset = new EventEmitter<void>();\n\n  form!: FormGroup;\n\n  constructor(\n    private builder: DynamicFormBuilderService,\n    private conditionEvaluator: ConditionEvaluatorService,\n    private cdr: ChangeDetectorRef,\n  ) {}\n\n  ngOnInit(): void {\n    this.buildForm();\n  }\n\n  ngOnChanges(changes: SimpleChanges): void {\n    // Rebuild form if config changes (e.g. dynamic schema loading)\n    if (changes['config'] && !changes['config'].firstChange) {\n      this.buildForm();\n    }\n    // Patch values if initialValues is updated\n    if (changes['initialValues'] && this.form) {\n      this.form.patchValue(this.normalizeValues(this.initialValues ?? {}));\n    }\n  }\n\n  private buildForm(): void {\n    this.form = this.builder.buildFormGroup(this.config.fields);\n\n    if (this.initialValues) {\n      this.form.patchValue(this.normalizeValues(this.initialValues));\n    }\n\n    // Global value change\n    this.form.valueChanges.subscribe((val) => {\n      this.formChange.emit(val);\n      this.cdr.markForCheck();\n    });\n\n    // Per-field fieldChange events\n    for (const field of this.config.fields) {\n      if (field.type === 'divider' || field.type === 'heading') continue;\n      this.form.get(field.key)?.valueChanges.subscribe(value => {\n        this.fieldChange.emit({ key: field.key, value });\n      });\n    }\n\n    // atLeastOneOf group validator from config (message from config.atLeastOneOfMessage)\n    if (this.config.atLeastOneOf?.length) {\n      const existing = this.form.validator;\n      const aoValidator = this.builder.atLeastOneOfValidator(\n        this.config.atLeastOneOf,\n        this.config.atLeastOneOfMessage\n      );\n      this.form.setValidators(existing ? [existing, aoValidator] : aoValidator);\n      this.form.updateValueAndValidity({ emitEvent: false });\n    }\n  }\n\n  isVisible(field: DynamicFormField): boolean {\n    return this.conditionEvaluator.isVisible(field, this.form);\n  }\n\n  onSubmit(): void {\n    this.form.markAllAsTouched();\n\n    if (this.form.invalid) {\n      this.cdr.markForCheck();\n      return;\n    }\n\n    this.formSubmit.emit({\n      value: this.form.value,\n      rawValue: this.form.getRawValue(), // includes disabled fields\n    });\n  }\n\n  onReset(): void {\n    this.form.reset();\n    this.formReset.emit();\n  }\n\n  /** Public API: access the FormGroup from the parent */\n  getForm(): FormGroup {\n    return this.form;\n  }\n\n  /** Public API: patch values from outside */\n  patchValues(values: Record<string, any>): void {\n    this.form.patchValue(this.normalizeValues(values));\n  }\n\n  /**\n   * For URL-based select/multiselect/radio fields, the API may return nested objects\n   * (e.g. ville: { id: 9, nom: \"Dakar\" }) instead of a primitive value (9).\n   * Extract the displayValue key so the select control matches the correct option.\n   */\n  private normalizeValues(values: Record<string, any>): Record<string, any> {\n    const normalized = { ...values };\n    for (const field of (this.config?.fields ?? [])) {\n      if (!field.url) continue;\n      const raw = normalized[field.key];\n      const key = field.displayValue ?? 'value';\n      if (raw != null && !Array.isArray(raw) && typeof raw === 'object') {\n        // select / radio: nested object → primitive (e.g. { id: 9, nom: \"Dakar\" } → 9)\n        normalized[field.key] = raw[key] ?? raw;\n      } else if (Array.isArray(raw) && raw.length > 0 && typeof raw[0] === 'object') {\n        // multiselect: array of nested objects → array of primitives\n        normalized[field.key] = raw.map(item => item[key] ?? item);\n      }\n    }\n    return normalized;\n  }\n}\n","import {\n  Component,\n  Input,\n  Output,\n  EventEmitter,\n  OnInit,\n  OnChanges,\n  SimpleChanges,\n  ChangeDetectorRef,\n  ViewChild,\n} from '@angular/core';\nimport { JsonPipe } from '@angular/common';\nimport { HttpClient } from '@angular/common/http';\nimport { ReactiveFormsModule, FormGroup } from '@angular/forms';\nimport { MatButton } from '@angular/material/button';\nimport { MatStepperModule, MatStepper } from '@angular/material/stepper';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatProgressSpinner } from '@angular/material/progress-spinner';\nimport {\n  StepperFormConfig,\n  DynamicFormSubmitEvent,\n  DynamicFormField,\n  SelectOption,\n  StepGuard,\n} from '../../models/form-field.model';\nimport { DynamicFormBuilderService } from '../../services/dynamic-form-builder.service';\nimport { ConditionEvaluatorService } from '../../services/condition-evaluator.service';\nimport { DynamicFieldComponent } from '../dynamic-field/dynamic-field.component';\n\ninterface SummaryItem { label: string; value: string; }\ninterface SummarySection { stepLabel: string; stepIndex: number; items: SummaryItem[]; }\n\n@Component({\n  selector: 'ngx-stepper-form',\n  standalone: true,\n  imports: [\n    JsonPipe,\n    ReactiveFormsModule,\n    DynamicFieldComponent,\n    MatButton,\n    MatStepperModule,\n    MatIcon,\n    MatProgressSpinner,\n  ],\n  template: `\n    <mat-stepper\n      [linear]=\"config.linear !== false\"\n      [orientation]=\"config.orientation || 'horizontal'\"\n      [class]=\"'ngx-stepper ' + (config.cssClass || '')\"\n      #stepper\n    >\n      <!-- ── Data steps ──────────────────────────────────── -->\n      @for (step of config.steps; track step.label; let i = $index; let last = $last) {\n        <mat-step\n          [stepControl]=\"stepForms[i]\"\n          errorMessage=\"Veuillez corriger les erreurs\"\n        >\n          <ng-template matStepLabel>\n            @if (step.icon) { <mat-icon>{{ step.icon }}</mat-icon> }\n            {{ step.label }}\n          </ng-template>\n\n          <div class=\"ngx-form-grid\">\n            @for (field of step.fields; track field.key) {\n              @if (isVisible(field, stepForms[i])) {\n                <div [style.grid-column]=\"'span ' + (field.col ?? 12)\">\n                  <ngx-dynamic-field\n                    [field]=\"field\"\n                    [form]=\"stepForms[i]\"\n                    [formAppearance]=\"config.appearance ?? 'outline'\"\n                    [formFloatLabel]=\"config.floatLabel ?? 'auto'\"\n                  />\n                </div>\n              }\n            }\n          </div>\n\n          @if (config.debug) {\n            <pre class=\"ngx-debug\">{{ stepForms[i].value | json }}</pre>\n          }\n\n          @if (guardLoading[i]) {\n            <div class=\"ngx-guard-loading\">\n              <mat-spinner diameter=\"20\"></mat-spinner>\n              <span>Vérification en cours…</span>\n            </div>\n          }\n          @if (guardError[i]) {\n            <div class=\"ngx-guard-error\">{{ guardError[i] }}</div>\n          }\n\n          <div class=\"ngx-stepper-actions\">\n            @if (i > 0) {\n              <button type=\"button\" mat-stroked-button matStepperPrevious>\n                Précédent\n              </button>\n            }\n            @if (config.showReset) {\n              <button type=\"button\" mat-stroked-button (click)=\"onReset()\">\n                {{ config.resetLabel || 'Réinitialiser' }}\n              </button>\n            }\n            @if (!last || config.showSummary) {\n              <button type=\"button\" mat-flat-button color=\"primary\"\n                (click)=\"nextStep(i)\"\n                [disabled]=\"guardLoading[i]\">\n                Suivant\n              </button>\n            }\n            @if (last && !config.showSummary) {\n              <button type=\"button\" mat-flat-button color=\"primary\" (click)=\"onSubmit()\">\n                {{ config.submitLabel || 'Envoyer' }}\n              </button>\n            }\n          </div>\n        </mat-step>\n      }\n\n      <!-- ── Summary step (optional) ──────────────────────── -->\n      @if (config.showSummary) {\n        <mat-step>\n          <ng-template matStepLabel>\n            {{ config.summaryLabel || 'Récapitulatif' }}\n          </ng-template>\n\n          <div class=\"ngx-summary\">\n            @for (section of getSummary(); track section.stepLabel) {\n              <div class=\"ngx-summary-section\">\n                <div class=\"ngx-summary-section-header\">\n                  <span class=\"ngx-summary-section-title\">{{ section.stepLabel }}</span>\n                  <button type=\"button\" mat-stroked-button (click)=\"goToStep(section.stepIndex)\">\n                    <mat-icon>edit</mat-icon> Modifier\n                  </button>\n                </div>\n                <div class=\"ngx-summary-items\">\n                  @for (item of section.items; track item.label) {\n                    <div class=\"ngx-summary-item\">\n                      <span class=\"ngx-summary-label\">{{ item.label }}</span>\n                      <span class=\"ngx-summary-value\">{{ item.value }}</span>\n                    </div>\n                  }\n                  @if (section.items.length === 0) {\n                    <div class=\"ngx-summary-empty\">Aucune donnée saisie</div>\n                  }\n                </div>\n              </div>\n            }\n          </div>\n\n          <div class=\"ngx-stepper-actions\">\n            <button type=\"button\" mat-stroked-button matStepperPrevious>\n              Précédent\n            </button>\n            @if (config.showReset) {\n              <button type=\"button\" mat-stroked-button (click)=\"onReset()\">\n                {{ config.resetLabel || 'Réinitialiser' }}\n              </button>\n            }\n            <button type=\"button\" mat-flat-button color=\"primary\" (click)=\"onSubmit()\">\n              {{ config.submitLabel || 'Envoyer' }}\n            </button>\n          </div>\n        </mat-step>\n      }\n    </mat-stepper>\n  `,\n  styles: [`\n    .ngx-form-grid {\n      display: grid;\n      grid-template-columns: repeat(12, 1fr);\n      gap: 1rem;\n      align-items: start;\n      padding: 1.5rem 0 1rem;\n    }\n    .ngx-stepper-actions {\n      display: flex;\n      gap: 0.75rem;\n      justify-content: flex-end;\n      padding-top: 0.5rem;\n      flex-wrap: wrap;\n    }\n\n    /* ── Summary ────────────────────────────────────────── */\n    .ngx-summary {\n      display: flex;\n      flex-direction: column;\n      gap: 0.75rem;\n      padding: 1.25rem 0 0.5rem;\n    }\n    .ngx-summary-section {\n      border: 1px solid #e2e8f0;\n      border-radius: 8px;\n      overflow: hidden;\n    }\n    .ngx-summary-section-header {\n      display: flex;\n      align-items: center;\n      justify-content: space-between;\n      padding: 0.5rem 0.75rem 0.5rem 1rem;\n      background: #f8fafc;\n      border-bottom: 1px solid #e2e8f0;\n    }\n    .ngx-summary-section-title {\n      font-size: 0.875rem;\n      font-weight: 600;\n      color: #1e293b;\n    }\n    .ngx-summary-items { padding: 0.25rem 0; }\n    .ngx-summary-item {\n      display: flex;\n      gap: 1rem;\n      padding: 0.45rem 1rem;\n      font-size: 0.83rem;\n      &:not(:last-child) { border-bottom: 1px solid #f1f5f9; }\n    }\n    .ngx-summary-label {\n      flex: 0 0 38%;\n      color: #64748b;\n      font-weight: 500;\n    }\n    .ngx-summary-value {\n      flex: 1;\n      color: #0f172a;\n      word-break: break-word;\n    }\n    .ngx-summary-empty {\n      padding: 0.6rem 1rem;\n      font-size: 0.8rem;\n      color: #94a3b8;\n      font-style: italic;\n    }\n\n    .ngx-debug {\n      background: #1e1e2e;\n      color: #cdd6f4;\n      border-radius: 4px;\n      padding: 1rem;\n      font-size: 0.8125rem;\n      overflow: auto;\n      margin-top: 1rem;\n    }\n    @media (max-width: 600px) {\n      .ngx-form-grid { grid-template-columns: 1fr; }\n      .ngx-stepper-actions { flex-direction: column-reverse; }\n      .ngx-summary-item { flex-direction: column; gap: 0.15rem; }\n      .ngx-summary-label { flex: none; }\n    }\n    .ngx-guard-loading {\n      display: flex;\n      align-items: center;\n      gap: 0.5rem;\n      padding: 0.5rem 0;\n      font-size: 0.875rem;\n      color: #64748b;\n    }\n    .ngx-guard-error {\n      padding: 0.5rem 0.75rem;\n      border-radius: 6px;\n      background: #fef2f2;\n      border: 1px solid #fecaca;\n      color: #dc2626;\n      font-size: 0.875rem;\n      margin-bottom: 0.5rem;\n    }\n  `],\n})\nexport class StepperFormComponent implements OnInit, OnChanges {\n  @Input({ required: true }) config!: StepperFormConfig;\n  @Input() initialValues?: Record<string, any>;\n\n  @Output() formSubmit = new EventEmitter<DynamicFormSubmitEvent>();\n  @Output() formChange = new EventEmitter<Record<string, any>>();\n  @Output() stepChange = new EventEmitter<number>();\n  /** Emitted on individual field value changes within any step */\n  @Output() fieldChange = new EventEmitter<{ key: string; value: any; step: number }>();\n\n  /** Per-step loading state for the beforeNext guard */\n  guardLoading: Record<number, boolean> = {};\n  /** Per-step error message from the beforeNext guard */\n  guardError: Record<number, string | null> = {};\n\n  @ViewChild('stepper') stepper!: MatStepper;\n\n  stepForms: FormGroup[] = [];\n\n  constructor(\n    private builder: DynamicFormBuilderService,\n    private conditionEvaluator: ConditionEvaluatorService,\n    private cdr: ChangeDetectorRef,\n    private http: HttpClient,\n  ) {}\n\n  ngOnInit(): void { this.buildForms(); }\n\n  ngOnChanges(changes: SimpleChanges): void {\n    if (changes['config'] && !changes['config'].firstChange) this.buildForms();\n    if (changes['initialValues'] && this.stepForms.length) {\n      this.config.steps.forEach((step, i) => {\n        this.stepForms[i].patchValue(this.normalizeValues(step.fields, this.initialValues ?? {}));\n      });\n    }\n  }\n\n  private buildForms(): void {\n    this.stepForms = this.config.steps.map((step, stepIdx) => {\n      const fg = this.builder.buildFormGroup(step.fields);\n      if (this.initialValues) fg.patchValue(this.normalizeValues(step.fields, this.initialValues));\n\n      fg.valueChanges.subscribe(() => {\n        this.formChange.emit(this.getAllValues());\n        this.cdr.markForCheck();\n      });\n\n      // Per-field fieldChange events\n      step.fields.forEach(f => {\n        if (f.type === 'divider' || f.type === 'heading') return;\n        fg.get(f.key)?.valueChanges.subscribe(value => {\n          this.fieldChange.emit({ key: f.key, value, step: stepIdx });\n        });\n      });\n\n      // atLeastOneOf group validator for this step\n      if (step.atLeastOneOf?.length) {\n        const aoValidator = this.builder.atLeastOneOfValidator(\n          step.atLeastOneOf,\n          step.atLeastOneOfMessage\n        );\n        const existing = fg.validator;\n        fg.setValidators(existing ? [existing, aoValidator] : aoValidator);\n        fg.updateValueAndValidity({ emitEvent: false });\n      }\n\n      return fg;\n    });\n  }\n\n  private normalizeValues(fields: DynamicFormField[], values: Record<string, any>): Record<string, any> {\n    const normalized = { ...values };\n    for (const field of fields) {\n      if (!field.url) continue;\n      const raw = normalized[field.key];\n      const key = field.displayValue ?? 'value';\n      if (raw != null && !Array.isArray(raw) && typeof raw === 'object') {\n        normalized[field.key] = raw[key] ?? raw;\n      } else if (Array.isArray(raw) && raw.length > 0 && typeof raw[0] === 'object') {\n        normalized[field.key] = raw.map(item => item[key] ?? item);\n      }\n    }\n    return normalized;\n  }\n\n  isVisible(field: DynamicFormField, form: FormGroup): boolean {\n    return this.conditionEvaluator.isVisible(field, form);\n  }\n\n  nextStep(i: number): void {\n    this.stepForms[i].markAllAsTouched();\n    this.cdr.markForCheck();\n    if (this.stepForms[i].invalid) return;\n\n    const guard = this.config.steps[i].beforeNext;\n    if (!guard) {\n      this.stepper.next();\n      this.stepChange.emit(i + 1);\n      return;\n    }\n\n    this.guardLoading[i] = true;\n    this.guardError[i] = null;\n    this.cdr.markForCheck();\n\n    const body = guard.withFormValues ? this.stepForms[i].getRawValue() : {};\n    const req$ = guard.method === 'POST'\n      ? this.http.post<any>(guard.url, body)\n      : this.http.get<any>(guard.url);\n\n    req$.subscribe({\n      next: (result) => {\n        this.guardLoading[i] = false;\n        if (guard.resultKey && result && typeof result === 'object' && this.stepForms[i + 1]) {\n          this.stepForms[i + 1].patchValue(result);\n        }\n        this.stepper.next();\n        this.stepChange.emit(i + 1);\n        this.cdr.markForCheck();\n      },\n      error: () => {\n        this.guardLoading[i] = false;\n        this.guardError[i] = guard.errorMessage ?? 'Une erreur est survenue. Veuillez réessayer.';\n        this.cdr.markForCheck();\n      },\n    });\n  }\n\n  goToStep(i: number): void {\n    this.stepper.selectedIndex = i;\n  }\n\n  onSubmit(): void {\n    if (!this.stepForms.every(f => f.valid)) {\n      this.stepForms.forEach(f => f.markAllAsTouched());\n      this.cdr.markForCheck();\n      return;\n    }\n    this.formSubmit.emit({\n      value: this.getAllValues(),\n      rawValue: this.getAllRawValues(),\n    });\n  }\n\n  onReset(): void {\n    this.stepForms.forEach(f => f.reset());\n    this.stepper.reset();\n  }\n\n  // ── Summary ──────────────────────────────────────────────────────────────\n\n  getSummary(): SummarySection[] {\n    return this.config.steps.map((step, i) => ({\n      stepLabel: step.label,\n      stepIndex: i,\n      items: step.fields\n        .filter(f => f.type !== 'divider' && f.type !== 'heading' && f.type !== 'hidden')\n        .map(f => ({\n          label: f.label || f.placeholder || f.key,\n          value: this.formatValue(f, this.stepForms[i]?.value?.[f.key]),\n        }))\n        .filter(item => item.value !== '—'),\n    }));\n  }\n\n  formatValue(field: DynamicFormField, value: any): string {\n    if (value === null || value === undefined || value === '' || value === false) return '—';\n\n    if (field.type === 'checkbox') return value ? 'Oui' : 'Non';\n\n    if ((field.type === 'select' || field.type === 'radio') && Array.isArray(field.options)) {\n      const opt = (field.options as SelectOption[]).find(o => o.value === value);\n      return opt?.label ?? String(value);\n    }\n\n    if (field.type === 'multiselect' && Array.isArray(field.options) && Array.isArray(value)) {\n      const labels = value.map(v => {\n        const opt = (field.options as SelectOption[]).find(o => o.value === v);\n        return opt?.label ?? String(v);\n      });\n      return labels.join(', ') || '—';\n    }\n\n    if (field.type === 'date' && value) {\n      try { return new Date(value).toLocaleDateString('fr-FR'); } catch { /* fall through */ }\n    }\n\n    if (field.type === 'password') return '••••••••';\n\n    if (Array.isArray(value)) return value.join(', ');\n\n    return String(value);\n  }\n\n  // ── Public API ────────────────────────────────────────────────────────────\n\n  getStepForm(stepIdx: number): FormGroup { return this.stepForms[stepIdx]; }\n\n  getAllValues(): Record<string, any> {\n    return this.stepForms.reduce((acc, fg) => ({ ...acc, ...fg.value }), {});\n  }\n\n  private getAllRawValues(): Record<string, any> {\n    return this.stepForms.reduce((acc, fg) => ({ ...acc, ...fg.getRawValue() }), {});\n  }\n}\n","import { Component, computed, inject, Input, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { ActivatedRoute, RouterLink } from '@angular/router';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatSnackBar } from '@angular/material/snack-bar';\nimport { MatTooltip } from '@angular/material/tooltip';\n\nimport { DynamicFormComponent } from '../dynamic-form/dynamic-form.component';\nimport { StepperFormComponent } from '../stepper-form/stepper-form.component';\nimport { FormConfigService } from '../../services/form-config.service';\nimport { PHONE_COUNTRIES } from '../../data/phone-countries';\nimport type {\n  DynamicFormConfig,\n  DynamicFormField,\n  FieldCondition,\n  FieldLookup,\n  FieldType,\n  FieldValidation,\n  RemoteSearchConfig,\n  SelectOption,\n  StepGuard,\n  StepperFormConfig,\n} from '../../models/form-field.model';\nimport type { SavedFormSchema } from '../../models/saved-form.model';\n\n// ── Internal types ────────────────────────────────────────────────────────────\n\ninterface FieldTypeDef {\n  type: FieldType;\n  label: string;\n  icon: string;\n  group: 'Saisie' | 'Choix' | 'Mise en page';\n}\n\ninterface BuilderStep {\n  label: string;\n  icon?: string;\n  fields: DynamicFormField[];\n  // v1.6.0\n  atLeastOneOf?: string[];\n  atLeastOneOfMessage?: string;\n  beforeNext?: StepGuard;\n}\n\n// ── Constants ─────────────────────────────────────────────────────────────────\n\nconst FIELD_TYPES: FieldTypeDef[] = [\n  // ── Saisie texte ────────────────────────────────────────────────────────────\n  { type: 'text',           label: 'Texte',               icon: 'text_fields',            group: 'Saisie' },\n  { type: 'email',          label: 'E-mail',              icon: 'email',                  group: 'Saisie' },\n  { type: 'password',       label: 'Mot de passe',        icon: 'lock',                   group: 'Saisie' },\n  { type: 'number',         label: 'Nombre',              icon: 'pin',                    group: 'Saisie' },\n  { type: 'tel',            label: 'Téléphone',           icon: 'phone',                  group: 'Saisie' },\n  { type: 'url',            label: 'URL',                 icon: 'link',                   group: 'Saisie' },\n  { type: 'textarea',       label: 'Zone de texte',       icon: 'notes',                  group: 'Saisie' },\n  // ── Date & Heure ────────────────────────────────────────────────────────────\n  { type: 'date',           label: 'Date',                icon: 'calendar_today',         group: 'Saisie' },\n  { type: 'datetime-local', label: 'Date & Heure',        icon: 'event',                  group: 'Saisie' },\n  { type: 'time',           label: 'Heure',               icon: 'schedule',               group: 'Saisie' },\n  { type: 'month',          label: 'Mois',                icon: 'date_range',             group: 'Saisie' },\n  { type: 'week',           label: 'Semaine',             icon: 'view_week',              group: 'Saisie' },\n  // ── Spéciaux ────────────────────────────────────────────────────────────────\n  { type: 'phone',          label: 'Téléphone (intl)',    icon: 'phone_in_talk',          group: 'Saisie' },\n  { type: 'range',          label: 'Curseur (range)',     icon: 'tune',                   group: 'Saisie' },\n  { type: 'color',          label: 'Couleur',             icon: 'palette',                group: 'Saisie' },\n  { type: 'location',       label: 'Géolocalisation',     icon: 'my_location',            group: 'Saisie' },\n  { type: 'file',           label: 'Fichier',             icon: 'attach_file',            group: 'Saisie' },\n  { type: 'iso-country',    label: 'Code ISO pays',       icon: 'flag',                   group: 'Saisie' },\n  { type: 'country-dial-code', label: 'Indicatif pays',   icon: 'add_call',               group: 'Saisie' },\n  // ── Choix ───────────────────────────────────────────────────────────────────\n  { type: 'select',         label: 'Liste déroulante',    icon: 'arrow_drop_down_circle', group: 'Choix'  },\n  { type: 'multiselect',    label: 'Multi-sélection',     icon: 'checklist',              group: 'Choix'  },\n  { type: 'radio',          label: 'Boutons radio',       icon: 'radio_button_checked',   group: 'Choix'  },\n  { type: 'checkbox',       label: 'Case à cocher',       icon: 'check_box',              group: 'Choix'  },\n  { type: 'switch',         label: 'Interrupteur',        icon: 'toggle_on',              group: 'Choix'  },\n  // ── Mise en page ────────────────────────────────────────────────────────────\n  { type: 'heading',        label: 'Titre de section',    icon: 'title',                  group: 'Mise en page' },\n  { type: 'divider',        label: 'Séparateur',          icon: 'horizontal_rule',        group: 'Mise en page' },\n];\n\nconst FIELD_ICONS: Record<string, string> = Object.fromEntries(\n  FIELD_TYPES.map(f => [f.type, f.icon]),\n);\n\nconst GROUPS = ['Saisie', 'Choix', 'Mise en page'] as const;\nconst COL_OPTIONS = [1, 2, 3, 4, 6, 8, 9, 12] as const;\n\nexport const ICON_OPTIONS: { value: string; label: string }[] = [\n  { value: '',                   label: '— Aucune —' },\n  { value: 'person',             label: 'person — Personne' },\n  { value: 'badge',              label: 'badge — Badge' },\n  { value: 'account_circle',     label: 'account_circle — Compte' },\n  { value: 'group',              label: 'group — Groupe' },\n  { value: 'groups',             label: 'groups — Groupes' },\n  { value: 'email',              label: 'email — E-mail' },\n  { value: 'phone',              label: 'phone — Téléphone' },\n  { value: 'smartphone',         label: 'smartphone — Mobile' },\n  { value: 'link',               label: 'link — URL / Lien' },\n  { value: 'lock',               label: 'lock — Mot de passe' },\n  { value: 'key',                label: 'key — Clé' },\n  { value: 'security',           label: 'security — Sécurité' },\n  { value: 'public',             label: 'public — Pays' },\n  { value: 'location_city',      label: 'location_city — Ville' },\n  { value: 'map',                label: 'map — Carte / Département' },\n  { value: 'home',               label: 'home — Adresse' },\n  { value: 'apartment',          label: 'apartment — Immeuble' },\n  { value: 'calendar_today',     label: 'calendar_today — Date' },\n  { value: 'event',              label: 'event — Événement' },\n  { value: 'schedule',           label: 'schedule — Heure' },\n  { value: 'cake',               label: 'cake — Anniversaire' },\n  { value: 'business',           label: 'business — Entreprise' },\n  { value: 'tag',                label: 'tag — SIRET / ID' },\n  { value: 'work',               label: 'work — Emploi' },\n  { value: 'domain',             label: 'domain — Organisation' },\n  { value: 'payment',            label: 'payment — Paiement' },\n  { value: 'credit_card',        label: 'credit_card — Carte' },\n  { value: 'account_balance',    label: 'account_balance — Banque' },\n  { value: 'euro',               label: 'euro — Montant' },\n  { value: 'attach_file',        label: 'attach_file — Fichier' },\n  { value: 'image',              label: 'image — Image' },\n  { value: 'description',        label: 'description — Document' },\n  { value: 'folder',             label: 'folder — Dossier' },\n  { value: 'edit',               label: 'edit — Édition' },\n  { value: 'edit_note',          label: 'edit_note — Note / Bio' },\n  { value: 'notes',              label: 'notes — Zone de texte' },\n  { value: 'title',              label: 'title — Titre' },\n  { value: 'pin',                label: 'pin — Code / PIN' },\n  { value: 'search',             label: 'search — Recherche' },\n  { value: 'info',               label: 'info — Information' },\n  { value: 'help',               label: 'help — Aide' },\n  { value: 'star',               label: 'star — Favori' },\n  { value: 'favorite',           label: 'favorite — Favori / Like' },\n  { value: 'send',               label: 'send — Envoyer' },\n  { value: 'visibility',         label: 'visibility — Voir' },\n  { value: 'check_circle',       label: 'check_circle — Validé' },\n];\n\n// ── Component ─────────────────────────────────────────────────────────────────\n\n@Component({\n  selector: 'ngx-form-builder',\n  standalone: true,\n  imports: [FormsModule, MatIcon, MatTooltip, RouterLink, DynamicFormComponent, StepperFormComponent],\n  templateUrl: './form-builder.component.html',\n  styleUrl: './form-builder.component.scss',\n})\nexport class FormBuilderComponent {\n  @Input() backRoute = '/';\n\n  private formService = inject(FormConfigService);\n  private snack       = inject(MatSnackBar);\n  private route        = inject(ActivatedRoute, { optional: true });\n\n  constructor() {\n    // Auto-charge le formulaire quand le composant est routé avec un :code\n    // (ex: 'forms/builder/:code') — fetch direct par code (pas besoin de la\n    // liste complète : reste rapide même avec des centaines de formulaires).\n    // Par code, pas par id : même convention que FormLoaderComponent, et\n    // l'endpoint GET /forms/:id de certains backends ne résout pas toujours\n    // correctement l'id alors que GET /forms/code/:code fonctionne.\n    const code = this.route?.snapshot.paramMap.get('code');\n    if (code) {\n      this.formService.fetchByCode(code).subscribe(schema => {\n        if (schema) this.applySchema(schema);\n      });\n    }\n  }\n\n  // ── Mode ──────────────────────────────────────────────────────────────────\n  isStepperMode = signal(false);\n\n  // ── Flat mode state ───────────────────────────────────────────────────────\n  private flatFields = signal<DynamicFormField[]>([]);\n\n  // ── Stepper mode state ────────────────────────────────────────────────────\n  steps            = signal<BuilderStep[]>([{ label: 'Étape 1', fields: [] }]);\n  selectedStepIdx  = signal(0);\n  renamingStepIdx  = signal<number | null>(null);\n  renamingLabel    = signal('');\n\n  // ── Shared state ──────────────────────────────────────────────────────────\n  selectedIdx  = signal<number | null>(null);\n  activeTab    = signal<'schema' | 'preview'>('schema');\n  formTitle    = signal('Mon formulaire');\n  submitLabel  = signal('Envoyer');\n  resetLabel   = signal('Réinitialiser');\n  showReset           = signal(false);\n  stepperShowSummary    = signal(true);\n  formAppearance        = signal<'outline' | 'fill' | 'simple'>('outline');\n  formFloatLabel        = signal<'auto' | 'always'>('auto');\n  formAtLeastOneOfKeys  = signal('');    // comma-separated field keys\n  formAtLeastOneOfMsg   = signal('');\n  formCode            = signal('');\n  currentId           = signal<string | null>(null);\n  showExport   = signal(false);\n  exportContent = signal('');\n\n  savedSchemas = this.formService.schemas;\n\n  readonly groups      = GROUPS;\n  readonly fieldTypes  = FIELD_TYPES;\n  readonly colOptions  = COL_OPTIONS;\n  readonly iconOptions = ICON_OPTIONS;\n  readonly phoneCountries = PHONE_COUNTRIES;\n\n  // ── Active fields (read from flat or selected step) ───────────────────────\n  readonly fields = computed(() =>\n    this.isStepperMode()\n      ? (this.steps()[this.selectedStepIdx()]?.fields ?? [])\n      : this.flatFields()\n  );\n\n  readonly selectedField = computed(() => {\n    const i = this.selectedIdx();\n    return i !== null ? this.fields()[i] : null;\n  });\n\n  readonly previewConfig = computed<DynamicFormConfig>(() => {\n    const keys = this.formAtLeastOneOfKeys().split(',').map(s => s.trim()).filter(Boolean);\n    return {\n      submitLabel:          this.submitLabel(),\n      resetLabel:           this.resetLabel(),\n      showReset:            this.showReset(),\n      fields:               this.fields(),\n      appearance:           this.formAppearance(),\n      floatLabel:           this.formFloatLabel(),\n      ...(keys.length ? { atLeastOneOf: keys } : {}),\n      ...(keys.length && this.formAtLeastOneOfMsg() ? { atLeastOneOfMessage: this.formAtLeastOneOfMsg() } : {}),\n    };\n  });\n\n  readonly stepperPreviewConfig = computed<StepperFormConfig>(() => ({\n    steps:       this.steps(),\n    submitLabel: this.submitLabel(),\n    resetLabel:  this.resetLabel(),\n    showReset:   this.showReset(),\n    showSummary: this.stepperShowSummary(),\n    appearance:  this.formAppearance(),\n    floatLabel:  this.formFloatLabel(),\n  }));\n\n  readonly groupedTypes = computed(() =>\n    GROUPS.map(g => ({ label: g, types: FIELD_TYPES.filter(f => f.group === g) })),\n  );\n\n  readonly stepperIsEmpty = computed(() =>\n    this.steps().every(s => s.fields.length === 0)\n  );\n\n  // ── Field mutations ───────────────────────────────────────────────────────\n\n  private mutateFields(fn: (fields: DynamicFormField[]) => DynamicFormField[]): void {\n    if (this.isStepperMode()) {\n      const stepIdx = this.selectedStepIdx();\n      this.steps.update(ss => {\n        const arr = [...ss];\n        arr[stepIdx] = { ...arr[stepIdx], fields: fn(arr[stepIdx].fields) };\n        return arr;\n      });\n    } else {\n      this.flatFields.update(fn);\n    }\n  }\n\n  getIcon(type: string): string { return FIELD_ICONS[type] ?? 'input'; }\n\n  getFieldDisplay(field: DynamicFormField): string {\n    return field.label || field.text || field.placeholder || field.key;\n  }\n\n  isInputField(type: FieldType): boolean { return type !== 'divider' && type !== 'heading'; }\n  hasOptions(type: FieldType): boolean   { return ['select', 'multiselect', 'radio'].includes(type); }\n  needsRows(type: FieldType): boolean    { return type === 'textarea'; }\n  isHeading(type: FieldType): boolean    { return type === 'heading'; }\n  isDivider(type: FieldType): boolean    { return type === 'divider'; }\n\n  addField(type: FieldType): void {\n    const existing = this.fields().filter(f => f.type === type).length;\n    const suffix   = existing > 0 ? existing + 1 : '';\n    const key      = `${type.replace('-', '_')}${suffix}`;\n    const base: DynamicFormField = { key, type, col: 12 };\n    if (this.isInputField(type)) base.label = this._defaultLabel(type);\n    if (this.hasOptions(type))   base.options = [{ label: 'Option 1', value: 'option1' }];\n    if (type === 'heading')      Object.assign(base, { text: 'Nouvelle section', level: 3 });\n    if (type === 'radio')        base.defaultValue = null;\n    if (type === 'range')        Object.assign(base, { min: 0, max: 100, step: 1, defaultValue: 0, showValue: true });\n    if (type === 'color')        base.defaultValue = '#3b82f6';\n    this.mutateFields(f => [...f, base]);\n    this.selectedIdx.set(this.fields().length - 1);\n    this.activeTab.set('schema');\n  }\n\n  removeField(i: number, e: Event): void {\n    e.stopPropagation();\n    this.mutateFields(f => f.filter((_, idx) => idx !== i));\n    if (this.selectedIdx() === i) this.selectedIdx.set(null);\n    else if ((this.selectedIdx() ?? 0) > i) this.selectedIdx.update(v => (v ?? 1) - 1);\n  }\n\n  moveUp(i: number, e: Event): void {\n    e.stopPropagation();\n    if (i === 0) return;\n    this.mutateFields(f => { const a = [...f]; [a[i - 1], a[i]] = [a[i], a[i - 1]]; return a; });\n    if (this.selectedIdx() === i) this.selectedIdx.set(i - 1);\n  }\n\n  moveDown(i: number, e: Event): void {\n    e.stopPropagation();\n    if (i >= this.fields().length - 1) return;\n    this.mutateFields(f => { const a = [...f]; [a[i], a[i + 1]] = [a[i + 1], a[i]]; return a; });\n    if (this.selectedIdx() === i) this.selectedIdx.set(i + 1);\n  }\n\n  selectField(i: number): void { this.selectedIdx.set(this.selectedIdx() === i ? null : i); }\n\n  duplicateField(i: number, e: Event): void {\n    e.stopPropagation();\n    const clone: DynamicFormField = {\n      ...this.fields()[i],\n      key: `${this.fields()[i].key}_copy${Date.now().toString(36).slice(-3)}`,\n    };\n    this.mutateFields(f => [...f.slice(0, i + 1), clone, ...f.slice(i + 1)]);\n    this.selectedIdx.set(i + 1);\n  }\n\n  updateProp(prop: keyof DynamicFormField, value: any): void {\n    const i = this.selectedIdx();\n    if (i === null) return;\n    this.mutateFields(list => { const c = [...list]; c[i] = { ...c[i], [prop]: value }; return c; });\n  }\n\n  // Le spread d'objet n'est pas supporté dans les expressions de template Angular\n  // ({ ...field.remoteSearch, x }) — merge fait ici plutôt que dans le HTML.\n  updateRemoteSearch(prop: keyof RemoteSearchConfig, value: any): void {\n    const i = this.selectedIdx();\n    if (i === null) return;\n    this.mutateFields(list => {\n      const c = [...list];\n      c[i] = { ...c[i], remoteSearch: { ...c[i].remoteSearch, [prop]: value } };\n      return c;\n    });\n  }\n\n  updateValidation(prop: keyof FieldValidation, value: any): void {\n    const i = this.selectedIdx();\n    if (i === null) return;\n    this.mutateFields(list => {\n      const c     = [...list];\n      const field = { ...c[i] };\n      const valid = { ...field.validation };\n      if (value === '' || value === null || value === undefined || value === false) {\n        delete (valid as any)[prop];\n      } else {\n        (valid as any)[prop] = value;\n      }\n      field.validation = Object.keys(valid).length ? valid : undefined;\n      c[i] = field;\n      return c;\n    });\n  }\n\n  getOptions(): SelectOption[] { return (this.selectedField()?.options as SelectOption[]) ?? []; }\n\n  addOption(): void {\n    const n = this.getOptions().length + 1;\n    this.updateProp('options', [...this.getOptions(), { label: `Option ${n}`, value: `option${n}` }]);\n  }\n\n  updateOption(idx: number, prop: 'label' | 'value' | 'dependsOnValue', value: string): void {\n    const opts = [...this.getOptions()];\n    opts[idx] = { ...opts[idx], [prop]: prop === 'dependsOnValue' && value === '' ? undefined : value };\n    this.updateProp('options', opts);\n  }\n\n  /** Options statiques du champ dont dépend le champ sélectionné (vide si liste API ou autre type). */\n  parentStaticOptions(): SelectOption[] {\n    const parentKey = this.selectedField()?.dependsOn;\n    const parent = parentKey ? this.fields().find(f => f.key === parentKey) : undefined;\n    if (!parent || parent.url !== undefined || !Array.isArray(parent.options)) return [];\n    return (parent.options as (SelectOption | string)[]).map(o => typeof o === 'string' ? { label: o, value: o } : o);\n  }\n\n  removeOption(idx: number): void {\n    this.updateProp('options', this.getOptions().filter((_, i) => i !== idx));\n  }\n\n  setOptionsSource(useUrl: boolean): void {\n    if (useUrl) {\n      this.updateProp('url', '');\n      this.updateProp('displayName', 'label');\n      this.updateProp('displayValue', 'value');\n      this.updateProp('options', []);\n    } else {\n      this.deleteProp('url', 'displayName', 'displayValue');\n      this.updateProp('options', [{ label: 'Option 1', value: 'option1' }]);\n    }\n  }\n\n  private deleteProp(...props: (keyof DynamicFormField)[]): void {\n    const i = this.selectedIdx();\n    if (i === null) return;\n    this.mutateFields(list => {\n      const c = [...list];\n      const updated = { ...c[i] };\n      props.forEach(p => delete updated[p]);\n      c[i] = updated;\n      return c;\n    });\n  }\n\n  // ── Pattern validation ────────────────────────────────────────────────────\n\n  setPattern(regex: string): void {\n    this.updateValidation('pattern', regex || undefined);\n  }\n\n  updateValidationMessage(key: keyof NonNullable<FieldValidation['messages']>, value: string): void {\n    const i = this.selectedIdx();\n    if (i === null) return;\n    this.mutateFields(list => {\n      const c = [...list];\n      const field = { ...c[i] };\n      const msgs = { ...(field.validation?.messages ?? {}), [key]: value || undefined };\n      if (!value) delete (msgs as any)[key];\n      field.validation = {\n        ...field.validation,\n        messages: Object.keys(msgs).length ? msgs : undefined,\n      };\n      c[i] = field;\n      return c;\n    });\n  }\n\n  // ── showWhen builder ──────────────────────────────────────────────────────\n\n  getConditions(): FieldCondition[] {\n    const sw = this.selectedField()?.showWhen;\n    if (!sw) return [];\n    return Array.isArray(sw) ? sw : [sw];\n  }\n\n  allFieldKeysExcludingCurrent(): string[] {\n    const currentKey = this.selectedField()?.key;\n    return this.fields()\n      .filter(f => f.key && f.key !== currentKey)\n      .map(f => f.key!);\n  }\n\n  setConditionLogic(logic: 'AND' | 'OR'): void {\n    this.updateProp('conditionLogic', logic);\n  }\n\n  addCondition(): void {\n    const conditions: FieldCondition[] = [\n      ...this.getConditions(),\n      { field: '', operator: 'equals', value: '' },\n    ];\n    this.updateProp('showWhen', conditions);\n  }\n\n  removeCondition(index: number): void {\n    const conditions = this.getConditions().filter((_, i) => i !== index);\n    this.updateProp('showWhen', conditions.length ? conditions : undefined);\n    if (!conditions.length) this.updateProp('conditionLogic', undefined);\n  }\n\n  updateCondition(index: number, key: keyof FieldCondition, value: any): void {\n    const conditions = this.getConditions().map((c, i) =>\n      i === index ? { ...c, [key]: value } : c\n    );\n    this.updateProp('showWhen', conditions);\n  }\n\n  // ── Filtre des options API (optionsFilter) ──────────────────────────────────\n  // Même forme que showWhen, mais condition.field est une propriété brute d'un\n  // item API (ex: 'status'), pas la clé d'un autre champ du formulaire — pas de\n  // dropdown allFieldKeysExcludingCurrent() possible ici, juste un texte libre.\n\n  getOptionsFilterConditions(): FieldCondition[] {\n    const f = this.selectedField()?.optionsFilter;\n    if (!f) return [];\n    return Array.isArray(f) ? f : [f];\n  }\n\n  setOptionsFilterLogic(logic: 'AND' | 'OR'): void {\n    this.updateProp('optionsFilterLogic', logic);\n  }\n\n  addOptionsFilterCondition(): void {\n    const conditions: FieldCondition[] = [\n      ...this.getOptionsFilterConditions(),\n      { field: '', operator: 'equals', value: '' },\n    ];\n    this.updateProp('optionsFilter', conditions);\n  }\n\n  removeOptionsFilterCondition(index: number): void {\n    const conditions = this.getOptionsFilterConditions().filter((_, i) => i !== index);\n    this.updateProp('optionsFilter', conditions.length ? conditions : undefined);\n    if (!conditions.length) this.updateProp('optionsFilterLogic', undefined);\n  }\n\n  updateOptionsFilterCondition(index: number, key: keyof FieldCondition, value: any): void {\n    const conditions = this.getOptionsFilterConditions().map((c, i) =>\n      i === index ? { ...c, [key]: value } : c\n    );\n    this.updateProp('optionsFilter', conditions);\n  }\n\n  // ── Unicité API ───────────────────────────────────────────────────────────\n\n  toggleUniqueCheck(enabled: boolean): void {\n    this.updateProp('uniqueCheck', enabled\n      ? { url: '', message: 'Cette valeur existe déjà.' }\n      : undefined\n    );\n  }\n\n  setUniqueCheckProp(key: 'url' | 'message', value: string): void {\n    const current = this.selectedField()?.uniqueCheck;\n    if (!current) return;\n    this.updateProp('uniqueCheck', { ...current, [key]: value });\n  }\n\n  // ── Lookup ────────────────────────────────────────────────────────────────\n\n  toggleLookup(enabled: boolean): void {\n    this.updateProp('lookup', enabled ? { url: '', populate: {} } : undefined);\n  }\n\n  setLookupUrl(value: string): void {\n    const l = this.selectedField()?.lookup ?? { url: '', populate: {} };\n    this.updateProp('lookup', { ...l, url: value });\n  }\n\n  setLookupMethod(value: string): void {\n    const l = this.selectedField()?.lookup ?? { url: '', populate: {} };\n    this.updateProp('lookup', { ...l, method: value as FieldLookup['method'] });\n  }\n\n  getLookupPopulateText(): string {\n    const p = this.selectedField()?.lookup?.populate ?? {};\n    return Object.entries(p).map(([k, v]) => `${k}=${v}`).join('\\n');\n  }\n\n  setLookupTriggerOn(value: string): void {\n    const l = this.selectedField()?.lookup ?? { url: '', populate: {} };\n    this.updateProp('lookup', { ...l, triggerOn: value as FieldLookup['triggerOn'] });\n  }\n\n  setLookupPopulateText(text: string): void {\n    const populate: Record<string, string> = {};\n    text.split('\\n').forEach(line => {\n      const idx = line.indexOf('=');\n      if (idx > 0) populate[line.slice(0, idx).trim()] = line.slice(idx + 1).trim();\n    });\n    const l = this.selectedField()?.lookup ?? { url: '', populate: {} };\n    this.updateProp('lookup', { ...l, populate });\n  }\n\n  // ── Required conditionnel ─────────────────────────────────────────────────\n\n  getRequiredWhenConditions(): FieldCondition[] {\n    const rw = this.selectedField()?.validation?.requiredWhen;\n    if (!rw) return [];\n    return Array.isArray(rw) ? rw : [rw];\n  }\n\n  addRequiredWhenCondition(): void {\n    const conditions: FieldCondition[] = [...this.getRequiredWhenConditions(), { field: '', operator: 'equals', value: '' }];\n    this.updateValidation('requiredWhen', conditions);\n  }\n\n  removeRequiredWhenCondition(index: number): void {\n    const conditions = this.getRequiredWhenConditions().filter((_, i) => i !== index);\n    this.updateValidation('requiredWhen', conditions.length ? conditions : undefined);\n  }\n\n  updateRequiredWhenCondition(index: number, key: keyof FieldCondition, value: any): void {\n    const conditions = this.getRequiredWhenConditions().map((c, i) =>\n      i === index ? { ...c, [key]: value } : c,\n    );\n    this.updateValidation('requiredWhen', conditions);\n  }\n\n  // ── Step-level settings ───────────────────────────────────────────────────\n\n  updateCurrentStep(key: string, value: any): void {\n    const i = this.selectedStepIdx();\n    this.steps.update(ss => {\n      const arr = [...ss];\n      const updated = { ...arr[i] } as any;\n      if (value === undefined || value === null || value === '' || (Array.isArray(value) && !value.length)) {\n        delete updated[key];\n      } else {\n        updated[key] = value;\n      }\n      arr[i] = updated;\n      return arr;\n    });\n  }\n\n  getStepAtLeastOneOf(): string {\n    const keys = (this.steps()[this.selectedStepIdx()] as any)?.atLeastOneOf as string[] | undefined;\n    return keys?.join(', ') ?? '';\n  }\n\n  setStepAtLeastOneOf(text: string): void {\n    const keys = text.split(',').map(s => s.trim()).filter(Boolean);\n    this.updateCurrentStep('atLeastOneOf', keys);\n  }\n\n  getStepBeforeNext(): StepGuard | undefined {\n    return (this.steps()[this.selectedStepIdx()] as any)?.beforeNext as StepGuard | undefined;\n  }\n\n  toggleBeforeNext(enabled: boolean): void {\n    this.updateCurrentStep('beforeNext', enabled ? { url: '', method: 'POST' } : undefined);\n  }\n\n  setBeforeNextProp(key: keyof StepGuard, value: string): void {\n    const current = this.getStepBeforeNext() ?? { url: '', method: 'POST' as const };\n    this.updateCurrentStep('beforeNext', { ...current, [key]: value || undefined });\n  }\n\n  // ── Style helpers ─────────────────────────────────────────────────────────\n\n  /** Presets de masques de saisie courants */\n  readonly maskPresets = [\n    { label: '— Aucun —',                          value: '' },\n    { label: 'Téléphone SN (## ### ## ##)',         value: '## ### ## ##' },\n    { label: 'Téléphone intl (+### ## ## ## ##)',   value: '+### ## ## ## ##' },\n    { label: 'Date (##/##/####)',                   value: '##/##/####' },\n    { label: 'Heure (##:##)',                       value: '##:##' },\n    { label: 'Carte bancaire (#### #### #### ####)', value: '#### #### #### ####' },\n    { label: 'Code postal (####)',                  value: '####' },\n    { label: 'Personnalisé…',                       value: '__custom__' },\n  ];\n\n  isCustomMask(): boolean {\n    const m = this.selectedField()?.mask;\n    if (!m) return false;\n    return !this.maskPresets.some(p => p.value === m && p.value !== '__custom__');\n  }\n\n  setMaskPreset(value: string): void {\n    if (value === '__custom__') {\n      this.updateProp('mask', '');\n    } else {\n      this.updateProp('mask', value || undefined);\n    }\n  }\n\n  getMaskPresetValue(): string {\n    const m = this.selectedField()?.mask;\n    if (!m) return '';\n    const found = this.maskPresets.find(p => p.value === m);\n    return found ? m : '__custom__';\n  }\n\n  /** Convertit le Record<string,string> en texte CSS pour l'éditeur */\n  getStylesText(): string {\n    const styles = this.selectedField()?.styles ?? {};\n    return Object.entries(styles).map(([k, v]) => `${k}: ${v}`).join('; ');\n  }\n\n  /** Parse le texte CSS et met à jour la propriété styles */\n  setStylesText(cssText: string): void {\n    const styles: Record<string, string> = {};\n    cssText.split(';').forEach(rule => {\n      const idx = rule.indexOf(':');\n      if (idx > 0) {\n        const key = rule.slice(0, idx).trim();\n        const val = rule.slice(idx + 1).trim();\n        if (key && val) styles[key] = val;\n      }\n    });\n    this.updateProp('styles', Object.keys(styles).length ? styles : undefined);\n  }\n\n  // ── Mode management ───────────────────────────────────────────────────────\n\n  setMode(stepper: boolean): void {\n    this.isStepperMode.set(stepper);\n    this.selectedIdx.set(null);\n  }\n\n  // ── Step management ───────────────────────────────────────────────────────\n\n  selectStep(i: number): void {\n    this.selectedStepIdx.set(i);\n    this.selectedIdx.set(null);\n  }\n\n  addStep(): void {\n    const n = this.steps().length + 1;\n    this.steps.update(ss => [...ss, { label: `Étape ${n}`, fields: [] }]);\n    this.selectStep(this.steps().length - 1);\n  }\n\n  deleteStep(i: number, e: Event): void {\n    e.stopPropagation();\n    if (this.steps().length <= 1) return;\n    this.steps.update(ss => ss.filter((_, idx) => idx !== i));\n    const newIdx = Math.min(this.selectedStepIdx(), this.steps().length - 1);\n    this.selectStep(newIdx);\n  }\n\n  startRename(i: number, e: Event): void {\n    e.stopPropagation();\n    this.renamingStepIdx.set(i);\n    this.renamingLabel.set(this.steps()[i].label);\n  }\n\n  confirmRename(i: number): void {\n    const label = this.renamingLabel().trim() || `Étape ${i + 1}`;\n    this.steps.update(ss => {\n      const arr = [...ss];\n      arr[i] = { ...arr[i], label };\n      return arr;\n    });\n    this.renamingStepIdx.set(null);\n  }\n\n  cancelRename(): void { this.renamingStepIdx.set(null); }\n\n  // ── Save / Load ───────────────────────────────────────────────────────────\n\n  save(): void {\n    if (!this.formCode().trim()) {\n      this.snack.open('Le code est obligatoire', '', { duration: 3000 });\n      return;\n    }\n    if (!this.formTitle().trim()) {\n      this.snack.open('Le titre est obligatoire', '', { duration: 3000 });\n      return;\n    }\n    const title  = this.formTitle();\n    const config = this.isStepperMode() ? this.stepperPreviewConfig() : this.previewConfig();\n    const id     = this.currentId();\n    if (id === null) {\n      this.formService.create(this.formCode(), title, config).subscribe({\n        next: saved => {\n          this.currentId.set(saved.id);\n          this.snack.open(`✓ \"${title}\" sauvegardé`, '', { duration: 2500 });\n        },\n        error: err => this.snack.open(`Erreur : ${err.message ?? err}`, 'Fermer', { duration: 5000 }),\n      });\n    } else {\n      const schema = this.formService.get(id)!;\n      this.formService.update(schema, title, config).subscribe({\n        next: () => this.snack.open(`✓ \"${title}\" mis à jour`, '', { duration: 2500 }),\n        error: err => this.snack.open(`Erreur : ${err.message ?? err}`, 'Fermer', { duration: 5000 }),\n      });\n    }\n  }\n\n  loadSchema(id: string): void {\n    const schema = this.formService.get(id);\n    if (!schema) return;\n    this.applySchema(schema);\n  }\n\n  private applySchema(schema: SavedFormSchema): void {\n    const config = schema.config as any;\n    const isStepper = Array.isArray(config.steps);\n\n    this.isStepperMode.set(isStepper);\n\n    if (isStepper) {\n      this.steps.set((config as StepperFormConfig).steps.map(s => ({ ...s })));\n      this.selectedStepIdx.set(0);\n    } else {\n      this.flatFields.set((config as DynamicFormConfig).fields ?? []);\n    }\n\n    this.formTitle.set(schema.title);\n    this.formCode.set(schema.code ?? '');\n    this.submitLabel.set(config.submitLabel ?? 'Envoyer');\n    this.resetLabel.set(config.resetLabel ?? 'Réinitialiser');\n    this.showReset.set(config.showReset ?? false);\n    this.stepperShowSummary.set((config as StepperFormConfig).showSummary ?? false);\n    this.formAppearance.set(config.appearance ?? 'outline');\n    this.formFloatLabel.set(config.floatLabel ?? 'auto');\n    this.formAtLeastOneOfKeys.set((config.atLeastOneOf as string[] | undefined)?.join(', ') ?? '');\n    this.formAtLeastOneOfMsg.set(config.atLeastOneOfMessage ?? '');\n    this.currentId.set(schema.id);\n    this.selectedIdx.set(null);\n    this.snack.open(`✓ \"${schema.title}\" chargé`, '', { duration: 2000 });\n  }\n\n  deleteSchema(id: string, e: Event): void {\n    e.stopPropagation();\n    this.formService.delete(id).subscribe({\n      next: () => { if (this.currentId() === id) this.newForm(); },\n      error: err => this.snack.open(`Erreur suppression : ${err.message ?? err}`, 'Fermer', { duration: 5000 }),\n    });\n  }\n\n  newForm(): void {\n    this.flatFields.set([]);\n    this.steps.set([{ label: 'Étape 1', fields: [] }]);\n    this.selectedStepIdx.set(0);\n    this.formTitle.set('Mon formulaire');\n    this.formCode.set('');\n    this.submitLabel.set('Envoyer');\n    this.resetLabel.set('Réinitialiser');\n    this.showReset.set(false);\n    this.stepperShowSummary.set(true);\n    this.formAppearance.set('outline');\n    this.formFloatLabel.set('auto');\n    this.formAtLeastOneOfKeys.set('');\n    this.formAtLeastOneOfMsg.set('');\n    this.currentId.set(null);\n    this.selectedIdx.set(null);\n  }\n\n  // ── Export ────────────────────────────────────────────────────────────────\n\n  exportJSON(): void {\n    const config = this.isStepperMode() ? this.stepperPreviewConfig() : this.previewConfig();\n    this.exportContent.set(JSON.stringify(config, null, 2));\n    this.showExport.set(true);\n  }\n\n  exportTypeScript(): void {\n    const config = this.isStepperMode() ? this.stepperPreviewConfig() : this.previewConfig();\n    const type   = this.isStepperMode() ? 'StepperFormConfig' : 'DynamicFormConfig';\n    const ts = `const config: ${type} = ${\n      JSON.stringify(config, null, 2)\n        .replace(/\"([a-zA-Z_][a-zA-Z0-9_]*)\"\\s*:/g, '$1:')\n        .replace(/\"/g, \"'\")\n    };\\n`;\n    this.exportContent.set(ts);\n    this.showExport.set(true);\n  }\n\n  async copyExport(): Promise<void> {\n    await navigator.clipboard.writeText(this.exportContent());\n    this.snack.open('✓ Copié dans le presse-papiers', '', { duration: 2000 });\n  }\n\n  copyFormUrl(): void {\n    const code = this.formCode();\n    if (!this.currentId() || !code) {\n      this.snack.open('Sauvegardez d\\'abord le formulaire', '', { duration: 2000 });\n      return;\n    }\n    navigator.clipboard.writeText(`${location.origin}/form/${code}`);\n    this.snack.open(`✓ Lien copié : /form/${code}`, '', { duration: 3000 });\n  }\n\n  labelOf(type: FieldType): string {\n    return FIELD_TYPES.find(f => f.type === type)?.label ?? type;\n  }\n\n  trackByKey(_i: number, field: DynamicFormField): string { return field.key; }\n  trackByIdx(i: number): number { return i; }\n\n  private _defaultLabel(type: FieldType): string {\n    const map: Partial<Record<FieldType, string>> = {\n      text: 'Texte', email: 'E-mail', password: 'Mot de passe', number: 'Nombre',\n      tel: 'Téléphone', url: 'URL', date: 'Date', textarea: 'Message',\n      select: 'Sélection', multiselect: 'Sélection multiple', radio: 'Choix',\n      checkbox: 'Option', switch: 'Activer', file: 'Fichier',\n      'datetime-local': 'Date et heure', time: 'Heure', month: 'Mois', week: 'Semaine',\n      range: 'Valeur', color: 'Couleur', location: 'Localisation', phone: 'Téléphone',\n    };\n    return map[type] ?? type;\n  }\n}\n","<div class=\"builder-root\">\n\n  <!-- ── Top Bar ───────────────────────────────────────────── -->\n  <header class=\"topbar\">\n    <a [routerLink]=\"backRoute\" class=\"topbar-back\">\n      <mat-icon>arrow_back</mat-icon>\n      <span>Retour</span>\n    </a>\n\n    <div class=\"topbar-center\">\n      <mat-icon class=\"topbar-logo\">dashboard_customize</mat-icon>\n      <input\n        [class.input-error]=\"!formCode().trim()\"\n        class=\"code-input\"\n        [ngModel]=\"formCode()\"\n        (ngModelChange)=\"formCode.set($event)\"\n        placeholder=\"Code * (unique)\"\n        aria-label=\"Code du formulaire\"\n        [disabled]=\"currentId() !== null\"\n      />\n      <input\n        [class.input-error]=\"!formTitle().trim()\"\n        class=\"title-input\"\n        [ngModel]=\"formTitle()\"\n        (ngModelChange)=\"formTitle.set($event)\"\n        placeholder=\"Titre *\"\n        aria-label=\"Titre du formulaire\"\n      />\n    </div>\n\n    <!-- Mode toggle -->\n    <div class=\"mode-toggle\">\n      <button class=\"mode-btn\" [class.active]=\"!isStepperMode()\" (click)=\"setMode(false)\" matTooltip=\"Formulaire simple\">\n        <mat-icon>list_alt</mat-icon>\n        <span>Formulaire</span>\n      </button>\n      <button class=\"mode-btn\" [class.active]=\"isStepperMode()\" (click)=\"setMode(true)\" matTooltip=\"Formulaire multi-étapes\">\n        <mat-icon>format_list_numbered</mat-icon>\n        <span>Stepper</span>\n      </button>\n    </div>\n\n    <div class=\"topbar-actions\">\n      <button class=\"btn-icon\" matTooltip=\"Nouveau formulaire\" (click)=\"newForm()\">\n        <mat-icon>add_circle_outline</mat-icon>\n      </button>\n      <button class=\"btn-icon\" matTooltip=\"Copier le lien du formulaire\" (click)=\"copyFormUrl()\">\n        <mat-icon>share</mat-icon>\n      </button>\n      <button class=\"btn-outline\" (click)=\"exportJSON()\">\n        <mat-icon>data_object</mat-icon> JSON\n      </button>\n      <button class=\"btn-outline\" (click)=\"exportTypeScript()\">\n        <mat-icon>code</mat-icon> TypeScript\n      </button>\n      <button class=\"btn-primary\" (click)=\"save()\">\n        <mat-icon>save</mat-icon> Sauvegarder\n      </button>\n    </div>\n  </header>\n\n  <!-- ── Main Layout ───────────────────────────────────────── -->\n  <div class=\"builder-body\">\n\n    <!-- ── Left: Palette ──────────────────────────────────── -->\n    <aside class=\"palette\">\n\n      <!-- Steps management (stepper mode only) -->\n      @if (isStepperMode()) {\n        <div class=\"palette-section\">\n          <p class=\"palette-section-title\">\n            <mat-icon style=\"font-size:.9rem;width:.9rem;height:.9rem;vertical-align:middle\">format_list_numbered</mat-icon>\n            Étapes\n          </p>\n          @for (step of steps(); track $index; let i = $index) {\n            <div class=\"step-item\" [class.active]=\"selectedStepIdx() === i\">\n              @if (renamingStepIdx() === i) {\n                <input\n                  class=\"step-rename-input\"\n                  [ngModel]=\"renamingLabel()\"\n                  (ngModelChange)=\"renamingLabel.set($event)\"\n                  (blur)=\"confirmRename(i)\"\n                  (keydown.enter)=\"confirmRename(i)\"\n                  (keydown.escape)=\"cancelRename()\"\n                  autofocus\n                />\n              } @else {\n                <button class=\"step-name-btn\" (click)=\"selectStep(i)\">\n                  <span class=\"step-num\">{{ i + 1 }}</span>\n                  <span class=\"step-label-text\">{{ step.label }}</span>\n                  <span class=\"step-count\">{{ step.fields.length }}</span>\n                </button>\n                <button class=\"step-action-btn\" (click)=\"startRename(i, $event)\" matTooltip=\"Renommer\">\n                  <mat-icon>edit</mat-icon>\n                </button>\n                <button class=\"step-action-btn danger\" [disabled]=\"steps().length <= 1\" (click)=\"deleteStep(i, $event)\" matTooltip=\"Supprimer\">\n                  <mat-icon>close</mat-icon>\n                </button>\n              }\n            </div>\n          }\n          <button class=\"btn-add-step\" (click)=\"addStep()\">\n            <mat-icon>add</mat-icon> Ajouter une étape\n          </button>\n        </div>\n      }\n\n      <!-- Field types -->\n      <div class=\"palette-section\">\n        <p class=\"palette-section-title\">Types de champs</p>\n        @for (group of groupedTypes(); track group.label) {\n          <p class=\"palette-group-label\">{{ group.label }}</p>\n          @for (ft of group.types; track ft.type) {\n            <button class=\"palette-btn\" (click)=\"addField(ft.type)\" matTooltip=\"Ajouter {{ ft.label }}\">\n              <mat-icon>{{ ft.icon }}</mat-icon>\n              <span>{{ ft.label }}</span>\n            </button>\n          }\n        }\n      </div>\n\n      <!-- Saved schemas -->\n      <div class=\"palette-section\">\n        <p class=\"palette-section-title\">\n          <mat-icon style=\"font-size:1rem;width:1rem;height:1rem;vertical-align:middle\">folder_open</mat-icon>\n          Formulaires sauvegardés\n        </p>\n        @if (savedSchemas().length === 0) {\n          <p class=\"palette-empty\">Aucun formulaire sauvegardé</p>\n        }\n        @for (schema of savedSchemas(); track schema.id) {\n          <div class=\"saved-item\" [class.active]=\"currentId() === schema.id\">\n            <button class=\"saved-item-name\" (click)=\"loadSchema(schema.id)\" matTooltip=\"Charger\">\n              <mat-icon>description</mat-icon>\n              <span>{{ schema.title }}</span>\n            </button>\n            <button class=\"saved-item-delete\" (click)=\"deleteSchema(schema.id, $event)\" matTooltip=\"Supprimer\">\n              <mat-icon>delete_outline</mat-icon>\n            </button>\n          </div>\n        }\n      </div>\n\n    </aside>\n\n    <!-- ── Center: Canvas ──────────────────────────────────── -->\n    <main class=\"canvas\">\n\n      <!-- Tab bar -->\n      <div class=\"canvas-tabs\">\n        <button\n          class=\"canvas-tab\"\n          [class.active]=\"activeTab() === 'schema'\"\n          (click)=\"activeTab.set('schema')\"\n        >\n          <mat-icon>list_alt</mat-icon> Schéma\n        </button>\n        <button\n          class=\"canvas-tab\"\n          [class.active]=\"activeTab() === 'preview'\"\n          (click)=\"activeTab.set('preview')\"\n        >\n          <mat-icon>visibility</mat-icon> Aperçu\n        </button>\n        <span class=\"canvas-tabs-info\">\n          @if (isStepperMode()) {\n            {{ steps().length }} étape{{ steps().length !== 1 ? 's' : '' }} ·\n          }\n          {{ fields().length }} champ{{ fields().length !== 1 ? 's' : '' }}\n        </span>\n      </div>\n\n      <!-- Step tabs (stepper mode, schema tab only) -->\n      @if (isStepperMode() && activeTab() === 'schema') {\n        <div class=\"step-tabs-bar\">\n          @for (step of steps(); track $index; let i = $index) {\n            <button\n              class=\"step-tab\"\n              [class.active]=\"selectedStepIdx() === i\"\n              (click)=\"selectStep(i)\"\n            >\n              <span class=\"step-tab-num\">{{ i + 1 }}</span>\n              <span class=\"step-tab-label\">{{ step.label }}</span>\n            </button>\n          }\n        </div>\n      }\n\n      <!-- ── Schema Tab ───────────────────────────────────── -->\n      @if (activeTab() === 'schema') {\n        <div class=\"schema-view\">\n\n          @if (fields().length === 0) {\n            <div class=\"empty-canvas\">\n              <mat-icon>add_box</mat-icon>\n              <p>Cliquez sur un type de champ à gauche pour commencer</p>\n            </div>\n          }\n\n          <div class=\"field-list\">\n            @for (field of fields(); track trackByKey($index, field); let i = $index) {\n              <div\n                class=\"field-card\"\n                [class.selected]=\"selectedIdx() === i\"\n                (click)=\"selectField(i)\"\n              >\n                <mat-icon class=\"field-card-icon\">{{ getIcon(field.type) }}</mat-icon>\n\n                <div class=\"field-card-body\">\n                  <span class=\"field-card-label\">{{ getFieldDisplay(field) }}</span>\n                  <span class=\"field-card-meta\">{{ labelOf(field.type) }} · col-{{ field.col ?? 12 }}</span>\n                </div>\n\n                @if (field.key) {\n                  <code class=\"field-card-key\">{{ field.key }}</code>\n                }\n\n                <div class=\"field-card-actions\">\n                  <button class=\"action-btn\" (click)=\"moveUp(i, $event)\" [disabled]=\"i === 0\" matTooltip=\"Monter\">\n                    <mat-icon>arrow_upward</mat-icon>\n                  </button>\n                  <button class=\"action-btn\" (click)=\"moveDown(i, $event)\" [disabled]=\"i === fields().length - 1\" matTooltip=\"Descendre\">\n                    <mat-icon>arrow_downward</mat-icon>\n                  </button>\n                  <button class=\"action-btn\" (click)=\"duplicateField(i, $event)\" matTooltip=\"Dupliquer\">\n                    <mat-icon>content_copy</mat-icon>\n                  </button>\n                  <button class=\"action-btn danger\" (click)=\"removeField(i, $event)\" matTooltip=\"Supprimer\">\n                    <mat-icon>delete_outline</mat-icon>\n                  </button>\n                </div>\n              </div>\n            }\n          </div>\n\n          <!-- Form settings -->\n          <div class=\"form-settings\">\n            <p class=\"settings-title\">\n              <mat-icon>settings</mat-icon> Paramètres du formulaire\n            </p>\n            <div class=\"settings-row\">\n              <label>Bouton Envoyer</label>\n              <input [ngModel]=\"submitLabel()\" (ngModelChange)=\"submitLabel.set($event)\" placeholder=\"Envoyer\" />\n            </div>\n            <div class=\"settings-row\">\n              <label>\n                <input type=\"checkbox\" [ngModel]=\"showReset()\" (ngModelChange)=\"showReset.set($event)\" />\n                Afficher Réinitialiser\n              </label>\n            </div>\n            @if (showReset()) {\n              <div class=\"settings-row\">\n                <label>Bouton Reset</label>\n                <input [ngModel]=\"resetLabel()\" (ngModelChange)=\"resetLabel.set($event)\" placeholder=\"Réinitialiser\" />\n              </div>\n            }\n            @if (isStepperMode()) {\n              <div class=\"settings-row\">\n                <label>\n                  <input type=\"checkbox\" [ngModel]=\"stepperShowSummary()\" (ngModelChange)=\"stepperShowSummary.set($event)\" />\n                  Afficher Récapitulatif\n                </label>\n              </div>\n            }\n          </div>\n\n        </div>\n      }\n\n      <!-- ── Preview Tab ──────────────────────────────────── -->\n      @if (activeTab() === 'preview') {\n        <div class=\"preview-view\">\n          @if (isStepperMode()) {\n            @if (stepperIsEmpty()) {\n              <div class=\"empty-canvas\">\n                <mat-icon>preview</mat-icon>\n                <p>Ajoutez des champs pour voir l'aperçu</p>\n              </div>\n            } @else {\n              <div class=\"preview-wrapper\">\n                <p class=\"preview-hint\">\n                  <mat-icon>info_outline</mat-icon>\n                  Aperçu en temps réel — les données ne sont pas envoyées\n                </p>\n                <ngx-stepper-form [config]=\"stepperPreviewConfig()\" />\n              </div>\n            }\n          } @else {\n            @if (fields().length === 0) {\n              <div class=\"empty-canvas\">\n                <mat-icon>preview</mat-icon>\n                <p>Ajoutez des champs pour voir l'aperçu du formulaire</p>\n              </div>\n            } @else {\n              <div class=\"preview-wrapper\">\n                <p class=\"preview-hint\">\n                  <mat-icon>info_outline</mat-icon>\n                  Aperçu en temps réel — les données ne sont pas envoyées\n                </p>\n                <ngx-dynamic-form [config]=\"previewConfig()\" />\n              </div>\n            }\n          }\n        </div>\n      }\n\n    </main>\n\n    <!-- ── Right: Properties ───────────────────────────────── -->\n    <aside class=\"properties\">\n\n      @if (selectedField(); as field) {\n        <div class=\"props-header\">\n          <mat-icon>{{ getIcon(field.type) }}</mat-icon>\n          <span>{{ labelOf(field.type) }}</span>\n          <button class=\"props-close\" (click)=\"selectedIdx.set(null)\">\n            <mat-icon>close</mat-icon>\n          </button>\n        </div>\n\n        <div class=\"props-body\">\n\n          <!-- ── GÉNÉRAL ─────────────────────────────────── -->\n          <section class=\"prop-section\">\n            <p class=\"prop-section-title\">Général</p>\n\n            <div class=\"prop-row\">\n              <label>Clé (key)</label>\n              <input [ngModel]=\"field.key\" (ngModelChange)=\"updateProp('key', $event)\" placeholder=\"mon_champ\" />\n            </div>\n\n            <div class=\"prop-row\">\n              <label>Largeur (col)</label>\n              <select [ngModel]=\"field.col ?? 12\" (ngModelChange)=\"updateProp('col', +$event)\">\n                @for (c of colOptions; track c) {\n                  <option [value]=\"c\">{{ c }} / 12</option>\n                }\n              </select>\n            </div>\n\n            @if (!isDivider(field.type) && !isHeading(field.type)) {\n              <div class=\"prop-row\">\n                <label>Label</label>\n                <input [ngModel]=\"field.label\" (ngModelChange)=\"updateProp('label', $event)\" placeholder=\"Libellé du champ\" />\n              </div>\n            }\n\n            @if (isHeading(field.type)) {\n              <div class=\"prop-row\">\n                <label>Texte</label>\n                <input [ngModel]=\"field.text\" (ngModelChange)=\"updateProp('text', $event)\" placeholder=\"Titre de section\" />\n              </div>\n              <div class=\"prop-row\">\n                <label>Niveau (h1–h6)</label>\n                <select [ngModel]=\"field.level ?? 3\" (ngModelChange)=\"updateProp('level', +$event)\">\n                  @for (n of [1,2,3,4,5,6]; track n) {\n                    <option [value]=\"n\">h{{ n }}</option>\n                  }\n                </select>\n              </div>\n            }\n\n            @if (isDivider(field.type)) {\n              <div class=\"prop-row\">\n                <label>Couleur</label>\n                <div style=\"display:flex;gap:8px;align-items:center\">\n                  <input type=\"color\"\n                         [value]=\"field.dividerColor || '#e0e0e0'\"\n                         (input)=\"updateProp('dividerColor', $any($event.target).value)\"\n                         style=\"width:40px;height:32px;padding:2px;border-radius:4px;cursor:pointer\" />\n                  <input type=\"text\" placeholder=\"#e0e0e0\"\n                         [value]=\"field.dividerColor || ''\"\n                         (input)=\"updateProp('dividerColor', $any($event.target).value || undefined)\"\n                         style=\"flex:1\" />\n                </div>\n              </div>\n              <div class=\"prop-row\">\n                <label>Épaisseur</label>\n                <input type=\"text\" placeholder=\"ex: 2px\"\n                       [value]=\"field.dividerHeight || ''\"\n                       (input)=\"updateProp('dividerHeight', $any($event.target).value || undefined)\" />\n              </div>\n              <div class=\"prop-row\">\n                <label>Largeur</label>\n                <input type=\"text\" placeholder=\"ex: 80%\"\n                       [value]=\"field.dividerWidth || ''\"\n                       (input)=\"updateProp('dividerWidth', $any($event.target).value || undefined)\" />\n              </div>\n            }\n          </section>\n\n          <!-- ── SAISIE ──────────────────────────────────── -->\n          @if (isInputField(field.type)) {\n            <section class=\"prop-section\">\n              <p class=\"prop-section-title\">Saisie</p>\n\n              <div class=\"prop-row\">\n                <label>Placeholder</label>\n                <input [ngModel]=\"field.placeholder\" (ngModelChange)=\"updateProp('placeholder', $event)\" placeholder=\"Texte indicatif\" />\n              </div>\n\n              <div class=\"prop-row\">\n                <label>Texte d'aide (hint)</label>\n                <input [ngModel]=\"field.hint\" (ngModelChange)=\"updateProp('hint', $event)\" placeholder=\"Aide visible sous le champ\" />\n              </div>\n\n              @if (needsRows(field.type)) {\n                <div class=\"prop-row\">\n                  <label>Lignes (rows)</label>\n                  <input type=\"number\" min=\"2\" max=\"20\" [ngModel]=\"field.rows ?? 4\" (ngModelChange)=\"updateProp('rows', +$event)\" />\n                </div>\n              }\n\n              <div class=\"prop-row\">\n                <label>\n                  <input type=\"checkbox\" [ngModel]=\"field.readonly ?? false\" (ngModelChange)=\"updateProp('readonly', $event)\" />\n                  Lecture seule (readonly)\n                </label>\n              </div>\n\n              <div class=\"prop-row\">\n                <label>\n                  <input type=\"checkbox\" [ngModel]=\"field.disabled ?? false\" (ngModelChange)=\"updateProp('disabled', $event)\" />\n                  Désactivé (disabled)\n                </label>\n              </div>\n\n              <div class=\"prop-row\">\n                <label>\n                  <input type=\"checkbox\" [ngModel]=\"field.hidden ?? false\" (ngModelChange)=\"updateProp('hidden', $event)\" />\n                  Masqué (hidden)\n                </label>\n              </div>\n\n              <div class=\"prop-row\">\n                <label>Valeur par défaut <span class=\"prop-hint\">defaultValue</span></label>\n                <input [ngModel]=\"field.defaultValue ?? ''\" (ngModelChange)=\"updateProp('defaultValue', $event || undefined)\" placeholder=\"ex: 5, Dakar, true\" />\n              </div>\n\n              <div class=\"prop-row\">\n                <label>Copier depuis <span class=\"prop-hint\">copyFrom</span></label>\n                <select [ngModel]=\"field.copyFrom ?? ''\" (ngModelChange)=\"updateProp('copyFrom', $event || undefined)\">\n                  <option value=\"\">— aucun —</option>\n                  @for (k of allFieldKeysExcludingCurrent(); track k) {\n                    <option [value]=\"k\">{{ k }}</option>\n                  }\n                </select>\n              </div>\n\n              @if (field.type === 'number') {\n                <div class=\"prop-row\">\n                  <label>\n                    <input type=\"checkbox\" [ngModel]=\"!!field.thousandSeparator\" (ngModelChange)=\"updateProp('thousandSeparator', $event || undefined)\" />\n                    Séparateur de milliers <span class=\"prop-hint\">20 000 au lieu de 20000</span>\n                  </label>\n                </div>\n              }\n\n              @if (['text','tel','number','email','url','password'].includes(field.type)) {\n                <div class=\"prop-row\">\n                  <label>Préfixe texte</label>\n                  <input [ngModel]=\"field.prefix ?? ''\" (ngModelChange)=\"updateProp('prefix', $event || undefined)\" placeholder=\"ex: +221, €\" />\n                </div>\n                <div class=\"prop-row\">\n                  <label>Suffixe texte</label>\n                  <input [ngModel]=\"field.suffix ?? ''\" (ngModelChange)=\"updateProp('suffix', $event || undefined)\" placeholder=\"ex: kg, FCFA, %\" />\n                </div>\n                <div class=\"prop-row\">\n                  <label>Masque de saisie</label>\n                  <select [ngModel]=\"getMaskPresetValue()\" (ngModelChange)=\"setMaskPreset($event)\">\n                    @for (p of maskPresets; track p.value) {\n                      <option [value]=\"p.value\">{{ p.label }}</option>\n                    }\n                  </select>\n                </div>\n                @if (isCustomMask()) {\n                  <div class=\"prop-row\">\n                    <label>Masque personnalisé <span class=\"prop-hint\"># = chiffre</span></label>\n                    <input [ngModel]=\"field.mask ?? ''\" (ngModelChange)=\"updateProp('mask', $event || undefined)\" placeholder=\"ex: ##/##/####\" />\n                  </div>\n                }\n              }\n            </section>\n\n            <!-- ── ICÔNES ──────────────────────────────── -->\n            <section class=\"prop-section\">\n              <p class=\"prop-section-title\">Icônes <span class=\"prop-hint\">Material Icons</span></p>\n              <div class=\"prop-row\">\n                <label>Préfixe (gauche)</label>\n                <div class=\"icon-select-row\">\n                  @if (field.icon) {\n                    <mat-icon class=\"icon-preview\">{{ field.icon }}</mat-icon>\n                  }\n                  <select [ngModel]=\"field.icon ?? ''\" (ngModelChange)=\"updateProp('icon', $event || undefined)\">\n                    @for (opt of iconOptions; track opt.value) {\n                      <option [value]=\"opt.value\">{{ opt.label }}</option>\n                    }\n                  </select>\n                </div>\n              </div>\n              <div class=\"prop-row\">\n                <label>Suffixe (droite)</label>\n                <div class=\"icon-select-row\">\n                  @if (field.iconSuffix) {\n                    <mat-icon class=\"icon-preview\">{{ field.iconSuffix }}</mat-icon>\n                  }\n                  <select [ngModel]=\"field.iconSuffix ?? ''\" (ngModelChange)=\"updateProp('iconSuffix', $event || undefined)\">\n                    @for (opt of iconOptions; track opt.value) {\n                      <option [value]=\"opt.value\">{{ opt.label }}</option>\n                    }\n                  </select>\n                </div>\n              </div>\n            </section>\n\n            <!-- ── STYLE ──────────────────────────────── -->\n            <section class=\"prop-section\">\n              <p class=\"prop-section-title\">Style & Apparence</p>\n\n              <!-- Couleurs -->\n              <div class=\"prop-row\">\n                <label>Couleur du texte</label>\n                <div class=\"color-row\">\n                  <input type=\"color\" [ngModel]=\"field.color || '#000000'\"\n                    (ngModelChange)=\"updateProp('color', $event === '#000000' ? undefined : $event)\" />\n                  <input type=\"text\" [ngModel]=\"field.color ?? ''\"\n                    (ngModelChange)=\"updateProp('color', $event || undefined)\"\n                    placeholder=\"Hériter\" />\n                </div>\n              </div>\n\n              <div class=\"prop-row\">\n                <label>Couleur de fond</label>\n                <div class=\"color-row\">\n                  <input type=\"color\" [ngModel]=\"field.backgroundColor || '#ffffff'\"\n                    (ngModelChange)=\"updateProp('backgroundColor', $event === '#ffffff' ? undefined : $event)\" />\n                  <input type=\"text\" [ngModel]=\"field.backgroundColor ?? ''\"\n                    (ngModelChange)=\"updateProp('backgroundColor', $event || undefined)\"\n                    placeholder=\"Transparent\" />\n                </div>\n              </div>\n\n              <div class=\"prop-row\">\n                <label>Couleur bordure</label>\n                <div class=\"color-row\">\n                  <input type=\"color\" [ngModel]=\"field.borderColor || '#d1d5db'\"\n                    (ngModelChange)=\"updateProp('borderColor', $event === '#d1d5db' ? undefined : $event)\" />\n                  <input type=\"text\" [ngModel]=\"field.borderColor ?? ''\"\n                    (ngModelChange)=\"updateProp('borderColor', $event || undefined)\"\n                    placeholder=\"Par défaut\" />\n                </div>\n              </div>\n\n              <div class=\"prop-row\">\n                <label>Couleur label</label>\n                <div class=\"color-row\">\n                  <input type=\"color\" [ngModel]=\"field.labelColor || '#374151'\"\n                    (ngModelChange)=\"updateProp('labelColor', $event === '#374151' ? undefined : $event)\" />\n                  <input type=\"text\" [ngModel]=\"field.labelColor ?? ''\"\n                    (ngModelChange)=\"updateProp('labelColor', $event || undefined)\"\n                    placeholder=\"Par défaut\" />\n                </div>\n              </div>\n\n              <!-- Apparence champ individuel -->\n              <div class=\"prop-row\">\n                <label>Style <span class=\"prop-hint\">override</span></label>\n                <select [ngModel]=\"field.appearance ?? ''\" (ngModelChange)=\"updateProp('appearance', $event || undefined)\">\n                  <option value=\"\">— Global ({{ formAppearance() }}) —</option>\n                  <option value=\"outline\">Outline</option>\n                  <option value=\"fill\">Fill</option>\n                  <option value=\"simple\">Simple</option>\n                </select>\n              </div>\n\n              <div class=\"prop-row\">\n                <label>Label <span class=\"prop-hint\">override</span></label>\n                <select [ngModel]=\"field.floatLabel ?? ''\" (ngModelChange)=\"updateProp('floatLabel', $event || undefined)\">\n                  <option value=\"\">— Global ({{ formFloatLabel() }}) —</option>\n                  <option value=\"auto\">Auto</option>\n                  <option value=\"always\">Toujours en haut</option>\n                </select>\n              </div>\n\n              <!-- Typographie -->\n              <div class=\"prop-row\">\n                <label>Taille police</label>\n                <input [ngModel]=\"field.fontSize ?? ''\"\n                  (ngModelChange)=\"updateProp('fontSize', $event || undefined)\"\n                  placeholder=\"ex: 14px, 1rem\" />\n              </div>\n\n              <div class=\"prop-row\">\n                <label>Mise en forme</label>\n                <div class=\"format-toggle\">\n                  <button [class.active]=\"field.fontWeight === 'bold'\"\n                    (click)=\"updateProp('fontWeight', field.fontWeight === 'bold' ? undefined : 'bold')\"\n                    title=\"Gras\">\n                    <strong>B</strong>\n                  </button>\n                  <button [class.active]=\"field.fontStyle === 'italic'\"\n                    (click)=\"updateProp('fontStyle', field.fontStyle === 'italic' ? undefined : 'italic')\"\n                    title=\"Italique\">\n                    <em>I</em>\n                  </button>\n                </div>\n              </div>\n\n              <!-- Alignement -->\n              <div class=\"prop-row\">\n                <label>Alignement</label>\n                <div class=\"align-toggle\">\n                  <button [class.active]=\"field.textAlign === 'left'\"\n                    (click)=\"updateProp('textAlign', field.textAlign === 'left' ? undefined : 'left')\"\n                    title=\"Gauche\">\n                    <mat-icon>format_align_left</mat-icon>\n                  </button>\n                  <button [class.active]=\"field.textAlign === 'center'\"\n                    (click)=\"updateProp('textAlign', field.textAlign === 'center' ? undefined : 'center')\"\n                    title=\"Centre\">\n                    <mat-icon>format_align_center</mat-icon>\n                  </button>\n                  <button [class.active]=\"field.textAlign === 'right'\"\n                    (click)=\"updateProp('textAlign', field.textAlign === 'right' ? undefined : 'right')\"\n                    title=\"Droite\">\n                    <mat-icon>format_align_right</mat-icon>\n                  </button>\n                </div>\n              </div>\n\n              <!-- Classe CSS & Styles inline -->\n              <div class=\"prop-row\">\n                <label>Classe CSS <span class=\"prop-hint\">cssClass</span></label>\n                <input [ngModel]=\"field.cssClass ?? ''\"\n                  (ngModelChange)=\"updateProp('cssClass', $event || undefined)\"\n                  placeholder=\"ex: my-field highlight\" />\n              </div>\n\n              <div class=\"prop-row\">\n                <label>Styles inline <span class=\"prop-hint\">CSS</span></label>\n                <input [ngModel]=\"getStylesText()\"\n                  (ngModelChange)=\"setStylesText($event)\"\n                  placeholder=\"ex: border-radius: 8px; opacity: 0.9\" />\n              </div>\n\n            </section>\n\n            <!-- ── VALIDATION ─────────────────────────── -->\n            <section class=\"prop-section\">\n              <p class=\"prop-section-title\">Validation</p>\n\n              <div class=\"prop-row\">\n                <label>\n                  <input type=\"checkbox\" [ngModel]=\"!!field.validation?.required\" (ngModelChange)=\"updateValidation('required', $event)\" />\n                  Champ obligatoire (required)\n                </label>\n              </div>\n\n              @if (['text','email','password','textarea','url'].includes(field.type)) {\n                <div class=\"prop-row\">\n                  <label>Longueur min</label>\n                  <input type=\"number\" min=\"0\"\n                    [ngModel]=\"field.validation?.minLength ?? ''\"\n                    (ngModelChange)=\"updateValidation('minLength', $event ? +$event : null)\"\n                    placeholder=\"–\" />\n                </div>\n                <div class=\"prop-row\">\n                  <label>Longueur max</label>\n                  <input type=\"number\" min=\"0\"\n                    [ngModel]=\"field.validation?.maxLength ?? ''\"\n                    (ngModelChange)=\"updateValidation('maxLength', $event ? +$event : null)\"\n                    placeholder=\"–\" />\n                </div>\n              }\n\n              @if (field.type === 'number') {\n                <div class=\"prop-row\">\n                  <label>Valeur min</label>\n                  <input type=\"number\"\n                    [ngModel]=\"field.validation?.min ?? ''\"\n                    (ngModelChange)=\"updateValidation('min', $event !== '' ? +$event : null)\"\n                    placeholder=\"–\" />\n                </div>\n                <div class=\"prop-row\">\n                  <label>Valeur max</label>\n                  <input type=\"number\"\n                    [ngModel]=\"field.validation?.max ?? ''\"\n                    (ngModelChange)=\"updateValidation('max', $event !== '' ? +$event : null)\"\n                    placeholder=\"–\" />\n                </div>\n              }\n\n              @if (['number','date','datetime-local','month','week','time'].includes(field.type)) {\n                <div class=\"prop-row\">\n                  <label>Max basé sur champ <span class=\"prop-hint\">maxField</span></label>\n                  <select [ngModel]=\"field.validation?.maxField ?? ''\"\n                          (ngModelChange)=\"updateValidation('maxField', $event || undefined)\">\n                    <option value=\"\">— aucun —</option>\n                    @for (k of allFieldKeysExcludingCurrent(); track k) {\n                      <option [value]=\"k\">{{ k }}</option>\n                    }\n                  </select>\n                </div>\n                <div class=\"prop-row\">\n                  <label>Min basé sur champ <span class=\"prop-hint\">minField</span></label>\n                  <select [ngModel]=\"field.validation?.minField ?? ''\"\n                          (ngModelChange)=\"updateValidation('minField', $event || undefined)\">\n                    <option value=\"\">— aucun —</option>\n                    @for (k of allFieldKeysExcludingCurrent(); track k) {\n                      <option [value]=\"k\">{{ k }}</option>\n                    }\n                  </select>\n                  @if (field.type !== 'number') {\n                    <p class=\"prop-hint-block\">\n                      Période : sur la date de début, <code>maxField</code> = date de fin ;\n                      sur la date de fin, <code>minField</code> = date de début.\n                    </p>\n                  }\n                </div>\n              }\n\n              @if (['date','datetime-local','month','week'].includes(field.type)) {\n                <div class=\"prop-row\">\n                  <label>Date min <span class=\"prop-hint\">'today' ou ISO</span></label>\n                  <input [ngModel]=\"field.minDate ?? ''\" (ngModelChange)=\"updateProp('minDate', $event || undefined)\" placeholder=\"ex: today ou 2026-01-01\" />\n                </div>\n                <div class=\"prop-row\">\n                  <label>Date max <span class=\"prop-hint\">'today' ou ISO</span></label>\n                  <input [ngModel]=\"field.maxDate ?? ''\" (ngModelChange)=\"updateProp('maxDate', $event || undefined)\" placeholder=\"ex: today ou 2099-12-31\" />\n                </div>\n              }\n\n              @if (field.type === 'date') {\n                <div class=\"prop-row\">\n                  <label>Locale <span class=\"prop-hint\">format d'affichage</span></label>\n                  <input [ngModel]=\"field.dateLocale ?? ''\" (ngModelChange)=\"updateProp('dateLocale', $event || undefined)\" placeholder=\"fr-FR par défaut (25/08/2026)\" />\n                </div>\n              }\n\n              @if (field.type === 'email') {\n                <div class=\"prop-row\">\n                  <label>\n                    <input type=\"checkbox\" [ngModel]=\"!!field.validation?.email\" (ngModelChange)=\"updateValidation('email', $event)\" />\n                    Valider le format e-mail\n                  </label>\n                </div>\n              }\n\n              @if (field.type === 'file') {\n                <div class=\"prop-row\">\n                  <label>Types acceptés</label>\n                  <input [ngModel]=\"field.accept\" (ngModelChange)=\"updateProp('accept', $event)\" placeholder=\".pdf,.docx,image/*\" />\n                </div>\n                <div class=\"prop-row\">\n                  <label>\n                    <input type=\"checkbox\" [ngModel]=\"field.multiple ?? false\" (ngModelChange)=\"updateProp('multiple', $event)\" />\n                    Fichiers multiples\n                  </label>\n                </div>\n              }\n\n              @if (field.type === 'range') {\n                <div class=\"prop-row\">\n                  <label>Valeur min</label>\n                  <input type=\"number\" [ngModel]=\"field.min ?? 0\" (ngModelChange)=\"updateProp('min', +$event)\" />\n                </div>\n                <div class=\"prop-row\">\n                  <label>Valeur max</label>\n                  <input type=\"number\" [ngModel]=\"field.max ?? 100\" (ngModelChange)=\"updateProp('max', +$event)\" />\n                </div>\n                <div class=\"prop-row\">\n                  <label>Pas (step)</label>\n                  <input type=\"number\" [ngModel]=\"field.step ?? 1\" (ngModelChange)=\"updateProp('step', +$event)\" />\n                </div>\n                <div class=\"prop-row\">\n                  <label>\n                    <input type=\"checkbox\" [ngModel]=\"field.showValue !== false\" (ngModelChange)=\"updateProp('showValue', $event)\" />\n                    Afficher la valeur\n                  </label>\n                </div>\n              }\n\n              <!-- Pattern -->\n              @if (!['checkbox','switch','radio','select','multiselect','range','color','file'].includes(field.type)) {\n                <div class=\"prop-row\">\n                  <label>Pattern (regex)</label>\n                  <input [ngModel]=\"field.validation?.pattern?.toString() ?? ''\"\n                         (ngModelChange)=\"setPattern($event)\"\n                         placeholder=\"ex: ^[0-9]+$\" />\n                </div>\n                <div class=\"prop-row preset-chips-row\">\n                  <label>Présets</label>\n                  <div class=\"preset-chips\">\n                    <button type=\"button\" class=\"chip-btn\" (click)=\"setPattern('^[\\\\w.+\\\\-]+@[a-zA-Z0-9.\\\\-]+\\\\.[a-zA-Z]{2,}$')\">Email</button>\n                    <button type=\"button\" class=\"chip-btn\" (click)=\"setPattern('^[a-zA-Z0-9]+$')\">Alphanum</button>\n                    <button type=\"button\" class=\"chip-btn\" (click)=\"setPattern('^[0-9]+$')\">Numérique</button>\n                  </div>\n                </div>\n                <div class=\"prop-row\">\n                  <label>Message d'erreur pattern</label>\n                  <input [ngModel]=\"field.validation?.messages?.pattern ?? ''\"\n                         (ngModelChange)=\"updateValidationMessage('pattern', $event)\"\n                         placeholder=\"Format invalide.\" />\n                </div>\n              }\n            </section>\n          }\n\n          <!-- ── TÉLÉPHONE ──────────────────────────────── -->\n          @if (field.type === 'phone') {\n            <section class=\"prop-section\">\n              <p class=\"prop-section-title\">Téléphone</p>\n              <div class=\"prop-row\">\n                <label>Pays par défaut</label>\n                <select [ngModel]=\"field.defaultCountry ?? 'FR'\" (ngModelChange)=\"updateProp('defaultCountry', $event)\">\n                  @for (c of phoneCountries; track c.code) {\n                    <option [value]=\"c.code\">{{ c.flag }} {{ c.name }} ({{ c.dialCode }})</option>\n                  }\n                </select>\n              </div>\n            </section>\n          }\n\n          <!-- ── OPTIONS (select / radio) ───────────────── -->\n          @if (hasOptions(field.type)) {\n            <section class=\"prop-section\">\n              <p class=\"prop-section-title\">Options</p>\n\n              <!-- Toggle source -->\n              <div class=\"options-source-toggle\">\n                <button [class.active]=\"field.url === undefined\" (click)=\"setOptionsSource(false)\">\n                  <mat-icon>list</mat-icon> Statiques\n                </button>\n                <button [class.active]=\"field.url !== undefined\" (click)=\"setOptionsSource(true)\">\n                  <mat-icon>cloud_download</mat-icon> Depuis une API\n                </button>\n              </div>\n\n              <!-- Options statiques -->\n              @if (field.url === undefined) {\n                <!-- Liste filtrée selon un autre champ : chaque option n'est proposée que si ce\n                     champ vaut sa valeur « dependsOnValue » (ex: Durée selon Périodicité). -->\n                <div class=\"prop-row\">\n                  <label>Dépend de <span class=\"prop-hint\">dependsOn</span></label>\n                  <select [ngModel]=\"field.dependsOn ?? ''\" (ngModelChange)=\"updateProp('dependsOn', $event || undefined)\">\n                    <option value=\"\">— aucun —</option>\n                    @for (k of allFieldKeysExcludingCurrent(); track k) {\n                      <option [value]=\"k\">{{ k }}</option>\n                    }\n                  </select>\n                </div>\n                @if (field.dependsOn) {\n                  <p class=\"prop-hint-block\">\n                    Pour chaque option, indiquez la valeur de « {{ field.dependsOn }} » pour laquelle elle est proposée.\n                  </p>\n                }\n                <div class=\"options-list\">\n                  @for (opt of getOptions(); track trackByIdx($index); let oi = $index) {\n                    <div class=\"option-row\">\n                      <input placeholder=\"Label\" [ngModel]=\"opt.label\" (ngModelChange)=\"updateOption(oi, 'label', $event)\" />\n                      <input placeholder=\"Valeur\" [ngModel]=\"opt.value\" (ngModelChange)=\"updateOption(oi, 'value', $event)\" />\n                      @if (field.dependsOn) {\n                        @if (parentStaticOptions().length) {\n                          <select\n                            class=\"option-depend\"\n                            [ngModel]=\"opt.dependsOnValue ?? ''\"\n                            (ngModelChange)=\"updateOption(oi, 'dependsOnValue', $event)\"\n                            [attr.aria-label]=\"'Si ' + field.dependsOn + ' ='\">\n                            <option value=\"\">Si {{ field.dependsOn }} =</option>\n                            @for (p of parentStaticOptions(); track $index) {\n                              <option [value]=\"p.value\">{{ p.label }}</option>\n                            }\n                          </select>\n                        } @else {\n                          <input\n                            class=\"option-depend\"\n                            [placeholder]=\"'Si ' + field.dependsOn + ' ='\"\n                            [ngModel]=\"opt.dependsOnValue ?? ''\"\n                            (ngModelChange)=\"updateOption(oi, 'dependsOnValue', $event)\" />\n                        }\n                      }\n                      <button class=\"action-btn danger\" (click)=\"removeOption(oi)\">\n                        <mat-icon>close</mat-icon>\n                      </button>\n                    </div>\n                  }\n                </div>\n                <button class=\"btn-add-option\" (click)=\"addOption()\">\n                  <mat-icon>add</mat-icon> Ajouter une option\n                </button>\n              }\n\n              <!-- Options depuis une API -->\n              @if (field.url !== undefined) {\n                <div class=\"api-options\">\n                  <div class=\"prop-row\">\n                    <label>URL de l'endpoint</label>\n                    <input\n                      [ngModel]=\"field.url\"\n                      (ngModelChange)=\"updateProp('url', $event)\"\n                      placeholder=\"ex: http://mon-service/api/villes\" />\n                    <p class=\"prop-hint-block\">\n                      URL complète recommandée (microservices). Chemin relatif possible si <code>dataUrl</code> est configuré globalement.\n                    </p>\n                  </div>\n                  <div class=\"prop-row\">\n                    <label>\n                      Propriété label\n                      <span class=\"prop-hint\">displayName</span>\n                    </label>\n                    <input\n                      [ngModel]=\"field.displayName ?? 'label'\"\n                      (ngModelChange)=\"updateProp('displayName', $event)\"\n                      placeholder=\"label\" />\n                    <p class=\"prop-hint-block\">\n                      Clé, chemin pointé (<code>personnePhysique.nom</code>) ou concaténation :\n                      <code ngNonBindable>{{codeClient}} - {{telephone}}</code>\n                    </p>\n                  </div>\n                  <div class=\"prop-row\">\n                    <label>\n                      Propriété valeur\n                      <span class=\"prop-hint\">displayValue</span>\n                    </label>\n                    <input\n                      [ngModel]=\"field.displayValue ?? 'value'\"\n                      (ngModelChange)=\"updateProp('displayValue', $event)\"\n                      placeholder=\"value\" />\n                  </div>\n                  <div class=\"prop-row\">\n                    <label>Clé données réponse <span class=\"prop-hint\">responseDataKey</span></label>\n                    <input\n                      [ngModel]=\"field.responseDataKey ?? ''\"\n                      (ngModelChange)=\"updateProp('responseDataKey', $event || undefined)\"\n                      placeholder=\"ex: data, results, items\" />\n                  </div>\n                  <div class=\"prop-row\">\n                    <label>Dépend de <span class=\"prop-hint\">dependsOn</span></label>\n                    <select [ngModel]=\"field.dependsOn ?? ''\" (ngModelChange)=\"updateProp('dependsOn', $event || undefined)\">\n                      <option value=\"\">— aucun —</option>\n                      @for (k of allFieldKeysExcludingCurrent(); track k) {\n                        <option [value]=\"k\">{{ k }}</option>\n                      }\n                    </select>\n                  </div>\n                  @if (field.dependsOn) {\n                    <div class=\"prop-row\">\n                      <label>Mode <span class=\"prop-hint\">dependsOnMode</span></label>\n                      <select [ngModel]=\"field.dependsOnMode ?? 'server'\" (ngModelChange)=\"updateProp('dependsOnMode', $event)\">\n                        <option value=\"server\">server (filtre API)</option>\n                        <option value=\"client\">client (filtre local)</option>\n                      </select>\n                    </div>\n                    <div class=\"prop-row\">\n                      <label>Clé de filtre <span class=\"prop-hint\">dependsOnItemKey</span></label>\n                      <input [ngModel]=\"field.dependsOnItemKey ?? ''\" (ngModelChange)=\"updateProp('dependsOnItemKey', $event || undefined)\" placeholder=\"ex: regionId\" />\n                    </div>\n                    <div class=\"prop-row\">\n                      <label>Décalage index <span class=\"prop-hint\">dependsOnOffset</span></label>\n                      <input type=\"number\" [ngModel]=\"field.dependsOnOffset ?? ''\" (ngModelChange)=\"updateProp('dependsOnOffset', $event !== '' ? +$event : undefined)\" placeholder=\"0\" />\n                    </div>\n                  }\n\n                  @if (field.type === 'select') {\n                    <div class=\"prop-row\">\n                      <label>\n                        <input type=\"checkbox\"\n                          [ngModel]=\"!!field.remoteSearch\"\n                          (ngModelChange)=\"updateProp('remoteSearch', $event ? { minChars: 3 } : undefined)\" />\n                        Recherche à distance <span class=\"prop-hint\">remoteSearch — au lieu de tout charger, interroge l'URL pendant la frappe</span>\n                      </label>\n                    </div>\n                    @if (field.remoteSearch) {\n                      <div class=\"prop-row\">\n                        <label>Nom du paramètre <span class=\"prop-hint\">paramName</span></label>\n                        <input\n                          [ngModel]=\"field.remoteSearch.paramName ?? 'q'\"\n                          (ngModelChange)=\"updateRemoteSearch('paramName', $event || undefined)\"\n                          placeholder=\"q\" />\n                      </div>\n                      <div class=\"prop-row\">\n                        <label>Caractères minimum <span class=\"prop-hint\">minChars</span></label>\n                        <input type=\"number\"\n                          [ngModel]=\"field.remoteSearch.minChars ?? 3\"\n                          (ngModelChange)=\"updateRemoteSearch('minChars', $event !== '' ? +$event : undefined)\"\n                          placeholder=\"3\" />\n                      </div>\n                      <div class=\"prop-row\">\n                        <label>Délai (ms) <span class=\"prop-hint\">debounceMs</span></label>\n                        <input type=\"number\"\n                          [ngModel]=\"field.remoteSearch.debounceMs ?? 300\"\n                          (ngModelChange)=\"updateRemoteSearch('debounceMs', $event !== '' ? +$event : undefined)\"\n                          placeholder=\"300\" />\n                      </div>\n                    }\n                  }\n\n                  <!-- Filtre des items reçus de l'API (ex: ne garder que status === 'ACTIF') -->\n                  <div class=\"prop-row prop-row-header\">\n                    <span class=\"prop-section-subtitle\">Filtrer les résultats <span class=\"prop-hint\">optionsFilter</span></span>\n                  </div>\n\n                  @if (getOptionsFilterConditions().length > 1) {\n                    <div class=\"prop-row\">\n                      <label>Logique</label>\n                      <div class=\"logic-toggle\">\n                        <button type=\"button\"\n                          [class.active]=\"(selectedField()?.optionsFilterLogic ?? 'AND') === 'AND'\"\n                          (click)=\"setOptionsFilterLogic('AND')\">ET</button>\n                        <button type=\"button\"\n                          [class.active]=\"selectedField()?.optionsFilterLogic === 'OR'\"\n                          (click)=\"setOptionsFilterLogic('OR')\">OU</button>\n                      </div>\n                    </div>\n                  }\n\n                  @for (cond of getOptionsFilterConditions(); track $index; let ci = $index) {\n                    <div class=\"condition-row\">\n                      <input [ngModel]=\"cond.field\"\n                        (ngModelChange)=\"updateOptionsFilterCondition(ci, 'field', $event)\"\n                        placeholder=\"ex: status\" />\n                      <select [ngModel]=\"cond.operator\" (ngModelChange)=\"updateOptionsFilterCondition(ci, 'operator', $event)\">\n                        <option value=\"equals\">= égal</option>\n                        <option value=\"notEquals\">≠ différent</option>\n                        <option value=\"contains\">contient</option>\n                        <option value=\"greaterThan\">&gt; supérieur</option>\n                        <option value=\"lessThan\">&lt; inférieur</option>\n                        <option value=\"exists\">existe</option>\n                        <option value=\"notExists\">n'existe pas</option>\n                      </select>\n                      @if (!['exists','notExists'].includes(cond.operator)) {\n                        <input [ngModel]=\"cond.value ?? ''\"\n                               (ngModelChange)=\"updateOptionsFilterCondition(ci, 'value', $event)\"\n                               placeholder=\"ex: ACTIF\" />\n                      }\n                      <button type=\"button\" class=\"action-btn danger\" (click)=\"removeOptionsFilterCondition(ci)\">\n                        <mat-icon>close</mat-icon>\n                      </button>\n                    </div>\n                  }\n\n                  <button type=\"button\" class=\"btn-add-option\" (click)=\"addOptionsFilterCondition()\">\n                    <mat-icon>add</mat-icon> Ajouter une condition de filtre\n                  </button>\n                </div>\n              }\n\n            </section>\n          }\n\n          <!-- ── AFFICHAGE CONDITIONNEL ──────────────────── -->\n          @if (isInputField(field.type)) {\n            <section class=\"prop-section\">\n              <p class=\"prop-section-title\">Afficher quand</p>\n\n              @if (getConditions().length > 1) {\n                <div class=\"prop-row\">\n                  <label>Logique</label>\n                  <div class=\"logic-toggle\">\n                    <button type=\"button\"\n                      [class.active]=\"(selectedField()?.conditionLogic ?? 'AND') === 'AND'\"\n                      (click)=\"setConditionLogic('AND')\">ET</button>\n                    <button type=\"button\"\n                      [class.active]=\"selectedField()?.conditionLogic === 'OR'\"\n                      (click)=\"setConditionLogic('OR')\">OU</button>\n                  </div>\n                </div>\n              }\n\n              @for (cond of getConditions(); track $index; let ci = $index) {\n                <div class=\"condition-row\">\n                  <select [ngModel]=\"cond.field\" (ngModelChange)=\"updateCondition(ci, 'field', $event)\">\n                    <option value=\"\">— champ —</option>\n                    @for (k of allFieldKeysExcludingCurrent(); track k) {\n                      <option [value]=\"k\">{{ k }}</option>\n                    }\n                  </select>\n                  <select [ngModel]=\"cond.operator\" (ngModelChange)=\"updateCondition(ci, 'operator', $event)\">\n                    <option value=\"equals\">= égal</option>\n                    <option value=\"notEquals\">≠ différent</option>\n                    <option value=\"contains\">contient</option>\n                    <option value=\"greaterThan\">&gt; supérieur</option>\n                    <option value=\"lessThan\">&lt; inférieur</option>\n                    <option value=\"exists\">existe</option>\n                    <option value=\"notExists\">n'existe pas</option>\n                  </select>\n                  @if (!['exists','notExists'].includes(cond.operator)) {\n                    <input [ngModel]=\"cond.value ?? ''\"\n                           (ngModelChange)=\"updateCondition(ci, 'value', $event)\"\n                           placeholder=\"valeur\" />\n                  }\n                  <button type=\"button\" class=\"action-btn danger\" (click)=\"removeCondition(ci)\">\n                    <mat-icon>close</mat-icon>\n                  </button>\n                </div>\n              }\n\n              <button type=\"button\" class=\"btn-add-option\" (click)=\"addCondition()\">\n                <mat-icon>add</mat-icon> Ajouter une condition\n              </button>\n            </section>\n          }\n\n          <!-- ── UNICITÉ API ─────────────────────────────── -->\n          @if (isInputField(field.type) && !['checkbox','switch','radio','select','multiselect','range','color','file'].includes(field.type)) {\n            <section class=\"prop-section\">\n              <p class=\"prop-section-title\">Vérification d'unicité</p>\n\n              <div class=\"prop-row\">\n                <label>\n                  <input type=\"checkbox\"\n                    [ngModel]=\"!!selectedField()?.uniqueCheck\"\n                    (ngModelChange)=\"toggleUniqueCheck($event)\" />\n                  Activer\n                </label>\n              </div>\n\n              @if (selectedField()?.uniqueCheck) {\n                <div class=\"prop-row\">\n                  <label>URL de vérification</label>\n                  <input\n                    [ngModel]=\"selectedField()?.uniqueCheck?.url ?? ''\"\n                    (ngModelChange)=\"setUniqueCheckProp('url', $event)\"\n                    placeholder=\"https://api.example.com/check-email\" />\n                </div>\n                <div class=\"prop-row\">\n                  <label>Message d'erreur</label>\n                  <input\n                    [ngModel]=\"selectedField()?.uniqueCheck?.message ?? ''\"\n                    (ngModelChange)=\"setUniqueCheckProp('message', $event)\"\n                    placeholder=\"Cette valeur existe déjà.\" />\n                </div>\n              }\n            </section>\n          }\n\n          <!-- ── LOOKUP (auto-remplissage) ──────────────── -->\n          @if (isInputField(field.type)) {\n            <section class=\"prop-section\">\n              <p class=\"prop-section-title\">Auto-remplissage <span class=\"prop-hint\">lookup</span></p>\n\n              <div class=\"prop-row\">\n                <label>\n                  <input type=\"checkbox\"\n                    [ngModel]=\"!!selectedField()?.lookup\"\n                    (ngModelChange)=\"toggleLookup($event)\" />\n                  Activer\n                </label>\n              </div>\n\n              @if (selectedField()?.lookup) {\n                <div class=\"prop-row\">\n                  <label>URL de l'endpoint</label>\n                  <input\n                    [ngModel]=\"selectedField()?.lookup?.url ?? ''\"\n                    (ngModelChange)=\"setLookupUrl($event)\"\n                    placeholder=\"ex: /api/check?telephone=valeur\" />\n                  <p class=\"prop-hint-block\">Entourez la clé d'un autre champ d'accolades doubles pour interpoler sa valeur dans l'URL.</p>\n                </div>\n                <div class=\"prop-row\">\n                  <label>Méthode</label>\n                  <select [ngModel]=\"selectedField()?.lookup?.method ?? 'GET'\" (ngModelChange)=\"setLookupMethod($event)\">\n                    <option value=\"GET\">GET</option>\n                    <option value=\"POST\">POST</option>\n                  </select>\n                </div>\n                <div class=\"prop-row\">\n                  <label>Populate <span class=\"prop-hint\">champ=chemin</span></label>\n                  <textarea\n                    rows=\"4\"\n                    [ngModel]=\"getLookupPopulateText()\"\n                    (ngModelChange)=\"setLookupPopulateText($event)\"\n                    placeholder=\"prenom=data.prenom&#10;email=data.email&#10;typeCode=data.typeCode\"></textarea>\n                  <p class=\"prop-hint-block\">Un mapping par ligne : <code>champCible=chemin.pointé</code></p>\n                </div>\n                <div class=\"prop-row\">\n                  <label>Déclencheur <span class=\"prop-hint\">triggerOn</span></label>\n                  <select [ngModel]=\"selectedField()?.lookup?.triggerOn ?? 'blur'\" (ngModelChange)=\"setLookupTriggerOn($event)\">\n                    <option value=\"blur\">blur (perte de focus)</option>\n                    <option value=\"change\">change (à chaque frappe)</option>\n                  </select>\n                </div>\n              }\n            </section>\n          }\n\n          <!-- ── REQUIRED QUAND ────────────────────────── -->\n          @if (isInputField(field.type)) {\n            <section class=\"prop-section\">\n              <p class=\"prop-section-title\">Requis quand <span class=\"prop-hint\">requiredWhen</span></p>\n\n              @for (cond of getRequiredWhenConditions(); track $index; let ci = $index) {\n                <div class=\"condition-row\">\n                  <select [ngModel]=\"cond.field\" (ngModelChange)=\"updateRequiredWhenCondition(ci, 'field', $event)\">\n                    <option value=\"\">— champ —</option>\n                    @for (k of allFieldKeysExcludingCurrent(); track k) {\n                      <option [value]=\"k\">{{ k }}</option>\n                    }\n                  </select>\n                  <select [ngModel]=\"cond.operator\" (ngModelChange)=\"updateRequiredWhenCondition(ci, 'operator', $event)\">\n                    <option value=\"equals\">= égal</option>\n                    <option value=\"notEquals\">≠ différent</option>\n                    <option value=\"contains\">contient</option>\n                    <option value=\"greaterThan\">&gt; supérieur</option>\n                    <option value=\"lessThan\">&lt; inférieur</option>\n                    <option value=\"exists\">existe</option>\n                    <option value=\"notExists\">n'existe pas</option>\n                  </select>\n                  @if (!['exists','notExists'].includes(cond.operator)) {\n                    <input [ngModel]=\"cond.value ?? ''\"\n                           (ngModelChange)=\"updateRequiredWhenCondition(ci, 'value', $event)\"\n                           placeholder=\"valeur\" />\n                  }\n                  <button type=\"button\" class=\"action-btn danger\" (click)=\"removeRequiredWhenCondition(ci)\">\n                    <mat-icon>close</mat-icon>\n                  </button>\n                </div>\n              }\n\n              <button type=\"button\" class=\"btn-add-option\" (click)=\"addRequiredWhenCondition()\">\n                <mat-icon>add</mat-icon> Ajouter une condition\n              </button>\n            </section>\n          }\n\n        </div>\n\n      } @else {\n        <!-- Paramètres globaux du formulaire (aucun champ sélectionné) -->\n        <div class=\"props-header\">\n          <mat-icon>settings</mat-icon>\n          <span>Paramètres du formulaire</span>\n        </div>\n\n        <div class=\"props-body\">\n\n          <section class=\"prop-section\">\n            <p class=\"prop-section-title\">Boutons</p>\n            <div class=\"prop-row\">\n              <label>Label soumettre</label>\n              <input [ngModel]=\"submitLabel()\" (ngModelChange)=\"submitLabel.set($event)\" placeholder=\"Envoyer\" />\n            </div>\n            <div class=\"prop-row\">\n              <label>\n                <input type=\"checkbox\" [ngModel]=\"showReset()\" (ngModelChange)=\"showReset.set($event)\" />\n                Afficher Réinitialiser\n              </label>\n            </div>\n          </section>\n\n          <section class=\"prop-section\">\n            <p class=\"prop-section-title\">Apparence des champs</p>\n\n            <div class=\"prop-row\">\n              <label>Style des champs</label>\n              <div class=\"appearance-toggle\">\n                <button [class.active]=\"formAppearance() === 'outline'\"\n                  (click)=\"formAppearance.set('outline')\"\n                  title=\"Outline — contour visible\">\n                  <mat-icon>crop_square</mat-icon>\n                  <span>Outline</span>\n                </button>\n                <button [class.active]=\"formAppearance() === 'fill'\"\n                  (click)=\"formAppearance.set('fill')\"\n                  title=\"Fill — fond coloré + soulignement\">\n                  <mat-icon>rectangle</mat-icon>\n                  <span>Fill</span>\n                </button>\n                <button [class.active]=\"formAppearance() === 'simple'\"\n                  (click)=\"formAppearance.set('simple')\"\n                  title=\"Simple — label fixe au-dessus, input borduré\">\n                  <mat-icon>text_fields</mat-icon>\n                  <span>Simple</span>\n                </button>\n              </div>\n            </div>\n\n            <div class=\"appearance-preview\">\n              <div class=\"ap-card\" [class.ap-active]=\"formAppearance() === 'outline'\" (click)=\"formAppearance.set('outline')\">\n                <div class=\"ap-field ap-outline\">\n                  <span class=\"ap-label\">Label</span>\n                </div>\n                <p>Outline</p>\n                <small>Label flottant, contour</small>\n              </div>\n              <div class=\"ap-card\" [class.ap-active]=\"formAppearance() === 'fill'\" (click)=\"formAppearance.set('fill')\">\n                <div class=\"ap-field ap-fill\">\n                  <span class=\"ap-label\">Label</span>\n                </div>\n                <p>Fill</p>\n                <small>Label flottant, fond coloré</small>\n              </div>\n              <div class=\"ap-card\" [class.ap-active]=\"formAppearance() === 'simple'\" (click)=\"formAppearance.set('simple')\">\n                <div class=\"ap-field ap-simple\">\n                  <span class=\"ap-simple-label\">Label</span>\n                  <div class=\"ap-simple-input-preview\"></div>\n                </div>\n                <p>Simple</p>\n                <small>Label fixe au-dessus</small>\n              </div>\n            </div>\n\n            @if (formAppearance() !== 'simple') {\n              <div class=\"prop-row\" style=\"margin-top:.75rem\">\n                <label>Label flottant</label>\n                <select [ngModel]=\"formFloatLabel()\" (ngModelChange)=\"formFloatLabel.set($event)\">\n                  <option value=\"auto\">Auto — flotte quand actif / rempli</option>\n                  <option value=\"always\">Toujours en haut</option>\n                </select>\n              </div>\n            }\n          </section>\n\n          @if (!isStepperMode()) {\n            <section class=\"prop-section\">\n              <p class=\"prop-section-title\">Au moins un obligatoire <span class=\"prop-hint\">atLeastOneOf</span></p>\n              <div class=\"prop-row\">\n                <label>Clés des champs</label>\n                <input\n                  [ngModel]=\"formAtLeastOneOfKeys()\"\n                  (ngModelChange)=\"formAtLeastOneOfKeys.set($event)\"\n                  placeholder=\"ex: email, telephone\" />\n                <p class=\"prop-hint-block\">Clés séparées par des virgules. Laissez vide pour désactiver.</p>\n              </div>\n              @if (formAtLeastOneOfKeys()) {\n                <div class=\"prop-row\">\n                  <label>Message d'erreur</label>\n                  <input\n                    [ngModel]=\"formAtLeastOneOfMsg()\"\n                    (ngModelChange)=\"formAtLeastOneOfMsg.set($event)\"\n                    placeholder=\"Au moins un champ est requis.\" />\n                </div>\n              }\n            </section>\n          }\n\n          @if (isStepperMode()) {\n            <section class=\"prop-section\">\n              <p class=\"prop-section-title\">Stepper</p>\n              <div class=\"prop-row\">\n                <label>\n                  <input type=\"checkbox\" [ngModel]=\"stepperShowSummary()\" (ngModelChange)=\"stepperShowSummary.set($event)\" />\n                  Afficher Récapitulatif\n                </label>\n              </div>\n            </section>\n\n            <section class=\"prop-section\">\n              <p class=\"prop-section-title\">Étape sélectionnée</p>\n              <div class=\"prop-row\">\n                <label>Au moins un <span class=\"prop-hint\">atLeastOneOf</span></label>\n                <input\n                  [ngModel]=\"getStepAtLeastOneOf()\"\n                  (ngModelChange)=\"setStepAtLeastOneOf($event)\"\n                  placeholder=\"ex: email, telephone\" />\n                <p class=\"prop-hint-block\">Clés séparées par des virgules.</p>\n              </div>\n              @if (getStepAtLeastOneOf()) {\n                <div class=\"prop-row\">\n                  <label>Message</label>\n                  <input\n                    [ngModel]=\"steps()[selectedStepIdx()].atLeastOneOfMessage ?? ''\"\n                    (ngModelChange)=\"updateCurrentStep('atLeastOneOfMessage', $event)\"\n                    placeholder=\"Au moins un champ est requis.\" />\n                </div>\n              }\n              <div class=\"prop-row\" style=\"margin-top:.5rem\">\n                <label>\n                  <input type=\"checkbox\"\n                    [ngModel]=\"!!getStepBeforeNext()\"\n                    (ngModelChange)=\"toggleBeforeNext($event)\" />\n                  Guard avant avancement <span class=\"prop-hint\">beforeNext</span>\n                </label>\n              </div>\n              @if (getStepBeforeNext()) {\n                <div class=\"prop-row\">\n                  <label>URL</label>\n                  <input\n                    [ngModel]=\"getStepBeforeNext()?.url ?? ''\"\n                    (ngModelChange)=\"setBeforeNextProp('url', $event)\"\n                    placeholder=\"/api/souscriptions/check\" />\n                </div>\n                <div class=\"prop-row\">\n                  <label>Méthode</label>\n                  <select [ngModel]=\"getStepBeforeNext()?.method ?? 'POST'\" (ngModelChange)=\"setBeforeNextProp('method', $event)\">\n                    <option value=\"POST\">POST</option>\n                    <option value=\"GET\">GET</option>\n                  </select>\n                </div>\n                <div class=\"prop-row\">\n                  <label>Message de fallback</label>\n                  <input\n                    [ngModel]=\"getStepBeforeNext()?.errorMessage ?? ''\"\n                    (ngModelChange)=\"setBeforeNextProp('errorMessage', $event)\"\n                    placeholder=\"Vérification impossible.\" />\n                </div>\n              }\n            </section>\n          }\n\n        </div>\n      }\n\n    </aside>\n\n  </div><!-- /.builder-body -->\n\n</div><!-- /.builder-root -->\n\n<!-- ── Export Modal ─────────────────────────────────────────── -->\n@if (showExport()) {\n  <div class=\"modal-overlay\" (click)=\"showExport.set(false)\">\n    <div class=\"modal\" (click)=\"$event.stopPropagation()\">\n      <div class=\"modal-header\">\n        <span>Code exporté</span>\n        <button (click)=\"showExport.set(false)\"><mat-icon>close</mat-icon></button>\n      </div>\n      <textarea class=\"modal-code\" readonly [value]=\"exportContent()\"></textarea>\n      <div class=\"modal-footer\">\n        <button class=\"btn-primary\" (click)=\"copyExport()\">\n          <mat-icon>content_copy</mat-icon> Copier\n        </button>\n        <button class=\"btn-outline\" (click)=\"showExport.set(false)\">Fermer</button>\n      </div>\n    </div>\n  </div>\n}\n","import { Component, computed, inject, Input, signal } from '@angular/core';\nimport { JsonPipe } from '@angular/common';\nimport { RouterLink } from '@angular/router';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatSnackBar } from '@angular/material/snack-bar';\n\nimport { DynamicFormComponent } from '../dynamic-form/dynamic-form.component';\nimport { StepperFormComponent } from '../stepper-form/stepper-form.component';\nimport { FormConfigService } from '../../services/form-config.service';\nimport type { DynamicFormConfig, StepperFormConfig, DynamicFormSubmitEvent } from '../../models/form-field.model';\nimport type { AnyFormConfig, SavedFormSchema } from '../../models/saved-form.model';\n\n@Component({\n  selector: 'ngx-mes-formulaires',\n  standalone: true,\n  imports: [RouterLink, MatIcon, DynamicFormComponent, StepperFormComponent, JsonPipe],\n  templateUrl: './mes-formulaires.component.html',\n  styleUrl: './mes-formulaires.component.scss',\n})\nexport class MesFormulairesComponent {\n  /** Route vers le builder (lien \"Nouveau formulaire\" et actions d'édition) */\n  @Input() builderRoute = '/builder';\n  /** Préfixe de route pour l'ouverture d'un formulaire par ID */\n  @Input() formRoute = '/form';\n  /** Route du lien \"Retour\" */\n  @Input() backRoute = '/';\n\n  private formService = inject(FormConfigService);\n  private snack       = inject(MatSnackBar);\n\n  readonly savedForms = this.formService.schemas;\n  readonly loadError  = this.formService.loadError;\n\n  searchTerm = signal('');\n\n  filteredForms = computed<SavedFormSchema[]>(() => {\n    const term = this.searchTerm().trim().toLowerCase();\n    if (!term) return this.savedForms();\n    return this.savedForms().filter(s =>\n      s.title.toLowerCase().includes(term) || s.code.toLowerCase().includes(term)\n    );\n  });\n\n  selectedId  = signal<string | null>(null);\n  submitted   = signal(false);\n  submitData  = signal<Record<string, unknown>>({});\n\n  activeConfig = computed<AnyFormConfig | null>(() => {\n    const id = this.selectedId();\n    return id ? (this.formService.get(id)?.config ?? null) : null;\n  });\n\n  activeFlatConfig = computed<DynamicFormConfig | null>(() => {\n    const c = this.activeConfig();\n    return c && !('steps' in c) ? (c as DynamicFormConfig) : null;\n  });\n\n  activeStepperConfig = computed<StepperFormConfig | null>(() => {\n    const c = this.activeConfig();\n    return c && 'steps' in c ? (c as StepperFormConfig) : null;\n  });\n\n  activeSchema = computed<SavedFormSchema | null>(() => {\n    const id = this.selectedId();\n    return id ? (this.formService.get(id) ?? null) : null;\n  });\n\n  selectForm(id: string): void {\n    if (this.selectedId() === id) {\n      this.selectedId.set(null);\n    } else {\n      this.selectedId.set(id);\n      this.submitted.set(false);\n      this.submitData.set({});\n    }\n  }\n\n  onSubmit(event: DynamicFormSubmitEvent): void {\n    this.submitData.set(event.value as Record<string, unknown>);\n    this.submitted.set(true);\n  }\n\n  resetForm(): void {\n    this.submitted.set(false);\n    this.submitData.set({});\n  }\n\n  retry(): void { this.formService.reload(); }\n\n  deleteForm(id: string, e: Event): void {\n    e.stopPropagation();\n    this.formService.delete(id).subscribe({\n      next: () => { if (this.selectedId() === id) this.selectedId.set(null); },\n      error: err => this.snack.open(`Erreur suppression : ${err.message ?? err}`, 'Fermer', { duration: 5000 }),\n    });\n  }\n\n  formatDate(iso: string): string {\n    return new Date(iso).toLocaleDateString('fr-FR', {\n      day: '2-digit', month: 'short', year: 'numeric',\n      hour: '2-digit', minute: '2-digit',\n    });\n  }\n\n  fieldCount(config: AnyFormConfig): number {\n    if ('steps' in config) {\n      return (config as StepperFormConfig).steps.reduce(\n        (sum, step) => sum + step.fields.filter(f => f.type !== 'divider' && f.type !== 'heading').length, 0\n      );\n    }\n    return (config as DynamicFormConfig).fields?.filter(f => f.type !== 'divider' && f.type !== 'heading').length ?? 0;\n  }\n}\n","<div class=\"page\">\n\n  <header class=\"page-header\">\n    <a [routerLink]=\"backRoute\" class=\"back-link\">\n      <mat-icon>arrow_back</mat-icon>\n    </a>\n    <div class=\"header-text\">\n      <h1>Mes Formulaires</h1>\n      <p>Sélectionnez un formulaire pour le charger via <code>FormConfigService</code></p>\n    </div>\n    <a [routerLink]=\"builderRoute\" class=\"btn-primary\">\n      <mat-icon>add</mat-icon> Nouveau formulaire\n    </a>\n  </header>\n\n  <div class=\"page-body\">\n\n    <!-- ════ COLONNE GAUCHE : liste des formulaires ════ -->\n    <aside class=\"sidebar\">\n\n      <p class=\"sidebar-title\">\n        <mat-icon>folder_open</mat-icon>\n        {{ savedForms().length }} formulaire{{ savedForms().length !== 1 ? 's' : '' }} sauvegardé{{ savedForms().length !== 1 ? 's' : '' }}\n      </p>\n\n      @if (savedForms().length > 0) {\n        <div class=\"search-box\">\n          <mat-icon>search</mat-icon>\n          <input\n            type=\"text\"\n            placeholder=\"Rechercher par titre ou code…\"\n            [value]=\"searchTerm()\"\n            (input)=\"searchTerm.set($any($event.target).value)\"\n          />\n          @if (searchTerm()) {\n            <button class=\"search-clear\" title=\"Effacer\" (click)=\"searchTerm.set('')\">\n              <mat-icon>close</mat-icon>\n            </button>\n          }\n        </div>\n      }\n\n      @if (loadError()) {\n        <div class=\"load-error-banner\">\n          <mat-icon>error_outline</mat-icon>\n          <span>{{ loadError() }}</span>\n          <button class=\"retry-btn\" (click)=\"retry()\">\n            <mat-icon>refresh</mat-icon> Réessayer\n          </button>\n        </div>\n      }\n\n      @if (!loadError() && savedForms().length === 0) {\n        <div class=\"empty-state\">\n          <mat-icon>inbox</mat-icon>\n          <p>Aucun formulaire sauvegardé</p>\n          <a [routerLink]=\"builderRoute\" class=\"btn-outline-sm\">\n            <mat-icon>add</mat-icon> Créer un formulaire\n          </a>\n        </div>\n      }\n\n      @if (!loadError() && savedForms().length > 0 && filteredForms().length === 0) {\n        <div class=\"empty-state\">\n          <mat-icon>search_off</mat-icon>\n          <p>Aucun formulaire ne correspond à « {{ searchTerm() }} »</p>\n        </div>\n      }\n\n      <div class=\"form-list\">\n        @for (schema of filteredForms(); track schema.id) {\n          <div\n            class=\"form-item\"\n            [class.active]=\"selectedId() === schema.id\"\n            (click)=\"selectForm(schema.id)\"\n            role=\"button\"\n            tabindex=\"0\"\n          >\n            <div class=\"form-item-icon\">\n              <mat-icon>description</mat-icon>\n            </div>\n\n            <div class=\"form-item-body\">\n              <span class=\"form-item-title\">{{ schema.title }}</span>\n              <span class=\"form-item-meta\">\n                {{ fieldCount(schema.config) }} champ{{ fieldCount(schema.config) !== 1 ? 's' : '' }}\n                &nbsp;·&nbsp; {{ formatDate(schema.updatedAt) }}\n              </span>\n              <code class=\"form-item-id\">Code : {{ schema.code }}</code>\n            </div>\n\n            <div class=\"form-item-actions\">\n              <a\n                [routerLink]=\"[formRoute, schema.code]\"\n                class=\"action-icon\"\n                title=\"Ouvrir dans la page dédiée\"\n                (click)=\"$event.stopPropagation()\"\n              >\n                <mat-icon>open_in_new</mat-icon>\n              </a>\n              <a\n                [routerLink]=\"[builderRoute, schema.code]\"\n                class=\"action-icon\"\n                title=\"Éditer dans le Builder\"\n                (click)=\"$event.stopPropagation()\"\n              >\n                <mat-icon>edit</mat-icon>\n              </a>\n              <button\n                class=\"action-icon danger\"\n                title=\"Supprimer\"\n                (click)=\"deleteForm(schema.id, $event)\"\n              >\n                <mat-icon>delete_outline</mat-icon>\n              </button>\n            </div>\n          </div>\n        }\n      </div>\n\n      <div class=\"code-hint\">\n        <p class=\"code-hint-title\">\n          <mat-icon>integration_instructions</mat-icon> Chargement par ID\n        </p>\n        <pre class=\"code-block\">private formService = inject(FormConfigService);\n\nconst schema = this.formService.get('{{ selectedId() ?? \"votre-id\" }}');\nthis.config.set(schema?.config ?? null);</pre>\n      </div>\n\n    </aside>\n\n    <!-- ════ COLONNE DROITE : rendu du formulaire ════ -->\n    <main class=\"content\">\n\n      @if (!selectedId()) {\n        <div class=\"select-hint\">\n          <mat-icon>arrow_back</mat-icon>\n          <p>Sélectionnez un formulaire à gauche pour le charger</p>\n        </div>\n      }\n\n      @if (selectedId() && activeConfig()) {\n\n        @if (!submitted()) {\n          <div class=\"form-card\">\n\n            <div class=\"form-card-header\">\n              <mat-icon>dynamic_form</mat-icon>\n              <div>\n                <h2>{{ activeSchema()?.title }}</h2>\n                <span class=\"loaded-badge\">\n                  <mat-icon>check_circle</mat-icon>\n                  Chargé via <code>FormConfigService.get('{{ selectedId() }}')</code>\n                </span>\n              </div>\n            </div>\n\n            @if (activeFlatConfig(); as flatCfg) {\n              <ngx-dynamic-form [config]=\"flatCfg\" (formSubmit)=\"onSubmit($event)\" />\n            }\n            @if (activeStepperConfig(); as stepperCfg) {\n              <ngx-stepper-form [config]=\"stepperCfg\" (formSubmit)=\"onSubmit($event)\" />\n            }\n\n          </div>\n        }\n\n        @if (submitted()) {\n          <div class=\"result-card\">\n            <mat-icon class=\"result-icon\">check_circle</mat-icon>\n            <h2>Données soumises avec succès</h2>\n            <p class=\"result-sub\">\n              Les données ci-dessous ont été reçues par <code>onSubmit(event)</code>\n            </p>\n\n            <div class=\"result-data\">\n              <p class=\"result-data-title\">event.value :</p>\n              <pre>{{ submitData() | json }}</pre>\n            </div>\n\n            <div class=\"result-actions\">\n              <button class=\"btn-outline\" (click)=\"resetForm()\">\n                <mat-icon>refresh</mat-icon> Recommencer\n              </button>\n              <a class=\"btn-primary\" [routerLink]=\"[builderRoute, activeSchema()?.code]\">\n                <mat-icon>dashboard_customize</mat-icon> Builder\n              </a>\n            </div>\n          </div>\n        }\n\n      }\n\n      @if (selectedId() && !activeConfig()) {\n        <div class=\"select-hint error\">\n          <mat-icon>error_outline</mat-icon>\n          <p>Formulaire introuvable pour l'ID <code>{{ selectedId() }}</code></p>\n        </div>\n      }\n\n    </main>\n\n  </div>\n</div>\n","import { Component, computed, inject, Input, OnInit, signal } from '@angular/core';\nimport { JsonPipe } from '@angular/common';\nimport { ActivatedRoute, RouterLink } from '@angular/router';\nimport { MatIcon } from '@angular/material/icon';\n\nimport { DynamicFormComponent } from '../dynamic-form/dynamic-form.component';\nimport { StepperFormComponent } from '../stepper-form/stepper-form.component';\nimport { FormConfigService } from '../../services/form-config.service';\nimport type { DynamicFormConfig, StepperFormConfig, DynamicFormSubmitEvent } from '../../models/form-field.model';\nimport type { AnyFormConfig } from '../../models/saved-form.model';\n\n@Component({\n  selector: 'ngx-form-loader',\n  standalone: true,\n  imports: [DynamicFormComponent, StepperFormComponent, MatIcon, RouterLink, JsonPipe],\n  templateUrl: './form-loader.component.html',\n  styleUrl: './form-loader.component.scss',\n})\nexport class FormLoaderComponent implements OnInit {\n  /** Passé directement si le composant est utilisé sans ActivatedRoute */\n  @Input() formCode?: string;\n  /** Route du lien \"Retour\" */\n  @Input() backRoute = '/';\n  /** Route vers le builder */\n  @Input() builderRoute = '/builder';\n\n  private route       = inject(ActivatedRoute, { optional: true });\n  private formService = inject(FormConfigService);\n\n  config     = signal<AnyFormConfig | null>(null);\n\n  flatConfig = computed<DynamicFormConfig | null>(() => {\n    const c = this.config();\n    return c && !('steps' in c) ? (c as DynamicFormConfig) : null;\n  });\n\n  stepperConfig = computed<StepperFormConfig | null>(() => {\n    const c = this.config();\n    return c && 'steps' in c ? (c as StepperFormConfig) : null;\n  });\n  formTitle  = signal('');\n  schemaCode = signal('');\n  submitted  = signal(false);\n  submitData = signal<Record<string, unknown>>({});\n  notFound   = signal(false);\n  loading    = signal(false);\n\n  ngOnInit(): void {\n    const code = this.formCode\n      ?? (this.route as ActivatedRoute | null)?.snapshot?.paramMap?.get('code')\n      ?? '';\n\n    this.schemaCode.set(code);\n    this.loading.set(true);\n\n    // fetch direct par code (pas de dépendance à la liste complète déjà\n    // chargée en mémoire — reste correct même si le catalogue de formulaires\n    // grossit, et évite la course avec le chargement initial de la liste).\n    this.formService.fetchByCode(code).subscribe(schema => {\n      this.loading.set(false);\n      if (schema) {\n        this.config.set(schema.config);\n        this.formTitle.set(schema.title);\n      } else {\n        this.notFound.set(true);\n      }\n    });\n  }\n\n  onSubmit(event: DynamicFormSubmitEvent): void {\n    this.submitData.set(event.value as Record<string, unknown>);\n    this.submitted.set(true);\n  }\n\n  reset(): void {\n    this.submitted.set(false);\n    this.submitData.set({});\n  }\n}\n","<div class=\"loader-page\">\n\n  <header class=\"loader-header\">\n    <a [routerLink]=\"backRoute\" class=\"back-link\">\n      <mat-icon>arrow_back</mat-icon>\n    </a>\n    @if (formTitle()) {\n      <h1 class=\"loader-title\">{{ formTitle() }}</h1>\n    }\n    <a [routerLink]=\"builderRoute\" class=\"edit-link\" title=\"Éditer dans le Builder\">\n      <mat-icon>edit</mat-icon>\n      <span>Éditer</span>\n    </a>\n  </header>\n\n  <div class=\"loader-body\">\n\n    @if (config()) {\n\n      @if (!submitted()) {\n        <div class=\"form-wrapper\">\n          <p class=\"api-badge\">\n            <mat-icon>api</mat-icon>\n            Chargé via FormConfigService · Code :\n            <code>{{ schemaCode() }}</code>\n          </p>\n          @if (flatConfig(); as flatCfg) {\n            <ngx-dynamic-form [config]=\"flatCfg\" (formSubmit)=\"onSubmit($event)\" />\n          }\n          @if (stepperConfig(); as stepperCfg) {\n            <ngx-stepper-form [config]=\"stepperCfg\" (formSubmit)=\"onSubmit($event)\" />\n          }\n        </div>\n      }\n\n      @if (submitted()) {\n        <div class=\"success-card\">\n          <mat-icon class=\"success-icon\">check_circle</mat-icon>\n          <h2>Formulaire soumis avec succès</h2>\n          <p>Les données ont été reçues (simulation — aucun envoi réseau).</p>\n\n          <div class=\"data-preview\">\n            <p class=\"data-title\">Données reçues :</p>\n            <pre>{{ submitData() | json }}</pre>\n          </div>\n\n          <div class=\"success-actions\">\n            <button class=\"btn-outline\" (click)=\"reset()\">\n              <mat-icon>refresh</mat-icon> Recommencer\n            </button>\n            <a class=\"btn-primary\" [routerLink]=\"builderRoute\">\n              <mat-icon>dashboard_customize</mat-icon> Retour au builder\n            </a>\n          </div>\n        </div>\n      }\n\n    }\n\n    @if (loading()) {\n      <div class=\"not-found\">\n        <mat-icon>hourglass_empty</mat-icon>\n        <p>Chargement du formulaire...</p>\n      </div>\n    }\n\n    @if (notFound()) {\n      <div class=\"not-found\">\n        <mat-icon>search_off</mat-icon>\n        <h2>Formulaire introuvable</h2>\n        <p>\n          Aucun formulaire avec le code <code>{{ schemaCode() }}</code> n'a été trouvé\n          dans le stockage.\n        </p>\n        <p class=\"not-found-hint\">\n          Créez un formulaire dans le <a [routerLink]=\"builderRoute\">Form Builder</a>,\n          sauvegardez-le, puis copiez son lien.\n        </p>\n      </div>\n    }\n\n  </div>\n</div>\n","// Components\nexport { DynamicFormComponent }     from './lib/components/dynamic-form/dynamic-form.component';\nexport { DynamicFieldComponent }    from './lib/components/dynamic-field/dynamic-field.component';\nexport { StepperFormComponent }     from './lib/components/stepper-form/stepper-form.component';\nexport { FormBuilderComponent }     from './lib/components/form-builder/form-builder.component';\nexport { MesFormulairesComponent }  from './lib/components/mes-formulaires/mes-formulaires.component';\nexport { FormLoaderComponent }      from './lib/components/form-loader/form-loader.component';\n\n// Directives\nexport { ThousandsInputDirective }  from './lib/utils/thousands-input.directive';\n\n// Services\nexport { DynamicFormBuilderService }    from './lib/services/dynamic-form-builder.service';\nexport { ConditionEvaluatorService }    from './lib/services/condition-evaluator.service';\nexport { FormConfigService }            from './lib/services/form-config.service';\nexport { UniquenessValidatorService }   from './lib/services/uniqueness-validator.service';\n\n// Storage\nexport { FormStorageAdapter }   from './lib/storage/form-storage.adapter';\nexport { LocalStorageAdapter }  from './lib/storage/local-storage.adapter';\nexport { HttpStorageAdapter, FORM_API_URL, NGX_FORMS_LIST_PAGE_SIZE } from './lib/storage/http-storage.adapter';\n\n// Providers\nexport { provideNgxForms, NGX_DATA_API_URL, ngxFormsAuthInterceptor } from './lib/providers';\nexport type { NgxFormsOptions, NgxFormsLocalOptions, NgxFormsHttpOptions } from './lib/providers';\n\n// Auth\nexport { NgxFormsAuthService, NGX_FORMS_AUTH } from './lib/auth/ngx-forms-auth.service';\nexport type { NgxFormsAuthOptions } from './lib/auth/ngx-forms-auth.service';\n\n// Models & types\nexport type {\n  DynamicFormField,\n  DynamicFormConfig,\n  StepperFormConfig,\n  FormStep,\n  DynamicFormSubmitEvent,\n  FieldType,\n  FieldValidation,\n  FieldCondition,\n  SelectOption,\n} from './lib/models/form-field.model';\n\nexport type { SavedFormSchema, AnyFormConfig } from './lib/models/saved-form.model';\n\n// Phone field\nexport type { PhoneCountry } from './lib/data/phone-countries';\nexport { PHONE_COUNTRIES }    from './lib/data/phone-countries';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["map","catchError","switchMap","tap","i1.DynamicFormBuilderService","i2.ConditionEvaluatorService","i3","i4"],"mappings":"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"}