{"version":3,"sources":["../src/index.ts","../src/interceptors/error.interceptor.ts","../src/interceptors/log.interceptor.ts","../src/services/data-control.service.ts","../src/services/file.service.ts","../src/services/firebase-admin.service.ts","../src/services/mail.service.ts","../src/services/outils.service.ts","../src/models/special-characters.ts","../src/services/pdf.service.ts","../src/services/zip.service.ts"],"sourcesContent":["export * from './interceptors/error.interceptor';\nexport * from './interceptors/log.interceptor';\nexport * from './interfaces/firebase-auth-config.interface';\nexport * from './interfaces/user-credentials.interface';\nexport * from './services/data-control.service';\nexport * from './services/file.service';\nexport * from './services/firebase-admin.service';\nexport * from './services/mail.service';\nexport * from './services/outils.service';\nexport * from './services/pdf.service';\nexport * from './services/zip.service';\n","// projects/clemledev-rest/src/lib/interceptors/error-5xx.interceptor.ts\nimport { Injectable, NestInterceptor, ExecutionContext, CallHandler, Logger } from '@nestjs/common';\nimport { Observable, throwError } from 'rxjs';\nimport { catchError } from 'rxjs/operators';\n\n@Injectable()\nexport class ErrorInterceptor implements NestInterceptor {\n  private readonly logger = new Logger(ErrorInterceptor.name);\n\n  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {\n    return next.handle().pipe(\n      catchError((err) => {\n        const res = context.switchToHttp().getResponse();\n        const status = err.status || res.statusCode || 500;\n\n        if (status >= 500 && status < 600) {\n          const req = context.switchToHttp().getRequest();\n          this.logger.error(\n            `[${req.method}] ${req.url} - Status: ${status} - Error: ${err.message}`,\n            err.stack\n          );\n        }\n        return throwError(() => err);\n      })\n    );\n  }\n}","import { Injectable, NestInterceptor, ExecutionContext, CallHandler, Logger } from '@nestjs/common';\nimport { Observable } from 'rxjs';\nimport { tap } from 'rxjs/operators';\n\n@Injectable()\nexport class LogInterceptor implements NestInterceptor {\n  private readonly logger = new Logger(LogInterceptor.name);\n\n  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {\n    const req = context.switchToHttp().getRequest();\n    const { method, url, body } = req;\n    const start = Date.now();\n\n    // Anonymisation des données sensibles\n    const anonymizedBody = this.anonymizeData(body);\n\n    this.logger.log(`[${method}] ${url} - Request: ${JSON.stringify(anonymizedBody)}`);\n\n    return next.handle().pipe(\n      tap((response) => {\n        const duration = Date.now() - start;\n        const res = context.switchToHttp().getResponse();\n        this.logger.log(`[${method}] ${url} - Status: ${res.statusCode} - ${duration}ms`);\n      })\n    );\n  }\n\n  private anonymizeData(data: any): any {\n    if (!data || typeof data !== 'object') return data;\n    const anonymized = { ...data };\n    const sensitiveFields = ['password', 'email', 'phone', 'token']; // À personnaliser\n    sensitiveFields.forEach((field) => {\n      if (anonymized[field]) {\n        anonymized[field] = '***';\n      }\n    });\n    return anonymized;\n  }\n}\n","import { Injectable, BadRequestException, HttpException, HttpStatus, UnauthorizedException } from '@nestjs/common';\nimport { DeepPartial, getMetadataArgsStorage, ObjectLiteral } from 'typeorm';\nimport { ColumnMetadataArgs } from 'typeorm/metadata-args/ColumnMetadataArgs.js';\n\n// Interface pour les règles de transformation/validation\ninterface DataRule<T> {\n  field: keyof T;\n  required?: boolean;\n  transform?: (value: any) => any; // Transformation (ex. toUpperCase)\n  validate?: (value: any) => string | null; // Validation (retourne erreur ou null)\n}\n\n// Interface minimale pour garantir 'id' et l'indexation\ninterface IndexableEntity extends ObjectLiteral {\n  id?: any;\n  [key: string]: any;\n}\n\n@Injectable()\nexport class DataControlService {\n  // NEW - Proposition Grok à partir du DCS de ClicTréso\n  /**\n   * Valide et prépare les données pour create/update/delete\n   */\n  prepareData<T extends IndexableEntity>(\n    entityClass: new () => T,\n    action: 'C' | 'U' | 'D',\n    data: DeepPartial<T>,\n    rules: DataRule<T>[] = [],\n    constructedFields: (keyof T)[] = []\n  ): { id?: any; data: DeepPartial<T> } {\n    if (!data || typeof data !== 'object') {\n      throw new BadRequestException(`${action} data cannot be emptyyyyyyy`);\n    }\n\n    const entity = new entityClass();\n    const columnMetadata = this.getColumnsMetadata(entity); // Nouvelle méthode pour métadonnées\n    const columns = columnMetadata.map((col) => col.propertyName);\n    const cleanedData: { [key: string]: any } = {};\n\n    let id: any = null;\n    if (action === 'U' || action === 'D') {\n      if (!data['id']) {\n        throw new BadRequestException(`ID is required for ${action}`);\n      }\n      id = data['id'];\n      if (action === 'D') {\n        return { id, data: cleanedData as DeepPartial<T> };\n      }\n    }\n\n    // Détection automatique des champs obligatoires\n    const autoRequiredFields = columnMetadata\n      .filter((col) => !col.options.nullable && col.options.default === undefined && col.propertyName !== 'id')\n      .map((col) => col.propertyName as keyof T);\n\n    const errors: string[] = [];\n\n    // Validation des champs obligatoires automatiques\n    if (action === 'C' || action === 'U') {\n      autoRequiredFields.forEach((field) => {\n        const fieldStr = field as string;\n        if (data[fieldStr] === undefined || data[fieldStr] === null) {\n          errors.push(`${fieldStr} is required for ${action} (auto-detected)`);\n        } else {\n          cleanedData[fieldStr] = data[fieldStr];\n        }\n      });\n    }\n    // console.log('CLEANED DATA 1', cleanedData);\n\n    // Application des règles manuelles (surchargent les auto-détectées si spécifiées)\n    rules.forEach((rule) => {\n      const field = rule.field as string;\n      const value = data[field];\n\n      const isAutoRequired = autoRequiredFields.includes(rule.field);\n      const required = rule.required !== undefined ? rule.required : isAutoRequired;\n\n      if (required && (value === undefined || value === null)) {\n        errors.push(`${field} is required for ${action}`);\n      } else if (value !== undefined) {\n        let transformedValue = value;\n        if (rule.transform) {\n          transformedValue = rule.transform(value);\n        }\n        if (rule.validate) {\n          const error = rule.validate(transformedValue);\n          if (error) {\n            errors.push(`${field}: ${error}`);\n          }\n        }\n        cleanedData[field] = transformedValue;\n      }\n    });\n\n    if (errors.length > 0) {\n      throw new BadRequestException(errors.join(', '));\n    }\n\n    // Ajout des champs facultatifs non couverts\n    Object.keys(data).forEach((key) => {\n      if (\n        !rules.some((r) => r.field === key) &&\n        !autoRequiredFields.includes(key as keyof T) &&\n        data[key] !== undefined &&\n        !constructedFields.includes(key as keyof T)\n      ) {\n        cleanedData[key] = data[key];\n      }\n    });\n\n    // Nettoyage des champs non persistés\n    Object.keys(cleanedData).forEach((key) => {\n      if (!columns.includes(key)) {\n        delete cleanedData[key];\n      }\n    });\n\n    return { id, data: cleanedData as DeepPartial<T> };\n  }\n\n  /**\n   * Fusionne un objet existant avec de nouvelles données pour update\n   */\n  mergeForUpdate<T extends ObjectLiteral>(\n    entityClass: new () => T,\n    oldObject: T,\n    newData: DeepPartial<T>,\n    constructedFields: (keyof T)[] = [],\n    fieldsToNull: (keyof T)[] = []\n  ): DeepPartial<T> {\n    if (!oldObject || !oldObject.id) {\n      throw new BadRequestException('No existing object found for update');\n    }\n\n    const columns = this.getColumnsMetadata(oldObject).map((col) => col.propertyName);\n    const mergedData: { [key: string]: any } = { ...oldObject };\n\n    // Appliquer les nouvelles données\n    Object.entries(newData).forEach(([key, value]) => {\n      if (value !== undefined) {\n        mergedData[key] = value;\n        // Transformations spécifiques (ex. toUpperCase, téléphone)\n        if (['ville', 'nom'].includes(key) && value) {\n          mergedData[key] = value.toString().toUpperCase();\n        } else if (key === 'telephone' && value) {\n          mergedData[key] = value.toString().replace(/\\s/g, '');\n        }\n      }\n    });\n\n    // Supprimer les champs non persistés ou construits\n    Object.keys(mergedData).forEach((key) => {\n      if (!columns.includes(key) || constructedFields.includes(key as keyof T)) {\n        delete mergedData[key];\n      }\n    });\n\n    // Mettre à null les champs spécifiés\n    fieldsToNull.forEach((field) => {\n      mergedData[field as string] = null;\n    });\n\n    return mergedData as DeepPartial<T>;\n  }\n\n  /**\n   * Vérifie l'autorisation basée sur id_asso\n   */\n  checkAssociationAuthorization<T extends { id_asso: any }>(\n    user: { id_asso: any },\n    data: T | T[]\n  ): boolean {\n    const items = Array.isArray(data) ? data : [data];\n    const uniqueAssos = [...new Set(items.map((item) => item.id_asso))];\n\n    if (uniqueAssos.length !== 1 || uniqueAssos[0] !== user.id_asso) {\n      throw new UnauthorizedException('Not authorized on this data');\n    }\n    return true;\n  }\n\n  /**\n   * Valide le résultat d'une opération TypeORM\n   */\n  validateOperationResult(action: 'C' | 'U' | 'D', result: any): any {\n    switch (action) {\n      case 'C':\n        if (result?.id) return result.id;\n        throw new HttpException('No row created', HttpStatus.INTERNAL_SERVER_ERROR);\n      case 'U':\n      case 'D':\n        if (result?.affected > 0) return true;\n        throw new HttpException(`No row affected for ${action}`, HttpStatus.INTERNAL_SERVER_ERROR);\n      default:\n        throw new HttpException('Invalid action', HttpStatus.INTERNAL_SERVER_ERROR);\n    }\n  }\n\n  /**\n   * Récupère les metadata d'une entité TypeORM\n   */\n  // Nouvelle méthode pour récupérer les métadonnées des colonnes\n  private getColumnsMetadata<T extends ObjectLiteral>(entity: T) {\n    const metadata = getMetadataArgsStorage();\n    let columns = metadata.columns.filter((column) => column.target === entity.constructor);\n\n    // const constructorName = entity.constructor.name;\n    // if (['Edition', 'EditionArchive'].includes(constructorName)) {\n    //   columns = [...columns, ...metadata.columns.filter((col) => col.target.name === 'EditionBase')];\n    // } else if (['EditionDetail', 'EditionDetailArchive'].includes(constructorName)) {\n    //   columns = [...columns, ...metadata.columns.filter((col) => col.target.name === 'EditionDetailBase')];\n    // }\n\n    return columns;\n  }\n\n  // OLD - Proposition Grok à partir de rien\n  // /**\n  //    * Valide et prépare les données pour création/mise à jour/suppression\n  //    * @param data Données à valider\n  //    * @param rules Règles de validation spécifiques à l'entité\n  //    * @param operation Type d'opération (pour logs ou messages)\n  //    */\n  // validateData<T extends ObjectLiteral>(\n  //   data: DeepPartial<T>,\n  //   rules: ValidationRule<T>[] = [],\n  //   operation: 'create' | 'update' | 'delete' = 'create'\n  // ): DeepPartial<T> {\n  //   if (!data || typeof data !== 'object') {\n  //     throw new BadRequestException(`${operation} data cannot be empty`);\n  //   }\n\n  //   const errors: string[] = [];\n\n  //   rules.forEach((rule) => {\n  //     // Typage explicite pour éviter TS2536\n  //     const field = rule.field as string; // Conversion en string pour indexer\n  //     const value = (data as any)[field]; // Utilisation de 'as any' pour contourner temporairement\n\n  //     if (rule.required && (value === undefined || value === null)) {\n  //       errors.push(`${field} is required for ${operation}`);\n  //     } else if (rule.validate && value !== undefined && value !== null) {\n  //       const validationError = rule.validate(value);\n  //       if (validationError) {\n  //         errors.push(`${field}: ${validationError}`);\n  //       }\n  //     }\n  //   });\n\n  //   if (errors.length > 0) {\n  //     throw new BadRequestException(errors.join(', '));\n  //   }\n\n  //   const cleanedData: { [key: string]: any } = { ...data };\n  //   Object.keys(cleanedData).forEach((key) => {\n  //     if (cleanedData[key] === undefined) {\n  //       delete cleanedData[key];\n  //     }\n  //   });\n\n  //   return cleanedData as DeepPartial<T>;\n  // }\n}\n","import { Injectable, NotFoundException } from \"@nestjs/common\";\nimport * as fs from 'fs';\nimport * as mimeTypes from 'mime-types';\nimport path, { extname } from 'path';\n\n// import { ConfigService } from '@nestjs/config';\n\n@Injectable()\nexport class FileService {\n    // private secureKey: string = \"\";\n\n    constructor(\n        // private configService: ConfigService\n    ) {\n        // this.secureKey = this.configService.get<string>('CLD_FILE_SECURE_KEY');\n    }\n\n    // constructor(\n    //     private zipService: ZipService,\n    //     private outilsService: OutilsService,\n    //     private configService: ConfigService\n    // ) { }\n\n    // const files = await fs.promises.readdir(folderToZip + folder); // %%% Tout passer les fs.readdir comme ça\n\n    createFolderIfNotExists(path: string) {\n        fs.mkdirSync(path, { recursive: true });\n    }\n\n    fileExists(path: string) {\n        return fs.existsSync(path);\n    }\n\n    getFileReadStream(path) {\n        return fs.createReadStream(path);\n    }\n\n    async getFile(path, res?: any) {\n        const fileStream = fs.createReadStream(path);\n        if (res) {\n            res.setHeader('Content-Type', mimeTypes.lookup(extname(path)));\n            fileStream.pipe(res);\n        } else {\n            if (extname(path) == 'pdf') { // PDF\n                return fs.createReadStream(path);\n            } else { // Image\n                const imageStream = await fs.promises.readFile(path, { encoding: 'base64' });\n                return {\n                    image: imageStream.toString(),\n                    mime: mimeTypes.lookup(extname(path))\n                };\n            }\n        }\n    }\n\n    // async getFile(structure: Structure, type: string, res?: Response, data?: any) {\n    //     this.setStructureFolder(structure.files_key, type);\n    //     let folder: string = this.structureFolder;\n    //     if (type == 'clictreso-filigrane') {\n    //         const path = await this.getFilePath(structure, type);\n    //         const imageStream = await fs.promises.readFile(path, { encoding: 'base64' });\n    //         return {\n    //             image: imageStream.toString(),\n    //             mime: mimeTypes.lookup(extname(path))\n    //         };\n    //     } else if (type == 's-logo' || type == 'e-perso') {\n    //         if (fs.existsSync(folder)) {\n    //             const files = await fs.promises.readdir(folder);\n    //             if (files.length > 0) {\n    //                 const path = folder + files[0];\n    //                 if (res) {\n    //                     const imageStream = fs.createReadStream(path);\n    //                     res.setHeader('Content-Type', mimeTypes.lookup(extname(path)));\n    //                     imageStream.pipe(res);\n    //                 } else {\n    //                     const imageStream = await fs.promises.readFile(path, { encoding: 'base64' });\n    //                     return {\n    //                         image: imageStream.toString(),\n    //                         mime: mimeTypes.lookup(extname(path))\n    //                     };\n    //                 }\n    //             } else {\n    //                 if (res) {\n    //                     res.send(null);\n    //                 } else {\n    //                     return null;\n    //                 }\n    //             }\n    //         } else {\n    //             if (res) {\n    //                 res.send(null);\n    //             } else {\n    //                 return null;\n    //             }\n    //         }\n    //     } else if (type == 'ps-photo') {\n    //         folder += data.id + '/';\n    //         if (fs.existsSync(folder)) {\n    //             fs.readdir(folder, (err, files) => {\n    //                 if (err) {\n    //                     res.send(null);\n    //                 }\n    //                 const path = folder + files[0];\n    //                 const stream = fs.createReadStream(path);\n    //                 res.setHeader('Content-Type', mimeTypes.lookup(extname(path)));\n    //                 stream.pipe(res);\n    //             });\n    //         } else {\n    //             res.send(null);\n    //         }\n    //     } else if (type == 'tc-justif') {\n    //         folder += data.id + '/';\n    //         if (fs.existsSync(folder)) {\n    //             fs.readdir(folder, (err, files) => {\n    //                 if (err) {\n    //                     res.send(null);\n    //                 }\n    //                 const path = folder + files[0];\n    //                 const stream = fs.createReadStream(path);\n    //                 res.setHeader('Content-Type', mimeTypes.lookup(extname(path)));\n    //                 stream.pipe(res);\n    //             });\n    //         } else {\n    //             res.send(null);\n    //         }\n    //     } else if (type == 'e-NDF') {\n    //         folder += data.id_edition + '/' + data.id + '/';\n    //         const path = folder + data.nom_fichier;\n    //         if (fs.existsSync(path)) {\n    //             const stream = fs.createReadStream(path);\n    //             res.setHeader('Content-Type', mimeTypes.lookup(extname(path)));\n    //             stream.pipe(res);\n    //         } else {\n    //             res.send(null);\n    //         }\n    //     } else if (type == 'pndf-mf' || type == 'e-CGV') {\n    //         if (fs.existsSync(folder)) {\n    //             fs.readdir(folder, (err, files) => {\n    //                 if (err) {\n    //                     res.send(null);\n    //                 }\n    //                 const path = folder + files[0];\n    //                 const imageStream = fs.createReadStream(path);\n    //                 res.setHeader('Content-Type', mimeTypes.lookup(extname(path)));\n    //                 imageStream.pipe(res);\n    //             });\n    //         } else {\n    //             res.send(null);\n    //         }\n    //     } else if (type == 'archivage') {\n    //         const pathArchive = folder + '../ARCHIVE_ClicTreso.zip';\n    //         if (fs.existsSync(pathArchive)) {\n    //             const stream = fs.createReadStream(pathArchive);\n    //             res.setHeader('Content-Type', mimeTypes.lookup(extname(pathArchive)));\n    //             stream.pipe(res);\n    //         } else {\n    //             res.send(null);\n    //         }\n    //     } else if (type == 'export') {\n    //         const pathExport = folder + '../EXPORT_ClicTreso.zip';\n    //         if (fs.existsSync(pathExport)) {\n    //             const stream = fs.createReadStream(pathExport);\n    //             res.setHeader('Content-Type', mimeTypes.lookup(extname(pathExport)));\n    //             stream.pipe(res);\n    //         } else {\n    //             res.send(null);\n    //         }\n    //     }\n    // }\n\n    moveFiles(oldPath: string, newPath: string) {\n        if (!this.fileExists(oldPath)) {\n            throw new NotFoundException('File not found');\n        }\n\n        const newPathSplited: string[] = newPath.split('/');\n        const newFolder: string = newPathSplited.filter((block, index) => index < newPathSplited.length - 1).join('/');\n        this.createFolderIfNotExists(newFolder);\n        fs.rename(oldPath, newPath, err => {\n            if (err) {\n                console.error('File not saved', err);\n            }\n        });\n    }\n\n    removeFilePath(path) {\n        return fs.rmSync(path);\n    }\n\n    async removeFilesNotEndingBy(folder: string, end: string) {\n        if (fs.existsSync(folder)) {\n            const items = await fs.promises.readdir(folder);\n            for (const item of items) {\n                if (item.search(end) === -1) {\n                    fs.rmSync(folder + item);\n                }\n            }\n        } else {\n            return;\n        }\n    }\n}\n","import { Injectable, Logger } from '@nestjs/common';\n// import * as admin from 'firebase-admin';\n// import { FirebaseAuthConfig } from '../interfaces/firebase-auth-config.interface';\n// import { UserCredentials } from '../interfaces/user-credentials.interface';\n// import { ConfigService } from '@nestjs/config';\n\n@Injectable()\nexport class FirebaseAuthService {\n  // private readonly logger = new Logger(FirebaseAuthService.name);\n  // private firebaseApp: admin.app.App;\n\n  constructor(\n          // private configService: ConfigService,\n          // config: FirebaseAuthConfig\n      ) {\n          // this.xxx = this.configService.get<string>('XXX');\n          // this.initializeFirebase(config);\n      }\n\n  // private initializeFirebase(config: FirebaseAuthConfig) {\n  //   try {\n  //     this.firebaseApp = admin.initializeApp({\n  //       credential: config.serviceAccount\n  //         ? admin.credential.cert(config.serviceAccount)\n  //         : admin.credential.applicationDefault(),\n  //     });\n  //     this.logger.log('Firebase initialized successfully');\n  //   } catch (error: any) {\n  //     this.logger.error('Failed to initialize Firebase', error.stack);\n  //     throw new Error('Firebase initialization failed');\n  //   }\n  // }\n\n  // async signUpWithEmail(email: string, password: string): Promise<UserCredentials> {\n  //   try {\n  //     const userRecord = await this.firebaseApp.auth().createUser({\n  //       email,\n  //       password,\n  //     });\n  //     const token = await this.firebaseApp.auth().createCustomToken(userRecord.uid);\n  //     this.logger.log(`User signed up: ${email}`);\n  //     return { uid: userRecord.uid, email: userRecord.email, token };\n  //   } catch (error: any) {\n  //     this.logger.error(`Sign-up failed for ${email}`, error.stack);\n  //     throw new Error(`Sign-up failed: ${error.message}`);\n  //   }\n  // }\n\n  // async signInWithEmail(email: string, password: string): Promise<UserCredentials> {\n  //   try {\n  //     // Firebase Admin SDK ne gère pas directement la connexion par mot de passe.\n  //     // On simule une vérification en récupérant l'utilisateur et générant un token.\n  //     const userRecord = await this.firebaseApp.auth().getUserByEmail(email);\n  //     const token = await this.firebaseApp.auth().createCustomToken(userRecord.uid);\n  //     this.logger.log(`User signed in: ${email}`);\n  //     return { uid: userRecord.uid, email: userRecord.email, token };\n  //   } catch (error: any) {\n  //     this.logger.error(`Sign-in failed for ${email}`, error.stack);\n  //     throw new Error(`Sign-in failed: ${error.message}`);\n  //   }\n  // }\n\n  // async signInWithGoogle(idToken: string): Promise<UserCredentials> {\n  //   try {\n  //     const decodedToken = await this.firebaseApp.auth().verifyIdToken(idToken);\n  //     const userRecord = await this.firebaseApp.auth().getUser(decodedToken.uid);\n  //     const token = await this.firebaseApp.auth().createCustomToken(userRecord.uid);\n  //     this.logger.log(`User signed in with Google: ${userRecord.email}`);\n  //     return { uid: userRecord.uid, email: userRecord.email, token };\n  //   } catch (error: any) {\n  //     this.logger.error('Google sign-in failed', error.stack);\n  //     throw new Error(`Google sign-in failed: ${error.message}`);\n  //   }\n  // }\n\n  // async verifyToken(token: string): Promise<admin.auth.DecodedIdToken> {\n  //   try {\n  //     const decodedToken = await this.firebaseApp.auth().verifyIdToken(token);\n  //     this.logger.log(`Token verified for UID: ${decodedToken.uid}`);\n  //     return decodedToken;\n  //   } catch (error: any) {\n  //     this.logger.error('Token verification failed', error.stack);\n  //     throw new Error(`Token verification failed: ${error.message}`);\n  //   }\n  // }\n}","import { Injectable } from '@nestjs/common';\nimport { ConfigService } from '@nestjs/config';\nimport * as nodemailer from 'nodemailer';\n\n@Injectable()\nexport class CldMailService {\n    // public alias: string = 'mail';\n    // public entite: string = 'mail';\n    public user: string;\n    public password: string;\n    public sender: string;\n\n    constructor(\n        private configService: ConfigService\n    ) {\n        this.user = this.configService.get<string>('CLD_MAIL_USER');\n        this.password = this.configService.get<string>('CLD_MAIL_PASSWORD');\n        this.sender = this.configService.get<string>('CLD_MAIL_SENDER');\n    }\n\n    async sendMail(destinataires: string[], objet: string, corps: any[], pj: any = null, mailNotif: boolean = false, expediteur: any = null, mailFromStructureToClient: boolean = false) {\n        let transporter = nodemailer.createTransport({\n            host: \"smtp.gmail.com\",\n            port: 587,\n            secure: false,\n            auth: {\n                user: this.user,\n                pass: this.password,\n            },\n        });\n\n        // Set des options\n        let options: any = {\n            from: this.sender, // sender address\n            to: [...new Set(destinataires)].join(\", \"), // list of distincts receivers\n            subject: objet, // Subject line\n        };\n        if (expediteur) {\n            if (expediteur.prenom && expediteur.nom) {\n                options.replyTo = '\"' + expediteur.prenom + ' ' + expediteur.nom + '\" <' + expediteur.mail + '>';\n            } else if (expediteur.nom_structure) {\n                options.replyTo = '\"' + expediteur.nom_structure + '\" <' + expediteur.mail + '>';\n            } else {\n                options.replyTo = expediteur.mail;\n            }\n        }\n        let mailContent = await this.getHtmlAndPlainText(corps, mailNotif, mailFromStructureToClient);\n        options.html = mailContent.html;\n        options.text = mailContent.plainText;\n\n        // PJs\n        let attachments: any[] = [];\n        if (mailContent.attachments.length > 0) {\n            attachments = [...attachments, ...mailContent.attachments];\n        }\n        if (pj) {\n            attachments = [...attachments, pj];\n        }\n        if (attachments.length > 0) {\n            options.attachments = attachments;\n        }\n\n        // Envoi du mail\n        try {\n            const info = await transporter.sendMail(options);\n            // console.log(info);\n        } catch (error) {\n            // console.log(error);\n            // console.log(options);\n            // await this.erreurService.controlError(null, error, `${this.alias}-SEND`, <Erreur>{\n            //     onglet: this.entite,\n            //     action: 'sendMail',\n            //     erreur: error.toString(),\n            //     donnees: { objet, corps }\n            // });\n        }\n    }\n\n    private async getHtmlAndPlainText(corpsMail: any[], mailNotif: boolean, mailFromStructureToClient: boolean = false) {\n        const styleGeneral = `<style>\n            @media (min-width: 768px) {\n                .display-only-on-large-screen {\n                    display: block;\n                }\n            }\n\n            @media (max-width: 768px) {\n                .display-only-on-large-screen {\n                    display: none;\n                }\n            }\n        </style>`;\n        let attachments: any[] = [];\n        let htmlContent = `<html><head>${styleGeneral}</head>\n            <body style='text-align: center;'><div style='max-width: 500px; text-align: left; margin: auto;'><br>\n            <img src=\"https://clictreso.fr/wp-content/uploads/clictreso-mails/banniere_mail.png\" alt='Bannière ClicTréso' style='width: 100%; max-width: 500px;' />\n            <div>`;\n        // console.log(htmlContent);\n        let plainTextContent = \"\";\n        for (let element of corpsMail) {\n            if (element.type == \"titre\") {\n                htmlContent += this.getHtmlTitle(element.contenu);\n                plainTextContent += this.getPlainTextLine(element.contenu);\n            } else if (element.type == \"ligne\") {\n                htmlContent += this.getHtmlLine(element.contenu, (element.options ? element.options : null));\n                plainTextContent += this.getPlainTextLine(element.contenu);\n            } else if (element.type == \"bouton\") {\n                htmlContent += this.getHtmlButton(element.contenu);\n                plainTextContent += this.getPlainTextLine(element.contenu[\"texte\"] + \" : \" + element.contenu.lien);\n            } else if (element.type == \"liste\") {\n                htmlContent += this.getHtmlListe(element.contenu);\n                for (let item of element.contenu) {\n                    plainTextContent += this.getPlainTextLine(\"   - \" + item);\n                }\n            } else if (element.type == \"liste-numeros\") {\n                htmlContent += this.getHtmlListeNumeros(element.contenu);\n                let index = 1;\n                for (let item of element.contenu) {\n                    plainTextContent += this.getPlainTextLine(\"   \" + index + \". \" + item);\n                    index++;\n                }\n            } else if (element.type == \"citation\") {\n                htmlContent += this.getHtmlCitation(element.contenu);\n                plainTextContent += this.getPlainTextLine('\"' + element.contenu + '\"');\n            } else if (element.type == \"note\") {\n                htmlContent += this.getHtmlNote(element.contenu);\n                plainTextContent += \"----- NOTE -----\\r\\n\";\n                plainTextContent += this.getPlainTextLine(element.contenu);\n                plainTextContent += \"----- FIN DE LA NOTE -----\\r\\n\";\n            } else if (element.type == \"encartjaune\") {\n                htmlContent += this.getHtmlEncartJaune(element.contenu);\n                plainTextContent += \"----- INFO -----\\r\\n\";\n                if (element.contenu[\"titre\"]) {\n                    plainTextContent += this.getPlainTextLine(element.contenu[\"titre\"]);\n                }\n                plainTextContent += this.getPlainTextLine(element.contenu[\"texte\"]);\n                plainTextContent += \"----- FIN DE L'INFO -----\\r\\n\";\n            } else if (element.type == \"encartjaunebig\") {\n                htmlContent += this.getHtmlBigEncartJaune(element.contenu);\n                plainTextContent += \"----- INFO -----\\r\\n\";\n                plainTextContent += this.getPlainTextLine(element.contenu[\"texte\"]);\n                plainTextContent += \"----- FIN DE L'INFO -----\\r\\n\";\n            } else if (element.type == \"qrcode\") {\n                htmlContent += this.getHtmlQrCode(element.contenu);\n                attachments.push({\n                    filename: 'QRCode.png',\n                    content: element.contenu.qrcode_img.split('base64,')[1],\n                    encoding: 'base64',\n                    cid: element.contenu.cid\n                })\n            } else if (element.type == \"encartpaiementenligne\") {\n                htmlContent += this.getHtmlEncartPEL(element.contenu);\n                plainTextContent += \"----- INFO -----\\r\\n\";\n                plainTextContent += this.getPlainTextLine(element.contenu[\"titre\"]);\n                plainTextContent += this.getPlainTextLine(element.contenu[\"texte\"]);\n                plainTextContent += \"----- FIN DE L'INFO -----\\r\\n\";\n            }\n        }\n\n        // Encart \"Mail automatique\"\n        if (mailFromStructureToClient) {\n            htmlContent += `<div style='width: 100%; text-align: center; background-color: #333333; color: white;'>\n                <p style='font-size: 11px; margin-bottom: 0; padding: 8px;'>\n                Utilisez ClicTréso pour gérer votre entreprise ou association en quelques clics !<br>\n                <a href='https://clictreso.fr' style='color: #ffc416;'>Découvrir ClicTréso</a><br><br>\n                Une erreur ? Une question ? Vous pouvez répondre à cet e-mail. Votre réponse sera directement envoyée à l'association / entreprise.\n                </p>`;\n            plainTextContent += `Utilisez ClicTréso pour gérer votre entreprise ou association en quelques clics !\\r\\n` +\n                `Découvrir ClicTréso sur https://clictreso.fr\\r\\n\\r\\n` +\n                `Une erreur ? Une question ? Vous pouvez répondre à cet e-mail. Votre réponse sera directement envoyée à l'association / entreprise.`;\n        } else if (mailNotif) {\n            htmlContent += `<div style='width: 100%; text-align: center; background-color: #333333; color: white;'>\n                <p style='font-size: 11px; margin-bottom: 0; padding: 8px;'>\n                CECI EST UN MAIL AUTOMATIQUE, merci de ne pas y répondre.<br>\n                Vous pouvez mettre à jour vos préférences de notifications dans votre profil <a href='https://app.clictreso.fr' style='color: #ffc416;'>ClicTréso</a>.\n                </p>`;\n            plainTextContent += `CECI EST UN MAIL AUTOMATIQUE, merci de ne pas y répondre.\\r\\n` +\n                `Vous pouvez mettre à jour vos préférences de notifications dans votre profil sur https://app.clictreso.fr`;\n        } else {\n            htmlContent += `<div style='width: 100%; text-align: center; background-color: #333333; color: white;'>\n                <p style='font-size: 11px; margin-bottom: 0; padding: 8px;'>\n                CECI EST UN MAIL AUTOMATIQUE, merci de ne pas y répondre.<br>\n                Plus d'infos à propos de ClicTréso sur <a href='https://clictreso.fr' style='color: #ffc416;'>https://clictreso.fr</a>.\n                </p>`;\n            plainTextContent += `CECI EST UN MAIL AUTOMATIQUE, merci de ne pas y répondre.\\r\\n` +\n                `Plus d'infos à propos de ClicTréso sur https://clictreso.fr`;\n        }\n        htmlContent += `<p style='width: 100%; padding: 8px; margin-top: 0; text-align: center;'>\n            <a href=\"https://www.facebook.com/clictreso\">\n                <img src=\"https://clictreso.fr/wp-content/uploads/clictreso-mails/facebook-circle.png\" alt='Page Facebook de ClicTréso' style=\"width: 25px; height: auto;\" /></a> \n            <a href=\"https://www.instagram.com/clictreso\">\n                <img src=\"https://clictreso.fr/wp-content/uploads/clictreso-mails/instagram-circle.png\" alt='Compte Instagram de ClicTréso' style=\"width: 25px; height: auto;\" /></a> \n            <a href=\"https://www.linkedin.com/company/clictreso\">\n                <img src=\"https://clictreso.fr/wp-content/uploads/clictreso-mails/linkedin-circle.png\" alt='Page LinkedIn de ClicTréso' style=\"width: 25px; height: auto;\" /></a>\n        </p>`\n\n        htmlContent += '</div></div></body></html>';\n\n        return {\n            html: htmlContent,\n            plainText: plainTextContent,\n            attachments: attachments\n        };\n    }\n\n    private getHtmlTitle(texte) {\n        return \"<p style='font-size: 18px; text-align:center;'><b>\" + texte + \"</b></p>\";\n    }\n\n    private getHtmlLine(texte, options: any = null) {\n        let texteRemastered = this.replaceLinkStyle(texte);\n        texteRemastered = texteRemastered.replace(\"<li>\", \"<li style='font-size: 14px;'>\");\n        const style = options && options.center ? 'text-align: center;' : '';\n        return `<p style='font-size: 14px; ${style}'>${texteRemastered}</p>`;\n    }\n\n    private getHtmlListe(lignes) {\n        let html = \"<p style='font-size: 14px;'>\";\n        html += \"<ul>\";\n        for (let ligne of lignes) {\n            html += \"<li style='font-size: 14px;'>\" + ligne + \"</li>\";\n        }\n        html += \"</ul>\";\n        html += \"</p>\";\n        return html;\n    }\n\n    private getHtmlListeNumeros(lignes) {\n        let html = \"<p style='font-size: 14px;'>\";\n        html += \"<ol>\";\n        for (let ligne of lignes) {\n            html += \"<li style='font-size: 14px;'>\" + ligne + \"</li>\";\n        }\n        html += \"</ol>\";\n        html += \"</p>\";\n        return html;\n    }\n\n    private getHtmlNote(texte) {\n        return \"<p style='font-size: 12px; text-align: center;'><i>\" + this.replaceLinkStyle(texte) + \"</i></p>\";\n    }\n\n    private getHtmlBigEncartJaune(encart) {\n        let html = \"<div style='background-color: #ffc107; padding: 2px 10px 2px 10px;'>\";\n        html += \"<p style='font-size: 24px; font-weight: bold; text-align: center;'><b>\" + encart.texte + \"</b></p>\";\n        html += \"</div>\";\n        return html;\n    }\n\n    private getHtmlEncartJaune(encart) {\n        let html = \"<div style='background-color: #ffc107; padding: 2px 10px 2px 10px;'>\";\n        if (encart.titre) {\n            html += \"<p style='font-size: 14px; text-align:center;'><b><u>\" + encart.titre + \"</u></b></p>\";\n        }\n        html += \"<p style='font-size: 14px; text-align:center;'>\" + this.replaceLinkStyle(encart.texte) + \"</p>\";\n        html += \"</div>\";\n        return html;\n    }\n\n    private getHtmlQrCode(qrCodeData) { // contenu_top, lien, qrcode_img, cid\n        let html = '<div class=\"display-only-on-large-screen\">';\n        html += this.getHtmlLine(qrCodeData.ligne_top, { center: true });\n\n        html += \"<p style='text-align:center;'>\" +\n            `<img src=\"cid:${qrCodeData.cid}\" width=\"100\" height=\"100\" />` +\n            \"</p>\";\n        html += '</div>';\n        return html;\n    }\n\n    private getHtmlEncartPEL(encart) {\n        let html = \"<div style='background-color: #ffc107; padding: 2px 10px 2px 10px;'>\";\n        if (encart.titre) {\n            html += \"<p style='font-size: 14px; text-align:center;'><b>\" + encart.titre + \"</b></p>\";\n        }\n        html += \"<p style='font-size: 14px; text-align:center;'>\" + this.replaceLinkStyle(encart.texte) + \"</p>\";\n        html += \"</div>\";\n        return html;\n    }\n\n    // private getHtmlButton(texte, lien) // OLD\n    private getHtmlButton(bouton) {\n        let styleButton = \"background: rgb(110, 4, 25);\" +\n            \"border: none;\" +\n            \"border-radius: 3px;\" +\n            \"color: rgb(255, 255, 255);\" +\n            \"cursor: pointer;\" +\n            \"display: inline-block;\" +\n            \"justify-content: center;\" +\n            \"padding: 10px 25px;\" +\n            \"text-decoration: none;\";\n        return \"<p style='font-size: 14px; text-align:center;'>\" +\n            '<a style=\"' + styleButton + '\" href=\"' + bouton.lien + '\" target=\"_blank\">' + bouton.texte + '</a>' +\n            \"</p>\";\n    }\n\n    private getHtmlCitation(texte) {\n        let styleQuote = \"color: #6f6f6f; font-family: Roboto, Helvetica, Arial, sans-serif; font-size: 16px; line-height: 22px;\";\n        return \"<p style='font-size: 14px; text-align:center;'>\" +\n            `<span style='${styleQuote}'>❝</span>` +\n            \"<span style='color: #2b2b2b'><i>\" + texte + \"</i></span>\" +\n            `<span style='${styleQuote}'>❞</span>` +\n            \"</p>\";\n    }\n\n    private getPlainTextLine(texte) {\n        return texte ? texte.replace(\"<br>\", \"\\r\\n\").replace(/<(.|\\n)*?>/g, '') : '';\n    }\n\n    private replaceLinkStyle(texte) {\n        return texte ? texte.replace(\"<a \", \"<a style='color: rgb(110, 4, 25);' \") : '';\n    }\n}\n","import { Injectable } from '@nestjs/common';\nimport moment from 'moment';\nimport * as chardet from 'chardet';\nimport * as iconv from 'iconv-lite';\nimport { SPECIAL_CHARACTERS } from '../models/special-characters';\n\n@Injectable()\nexport class OutilsService {\n  public uppercase: string = 'AÀÂÆBCDEÉÈÊËFGHIÎÏJKLMNOÔŒÖPQRSTUÛÙÜVWXYŸZ';\n  public lowercase: string = 'aàâæbcdeéèêëfghiîïjklmnoôœöpqrstuûùüvwxyÿz';\n  public consonnesUpperCase: string = 'BCDFGHJKLMNPQRSTVWXZ';\n  public consonnesLowerCase: string = 'bcdfghjklmnpqrstvwxz';\n  public voyellesUpperCase: string = 'AÀÂÆEÉÈÊËIÎÏOÔŒÖUÛÙÜYŸ';\n  public voyellesLowerCase: string = 'aàâæeéèêëiîïoôœöuûùüyÿ';\n  public digits: string = '0123456789';\n\n  // IMAGE - IMAGES - BASE64 - BLOB\n  base64ToBlob(base64: string, contentType: string): Blob {\n    const byteCharacters = atob(base64.split(',')[1]); // Séparer la partie base64 de la partie MIME\n    const byteNumbers = new Array(byteCharacters.length);\n    for (let i = 0; i < byteCharacters.length; i++) {\n      byteNumbers[i] = byteCharacters.charCodeAt(i);\n    }\n    const byteArray = new Uint8Array(byteNumbers);\n    return new Blob([byteArray], { type: contentType });\n  }\n\n  // DATE - DATES - TS - TIMESTAMP - TIME STAMP\n  formatDate(date: Date | string, format: string = 'DD/MM/YYYY'): string {\n    return moment(date).format(format);\n  }\n\n  checkDate(year: number, month: number, day: number): boolean {\n    var date = new Date(year, month, day);\n    return (\n      date.getDate() === day &&\n      date.getMonth() === month &&\n      date.getFullYear() === year\n    );\n  }\n\n  tsToDate(timestamp: number): Date {\n    return new Date(timestamp);\n  }\n\n  dateToTs(date: Date): number {\n    return date.getTime();\n  }\n\n  getCountDaysInYear(year: number): number {\n    return ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) ? 366 : 365;\n  }\n\n  dateDiff(date1: Date, date2: Date) {\n    let date1TS = date1.getTime();\n    let date2TS = date2.getTime();\n    return this.dateDiffTs(date1TS, date2TS);\n  }\n\n  dateDiffTs(ts1: number, ts2: number): number {\n    return Math.round((ts2 - ts1) / (24 * 60 * 60 * 1000));\n  }\n\n  yearDiffTs(ts1: number, ts2: number) {\n    const toMs = (ts: number) => (ts < 1e12 ? ts * 1000 : ts); // auto sec -> ms\n    const a = new Date(Math.min(toMs(ts1), toMs(ts2)));\n    const b = new Date(Math.max(toMs(ts1), toMs(ts2)));\n\n    // années entières entre les deux dates\n    let fullYears = b.getFullYear() - a.getFullYear();\n\n    // Date de référence après avoir ajouté ces années entières\n    const ref = new Date(a);\n    ref.setFullYear(ref.getFullYear() + fullYears);\n\n    // si on a dépassé la date b, on retire 1 an\n    if (ref > b) {\n      fullYears--;\n      ref.setFullYear(ref.getFullYear() - 1);\n    }\n\n    // partie fractionnaire = proportion de l'année suivante écoulée\n    const nextYear = new Date(ref);\n    nextYear.setFullYear(nextYear.getFullYear() + 1);\n\n    const fraction =\n      (b.getTime() - ref.getTime()) / (nextYear.getTime() - ref.getTime());\n\n    return fullYears + fraction;\n  }\n\n  addMonth(date: Date, nbMonths: number) {\n    let annee = date.getFullYear();\n    let mois = date.getMonth();\n    const jour = date.getDate();\n    const nbAnnees = Math.floor(nbMonths / 12);\n    const nbMois = nbMonths % 12;\n    annee += nbAnnees;\n    mois += nbMois;\n    if (mois >= 12) {\n      mois -= 12;\n      annee += 1;\n    }\n    if (this.checkDate(annee, mois, jour)) {\n      const newMois = mois <= 8 ? '0' + (+mois + 1) : (+mois + 1);\n      const newJour = jour <= 9 ? '0' + (+jour) : (+jour);\n      const newDate = new Date(annee.toString() + '-' + newMois.toString() + '-' + newJour.toString());\n      return newDate;\n    } else {\n      for (let i = 1; i <= 3; i++) {\n        if (this.checkDate(annee, mois, jour - i)) {\n          const newMois = mois <= 8 ? '0' + (+mois + 1) : (+mois + 1);\n          const newJour = jour <= 9 ? '0' + (+jour - +i) : (+jour - +i);\n          const newDate = new Date(annee.toString() + '-' + newMois.toString() + '-' + newJour.toString());\n          return newDate;\n        }\n      }\n    }\n  }\n\n  generateDateRange(startDate: Date, endDate: Date): Date[] {\n    const dates: Date[] = [];\n    const currentDate = new Date(startDate);\n    while (currentDate <= endDate) {\n      dates.push(new Date(currentDate));\n      currentDate.setDate(currentDate.getDate() + 1); // Incrémenter d'un jour\n    }\n    return dates;\n  }\n\n  substractMonth(date: Date, nbMonths: number) {\n    let annee = date.getFullYear(); // 2023\n    let mois = date.getMonth(); // 2 Mars\n    const jour = date.getDate(); // 30\n    const nbAnnees = Math.floor(nbMonths / 12); // 0\n    const nbMois = nbMonths % 12; // 1\n    annee += nbAnnees; // 2023\n    mois -= nbMois; // 1 Férier\n    if (mois < 0) {\n      mois += 12; // -\n      annee -= 1; // -\n    }\n    if (this.checkDate(annee, mois, jour)) {\n      const newMois = mois <= 8 ? '0' + (+mois + 1) : (+mois + 1);\n      const newJour = jour <= 9 ? '0' + (+jour) : (+jour);\n      const newDate = new Date(annee.toString() + '-' + newMois.toString() + '-' + newJour.toString());\n      return newDate;\n    } else {\n      for (let i = 1; i <= 3; i++) {\n        if (this.checkDate(annee, mois, jour - i)) {\n          const newMois = mois <= 8 ? '0' + (+mois + 1) : (+mois + 1);\n          const newJour = jour <= 9 ? '0' + (+jour - +i) : (+jour - +i);\n          const newDate = new Date(annee.toString() + '-' + newMois.toString() + '-' + newJour.toString());\n          return newDate;\n        }\n      }\n    }\n  }\n\n  addYearsTs(ts: number, nbYears: number = 1) {\n    const toMs = (t: number) => (t < 1e12 ? t * 1000 : t); // auto sec -> ms\n    const d = new Date(toMs(ts));\n\n    const targetYear = d.getFullYear() + nbYears;\n    const month = d.getMonth();         // 0-11\n    const day = d.getDate();            // 1-31\n    const hours = d.getHours();\n    const minutes = d.getMinutes();\n    const seconds = d.getSeconds();\n    const millis = d.getMilliseconds();\n\n    // Dernier jour du mois cible dans l'année cible\n    const lastDayOfTargetMonth = new Date(targetYear, month + 1, 0).getDate();\n    const safeDay = Math.min(day, lastDayOfTargetMonth);\n\n    const result = new Date(targetYear, month, safeDay, hours, minutes, seconds, millis);\n\n    return result.getTime();\n  }\n\n  toMs = (t: number) => (t < 1e12 ? t * 1000 : t);\n\n  /** Construit la même date (jour/mois + heure) que init mais dans l'année `year`, en sécurisant le jour. */\n  buildSameDayMonth(init: Date, year: number): Date {\n    const month = init.getMonth();      // 0-11\n    const day = init.getDate();         // 1-31\n    const h = init.getHours();\n    const m = init.getMinutes();\n    const s = init.getSeconds();\n    const ms = init.getMilliseconds();\n\n    const lastDay = new Date(year, month + 1, 0).getDate(); // dernier jour du mois\n    const safeDay = Math.min(day, lastDay);\n    console.log('DATE INIT : ', init, ' - SAFE DAY : ', safeDay, ' - ', day, lastDay);\n\n    return new Date(year, month, safeDay, h, m, s, ms);\n  }\n\n  /**\n   * Renvoie la prochaine/dernière occurrence annuelle de tsInit\n   * strictement APRÈS (mode='next') ou strictement AVANT (mode='prev') tsRef.\n   * @param tsInit Date sur laquelle se baser pour le DD/MM\n   * @param tsRef Date sur laquelle baser l'année\n   * @param mode 'next' pour avoir le DD/MM de l'année suivant tsRef.year / 'prev' pour avoir le DD/MM de l'année précédant tsRef.year\n   * @returns \n   */\n  yearlyOccurrenceRelative(tsInit: number, tsRef: number, mode: 'next' | 'prev'): number {\n    const init = new Date(this.toMs(tsInit));\n    const ref = new Date(this.toMs(tsRef));\n    const baseYear = ref.getFullYear();\n\n    let candidate = this.buildSameDayMonth(init, baseYear);\n\n    if (mode === 'next') {\n      // si pas strictement après, prendre l'année suivante\n      if (candidate.getTime() <= ref.getTime()) {\n        candidate = this.buildSameDayMonth(init, baseYear + 1);\n      }\n    } else {\n      // mode 'prev' : si pas strictement avant, prendre l'année précédente\n      if (candidate.getTime() >= ref.getTime()) {\n        candidate = this.buildSameDayMonth(init, baseYear - 1);\n      }\n    }\n\n    return candidate.getTime();\n  }\n\n  /**\n   * Renvoie la prochaine occurrence annuelle de tsInit\n   * @param tsInit (TS) Date sur laquelle se baser pour le DD/MM\n   * @param tsAnniv (TS) Date sur laquelle baser l'année\n   * @returns (TS) DD/MM suivant tsAnniv\n   */\n  nextYearlyOccurenceAfter(tsInit: number, tsAnniv: number): number {\n    return this.yearlyOccurrenceRelative(tsInit, tsAnniv, 'next');\n  }\n\n\n  /**\n   * Renvoie la précédente occurrence annuelle de tsInit\n   * @param tsInit (TS) Date sur laquelle se baser pour le DD/MM\n   * @param tsAnniv (TS) Date sur laquelle baser l'année\n   * @returns (TS) DD/MM précédant tsAnniv\n   */\n  previousYearlyOccurenceBefore(tsInit: number, tsAnniv: number): number {\n    return this.yearlyOccurrenceRelative(tsInit, tsAnniv, 'prev');\n  }\n\n  // ARRAY\n  shuffleArray<T>(array: T[]): T[] {\n    const result = [...array]; // moderne, performant\n    for (let i = result.length; i-- > 1;) {\n      const j = Math.floor(Math.random() * (i + 1));\n      [result[i], result[j]] = [result[j], result[i]];\n    }\n    return result;\n  }\n\n  removeDuplicatesInArray(array: any[]) {\n    return array.filter((x, i) => array.indexOf(x) === i);\n  }\n\n  // NUMBER - NUMBERS - INT - INTEGER - NAN - NaN\n  isNumber(value: any): boolean {\n    if (isNaN(parseInt(value))) {\n      return false;\n    } else {\n      return true;\n    }\n  }\n\n  // PARSE - FLOAT - DECIMAL - DOUBLE - ROUND\n  parseFloatAndRound(value: any): number | null {\n    const parsed = parseFloat(value);\n    return isNaN(parsed) ? null : Math.round(parsed * 100) / 100;\n  }\n\n  // STRING - CHAINE - CHAÎNE - TYPO - TYPOGRAPHIE - TYPOGRAPHY - REPLACE - REPLACEALL \n  replaceAll(subject: string, toReplace: string, replacedBy: string) {\n    return subject.replace(new RegExp(toReplace, 'g'), replacedBy);\n  }\n\n  // STRING - CHAINE - CHAÎNE - TYPO - TYPOGRAPHIE - TYPOGRAPHY\n  shortify(chaine: string, longueur: number = 20): string {\n    if (chaine.length > longueur) {\n      return chaine.substring(0, longueur).trim() + \"...\";\n    } else {\n      return chaine;\n    }\n  }\n\n  // OCTET - OCTETS\n  formatOctets(fileSizeInBytes: number): string {\n    let i = -1;\n    let byteUnits = [' ko', ' Mo', ' Go', ' To', 'Po', 'Eo', 'Zo', 'Yo'];\n    do {\n      fileSizeInBytes = fileSizeInBytes / 1024;\n      i++;\n    } while (fileSizeInBytes > 1024);\n\n    return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i];\n  }\n\n  // FILE - NAME - FILENAME - FORMAT\n  formatFileName(nomOriginal: string, withExtension: boolean = true) {\n    const detectedEncoding = chardet.detect(Buffer.from(nomOriginal, 'binary'));\n    const nomOriginalDecode = iconv.decode(Buffer.from(nomOriginal, 'binary'), detectedEncoding).toString();\n\n    let nomFinal = nomOriginalDecode;\n    let extension = '';\n    if (withExtension) {\n      const nomOriginalDecoupe = nomOriginalDecode.split('.');\n      const nomOriginalSansExtensionDecoupe = nomOriginalDecoupe.slice(0, -1);\n      nomFinal = nomOriginalSansExtensionDecoupe.join('.');\n      extension = '.' + nomOriginalDecoupe[nomOriginalDecoupe.length - 1];\n    }\n\n    const specialCharacters = SPECIAL_CHARACTERS;\n    for (let sc of specialCharacters.specials) {\n      // nomFinal = nomFinal.replaceAll(sc.old, sc.new);\n      nomFinal = this.replaceAll(nomFinal, sc.old, sc.new);\n    }\n    nomFinal = nomFinal.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '');\n    return nomFinal + extension;\n  }\n\n  // RANDOM - RANDOMIZE\n  getRandomNumber(max: number) {\n    return Math.floor(Math.random() * max);\n  }\n\n  getRandomString(length: number, numericOnly: boolean = false) {\n    let string = \"\";\n    let characters = '0123456789';\n    if (!numericOnly)\n      characters += 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n    for (let i = 0; i < length; i++) {\n      string += characters.charAt(Math.floor(Math.random() * characters.length));\n    }\n    return string;\n  }\n\n  randomizeCharacter(char: string): string {\n    if (this.consonnesUpperCase.includes(char)) {\n      return this.consonnesUpperCase[Math.floor(Math.random() * this.consonnesUpperCase.length)];\n    } else if (this.voyellesUpperCase.includes(char)) {\n      return this.voyellesUpperCase[Math.floor(Math.random() * this.voyellesUpperCase.length)];\n    } else if (this.consonnesLowerCase.includes(char)) {\n      return this.consonnesLowerCase[Math.floor(Math.random() * this.consonnesLowerCase.length)];\n    } else if (this.voyellesLowerCase.includes(char)) {\n      return this.voyellesLowerCase[Math.floor(Math.random() * this.voyellesLowerCase.length)];\n    } else if (this.digits.includes(char)) {\n      return this.digits[Math.floor(Math.random() * this.digits.length)];\n    }\n    return char; // Ne remplace pas les caractères spéciaux ou autres\n  }\n\n  getNowDatetime() {\n    const now = new Date();\n    return new Date(Date.UTC(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours(), now.getMinutes(), now.getSeconds()));\n  }\n\n  // ANONYMIZATION - ANONYMOUS - ANONYMISE - ANONYMISATION\n  anonymizeString(input: string): string {\n    return input.split('').map(s => this.randomizeCharacter(s)).join('');\n  }\n\n  anonymizeObject(data: any, fieldsToAnonymize: string[] = []): any {\n    if (Array.isArray(data)) {\n      return data.map(item => this.anonymizeObject(item, fieldsToAnonymize));\n    } else if (data && typeof data === 'object') {\n      return Object.fromEntries(\n        Object.entries(data).map(([key, value]) => [\n          key,\n          fieldsToAnonymize.includes(key) && typeof value === 'string'\n            ? this.anonymizeString(value)\n            : this.anonymizeObject(value, fieldsToAnonymize),\n        ])\n      );\n    }\n    return data;\n  }\n}\n","export const SPECIAL_CHARACTERS = {\n    specials: [\n        { old: ' ', new: '_' },\n        { old: ' ', new: '_' },\n        { old: ' ', new: '_' },\n        { old: ',', new: '_' },\n        { old: '\\\\.', new: '_' },\n        { old: '!', new: '_' },\n        { old: `\\\\[`, new: '' },\n        { old: `\\\\]`, new: '' },\n        { old: '\\\\(', new: '' },\n        { old: '\\\\)', new: '' },\n        { old: '\\\\?', new: '_' },\n        { old: '\\\\/', new: '_' },\n        { old: \"\\\\\\\\\", new: '_' },\n        { old: '&', new: 'et' },\n        { old: \"'\", new: '_' },\n        { old: '\"', new: '' },\n        { old: '\\\\*', new: '' },\n        { old: '$', new: '' },\n        { old: '€', new: '' },\n        { old: '£', new: '' },\n        { old: '`', new: '' },\n        { old: '\\\\+', new: '' },\n        { old: '=', new: '' },\n        { old: '\\\\:', new: '' },\n        { old: ';', new: '' },\n        { old: '§', new: '' },\n        { old: '#', new: '' },\n        { old: '@', new: '' },\n        { old: '<', new: '' },\n        { old: '>', new: '' },\n        { old: '°', new: '' },\n        { old: '%', new: '' },\n    ],\n    letters: [\n        { old: 'À', new: 'A' },\n        { old: 'Â', new: 'A' },\n        { old: 'ª', new: 'A' },\n        { old: 'Æ', new: 'AE' },\n        { old: 'Á', new: 'A' },\n        { old: 'Ä', new: 'A' },\n        { old: 'Ã', new: 'A' },\n        { old: 'Å', new: 'A' },\n        { old: 'Ā', new: 'A' },\n        { old: 'Ç', new: 'C' },\n        { old: 'Ć', new: 'C' },\n        { old: 'Č', new: 'C' },\n        { old: 'É', new: 'E' },\n        { old: 'È', new: 'E' },\n        { old: 'Ê', new: 'E' },\n        { old: 'Ë', new: 'E' },\n        { old: 'Ę', new: 'E' },\n        { old: 'Ė', new: 'E' },\n        { old: 'Ē', new: 'E' },\n        { old: 'Î', new: 'I' },\n        { old: 'Ï', new: 'I' },\n        { old: 'Ì', new: 'I' },\n        { old: 'Í', new: 'I' },\n        { old: 'Į', new: 'I' },\n        { old: 'Ī', new: 'I' },\n        { old: 'Ñ', new: 'N' },\n        { old: 'Ń', new: 'N' },\n        { old: 'Ô', new: 'O' },\n        { old: 'Œ', new: 'O' },\n        { old: 'º', new: 'O' },\n        { old: 'Ö', new: 'O' },\n        { old: 'Ò', new: 'O' },\n        { old: 'Ó', new: 'O' },\n        { old: 'Õ', new: 'O' },\n        { old: 'Ø', new: 'O' },\n        { old: 'Ō', new: 'O' },\n        { old: 'Û', new: 'U' },\n        { old: 'Ù', new: 'U' },\n        { old: 'Ü', new: 'U' },\n        { old: 'Ú', new: 'U' },\n        { old: 'Ū', new: 'U' },\n        { old: 'Ý', new: 'Y' },\n        { old: 'Ÿ', new: 'Y' },\n        { old: 'à', new: 'a' },\n        { old: 'â', new: 'a' },\n        { old: 'ª', new: 'a' },\n        { old: 'æ', new: 'ae' },\n        { old: 'á', new: 'a' },\n        { old: 'ä', new: 'a' },\n        { old: 'ã', new: 'a' },\n        { old: 'å', new: 'a' },\n        { old: 'ā', new: 'a' },\n        { old: 'ç', new: 'c' },\n        { old: 'ć', new: 'c' },\n        { old: 'č', new: 'c' },\n        { old: 'é', new: 'e' },\n        { old: 'é', new: 'e' },\n        { old: 'è', new: 'e' },\n        { old: 'ê', new: 'e' },\n        { old: 'ë', new: 'e' },\n        { old: 'ę', new: 'e' },\n        { old: 'ė', new: 'e' },\n        { old: 'ē', new: 'e' },\n        { old: 'î', new: 'i' },\n        { old: 'ï', new: 'i' },\n        { old: 'ì', new: 'i' },\n        { old: 'í', new: 'i' },\n        { old: 'į', new: 'i' },\n        { old: 'ī', new: 'i' },\n        { old: 'ñ', new: 'n' },\n        { old: 'ń', new: 'n' },\n        { old: 'ô', new: 'o' },\n        { old: 'œ', new: 'o' },\n        { old: 'º', new: 'o' },\n        { old: 'ö', new: 'o' },\n        { old: 'ò', new: 'o' },\n        { old: 'ó', new: 'o' },\n        { old: 'õ', new: 'o' },\n        { old: 'ø', new: 'o' },\n        { old: 'ō', new: 'o' },\n        { old: 'û', new: 'u' },\n        { old: 'ù', new: 'u' },\n        { old: 'ü', new: 'u' },\n        { old: 'ú', new: 'u' },\n        { old: 'ū', new: 'u' },\n        { old: 'ý', new: 'y' },\n        { old: 'ÿ', new: 'y' }\n    ]\n};","import { Injectable } from \"@nestjs/common\";\nimport { OutilsService } from \"./outils.service\";\nimport { FileService } from \"./file.service\";\nimport { CldPdfContent } from \"./pdf/cld-pdf-content\";\nimport { CldPdfOptions } from \"./pdf/cld-pdf-options\";\nvar sizeOf = require('image-size');\nconst PdfPrinter = require('pdfmake');\nconst fs = require('fs');\nconst sharp = require(\"sharp\");\n\n@Injectable()\nexport class PdfService {\n    // Doc sur https://pdfmake.github.io/docs/0.1/document-definition-object/styling/\n    //  et sur http://pdfmake.org/playground.html\n\n    public document: any;\n    public logoSize: any;\n    public colors: any;\n    public fonts: any = {};\n    public stylesEP: any;\n    public stylesPDF: any;\n    public ratioA4 = 2480 / 3508;\n\n    constructor(\n        private outilsService: OutilsService,\n        private fileService: FileService,\n    ) { }\n\n    setVariablesStyle() {\n        this.colors = {\n            principal: {\n                color: '#000000',\n                background: '#DFDFE8'\n            },\n            secondary: {\n                color: '#000000',\n                background: '#DFDFE8'\n            },\n        };\n        this.stylesEP = {\n            primary: {\n                fillColor: '#DFDFE8',\n                fillOpacity: 1\n            },\n            secondary: {\n                fillColor: '#FFFFFF',\n                fillOpacity: 1\n            },\n        };\n        this.stylesPDF = {\n            header: {\n                fontSize: 18,\n                bold: true,\n                margin: [0, 0, 0, 2]\n            },\n            footer: {\n                fontSize: 10,\n                margin: [0, 0, 0, 2]\n            },\n            subheader: {\n                fontSize: 16,\n                bold: true,\n                margin: [0, 2, 0, 10]\n            },\n            normal: {\n                fontSize: 14,\n                margin: [0, 0, 0, 2]\n            },\n            details: {\n                fontSize: 12,\n                // margin: [0, 0, 0, 2]\n            },\n            headerTableLeft: {\n                margin: [0, 5, 10, 0],\n                bold: true\n            },\n            tableLeft: {\n                margin: [0, 5, 10, 5]\n            },\n            tvaNonApplicable: {\n                fontSize: 10,\n                margin: [10, 5, 0, 0],\n            },\n            penalites: {\n                fontSize: 7,\n                margin: [10, 15, 0, 0],\n                color: 'grey',\n            },\n            headerTableRight: {\n                margin: [10, 5, 0, 0],\n                bold: true\n            },\n            eSignatureInfos: {\n                fontSize: 10,\n                margin: [10, 0, 0, 0],\n                color: 'grey',\n            },\n            textAfterTableRight: {\n                fontSize: 10,\n                margin: [10, 0, 0, 0]\n            },\n            tableRight: {\n                margin: [10, 5, 0, 5]\n            },\n            table: {\n                margin: [0, 5, 0, 5]\n            },\n            tableHeader: {\n                bold: true,\n                fontSize: 10,\n                color: 'black',\n            },\n            acomptesHeader: {\n                bold: true,\n                fontSize: 10,\n                margin: [0, 12, 0, 0]\n            },\n            tableCell: {\n                fontSize: 9,\n                color: 'black',\n            },\n            tableCP: {\n                fontSize: 10,\n                color: 'black',\n            },\n            bold: {\n                bold: true\n            },\n            retrait: {\n                margin: [20, 0, 0, 0]\n            },\n            petitRetrait: {\n                margin: [5, 0, 0, 0]\n            },\n        };\n    }\n\n    // setPolice(font: string) {\n    //     this.fonts[font] = {\n    //         normal: `src/services/pdf/fonts/${font}/${font}-Regular.ttf`,\n    //         bold: `src/services/pdf/fonts/${font}/${font}-Medium.ttf`,\n    //         italics: `src/services/pdf/fonts/${font}/${font}-Medium.ttf`,\n    //         bolditalics: `src/services/pdf/fonts/${font}/${font}-Medium.ttf`\n    //     };\n    // }\n\n    async newPdf(content: CldPdfContent, options: CldPdfOptions, res: any = null, path: string = null) {\n        this.setVariablesStyle();\n        // this.setPolice(ep && ep.police ? ep.police.nom : 'Roboto');\n        var printer = new PdfPrinter(this.fonts);\n\n        var docDefinition = {\n            pageSize: options.page?.size ? options.page.size : 'A4',\n            pageOrientation: options.page?.orientation ? options.page.orientation : 'portrait',\n            pageMargins: options.page?.margin ? options.page.margin : 20,\n            defaultStyle: {\n                font: options.style?.font ? options.style.font : 'Arial'\n            },\n\n            background: function (currentPage, pageSize) {\n                return options.background?.base64 ? [{\n                    image: 'data:' + options.background.base64.mime + ';base64,' + options.background.base64.image,\n                    width: pageSize.width,\n                    height: pageSize.height,\n                    opacity: options.background.opacity ? options.background.opacity : 1,\n                    alignment: options.background.alignment ? options.background.alignment : 'center',\n                }] : null;\n            },\n\n            watermark: { text: options.watermark ? options.watermark : '' },\n\n            header: content.header ? content.header : null,\n\n            footer: content.footer ? content.footer : null,\n\n            content: content.content,\n            styles: this.stylesPDF\n        };\n\n        this.document = await printer.createPdfKitDocument(docDefinition, {});\n        const fileName = this.outilsService.formatFileName(options.file.name);\n        await this.exportPdf(fileName, res, path);\n        // if (edition.type == 'DEV' && ep && ep.cgv) {\n        //     await this.exportMergePdf(edition, nomFichier, res, path);\n        // } else if (edition.type == 'NDF' && tabJustificatifsPDF.length > 0) {\n        //     await this.exportMergeNdfPdf(edition, nomFichier, tabJustificatifsPDF, res, path);\n        // } else {\n        //     await this.exportPdf(nomFichier, res, path);\n        // }\n    }\n\n    private async exportPdf(fileName: string, res: any = null, path: string = null) {\n        if (res) {\n            this.document.pipe(res);\n        } else if (path) {\n            await this.exportPdfToPath(fileName, path);\n        }\n        await this.document.end();\n    }\n\n    private async exportPdfToPath(fileName: string, path: string) {\n        this.fileService.createFolderIfNotExists(path);\n        return new Promise(async (resolve, reject) => {\n            const stream = await fs.createWriteStream(path + this.outilsService.formatFileName(fileName + '.pdf'));\n            this.document.pipe(stream);\n            this.document.on('end', () => {\n                resolve(true);\n            });\n            this.document.end();\n        });\n    }\n\n    // private async exportMergePdf(edition: Edition, fileName: string, res: any = null, path: string = null) {\n    //     try {\n    //         const stream = new Duplex();\n    //         stream._write = async (chunk, encoding, done) => {\n    //             await stream.push(chunk);\n    //             await done();\n    //         };\n    //         stream._read = () => { };\n\n    //         await this.document.pipe(stream);\n    //         await this.document.end();\n\n    //         // Devis\n    //         const bufferPdfMakDocument = await this.outilsService.streamToArrayBuffer(this.document);\n    //         const pdfMakeDocument = await PDFDocument.load(bufferPdfMakDocument);\n    //         // CGV\n    //         const filePathCGV = await this.fileService.getFilePath(edition.structure, 'e-CGV');\n    //         const pdfCGV = await fs.promises.readFile(filePathCGV);\n    //         const pdfCgvDocument = await PDFDocument.load(pdfCGV);\n    //         // Fusionner les documents\n    //         const mergedPdfDoc = await PDFDocument.create();\n    //         const copiedPagesFromPdfMakeDoc = await mergedPdfDoc.copyPages(pdfMakeDocument, pdfMakeDocument.getPageIndices());\n    //         copiedPagesFromPdfMakeDoc.forEach(async (page) => await mergedPdfDoc.addPage(page));\n\n    //         const copiedPagesFromExistingPdfDoc = await mergedPdfDoc.copyPages(pdfCgvDocument, pdfCgvDocument.getPageIndices());\n    //         copiedPagesFromExistingPdfDoc.forEach(async (page) => await mergedPdfDoc.addPage(page));\n\n    //         // Sauvegarder le document fusionné en ArrayBuffer\n    //         const mergedPdfBytes = await mergedPdfDoc.save();\n    //         // return mergedPdfBytes;\n\n    //         if (res) {\n    //             // res.setHeader('Content-Type', 'application/pdf');\n    //             await res.send(Buffer.from(mergedPdfBytes));\n    //         } else {\n    //             const filePath = path + this.fileService.formatFileName(fileName + '.pdf');\n    //             const writeStream = fs.createWriteStream(filePath);\n\n    //             await new Promise((resolve, reject) => {\n    //                 writeStream.write(Buffer.from(mergedPdfBytes), (err) => {\n    //                     if (err) reject(err);\n    //                 });\n\n    //                 writeStream.end();\n    //                 writeStream.on('finish', resolve);\n    //                 writeStream.on('error', reject);\n    //             });\n    //         }\n    //     } catch (error) {\n    //         console.log(error);\n    //     }\n    // }\n\n    // private async exportMergeNdfPdf(edition: Edition, fileName: string, filePaths: string[], res: any = null, path: string = null) {\n    //     const stream = new Duplex();\n    //     stream._write = (chunk, encoding, done) => {\n    //         stream.push(chunk);\n    //         done();\n    //     };\n    //     stream._read = () => { };\n\n    //     this.document.pipe(stream);\n    //     this.document.end();\n\n    //     // NDF\n    //     const bufferPdfMakDocument = await this.outilsService.streamToArrayBuffer(this.document);\n    //     const pdfMakeDocument = await PDFDocument.load(bufferPdfMakDocument);\n    //     // Création du document\n    //     const mergedPdfDoc = await PDFDocument.create();\n    //     // Ajout des pages de la NDF\n    //     const copiedPagesFromPdfMakeDoc = await mergedPdfDoc.copyPages(pdfMakeDocument, pdfMakeDocument.getPageIndices());\n    //     copiedPagesFromPdfMakeDoc.forEach(page => mergedPdfDoc.addPage(page));\n\n    //     // JCs\n    //     for (let path of filePaths) {\n    //         const pdfJC = await fs.promises.readFile(path);\n    //         const pdfJcDocument = await PDFDocument.load(pdfJC);\n    //         // Fusionner JCs\n    //         const copiedPagesFromExistingPdfDoc = await mergedPdfDoc.copyPages(pdfJcDocument, pdfJcDocument.getPageIndices());\n    //         copiedPagesFromExistingPdfDoc.forEach(page => mergedPdfDoc.addPage(page));\n    //     }\n\n    //     // Sauvegarder le document fusionné en ArrayBuffer\n    //     const mergedPdfBytes = await mergedPdfDoc.save();\n\n    //     if (res) {\n    //         // res.setHeader('Content-Type', 'application/pdf');\n    //         res.send(Buffer.from(mergedPdfBytes));\n    //     } else {\n    //         const writeStream = fs.createWriteStream(path + this.fileService.formatFileName(fileName + '.pdf'));\n    //         writeStream.write(Buffer.from(mergedPdfBytes));\n    //         writeStream.end();\n    //     }\n    // }\n\n    getStylesPdf() {\n        return this.stylesPDF;\n    }\n\n    getImageSize(lien: string, baseHeight: number = 120, baseWidth: number = null) {\n        const dimensions = sizeOf(lien);\n        if (baseWidth) {\n            return {\n                width: baseWidth,\n                height: (dimensions.height * baseWidth) / dimensions.width\n            };\n        } else {\n            return {\n                width: (dimensions.width * baseHeight) / dimensions.height,\n                height: baseHeight\n            };\n        }\n    }\n\n    async getBase64ImageDimensions(base64Image) {\n        // Supprimer le préfixe de la chaîne Base64 (par exemple, 'data:image/jpeg;base64,')\n        const base64Data = base64Image.replace(/^data:image\\/\\w+;base64,/, '');\n\n        // Convertir la chaîne Base64 en un buffer\n        const imgBuffer = Buffer.from(base64Data, 'base64');\n\n        try {\n            // Utiliser sharp pour lire les métadonnées de l'image\n            const metadata = await sharp(imgBuffer).metadata();\n            return { width: metadata.width, height: metadata.height };\n        } catch (error) {\n            console.error('Error reading image metadata:', error);\n            throw error;\n        }\n    }\n\n    replaceQuillStyles(corps: any) {\n        let newCorps = corps;\n        const tabStyles = [\n            { quill: 'ql-align-center\"', css: 'ql-align-center\" style=\"text-align: center\"' },\n            { quill: 'ql-align-right\"', css: 'ql-align-right\" style=\"text-align: right\"' },\n            { quill: 'ql-align-justify\"', css: 'ql-align-justify \" style=\"text-align: justify\"' },\n        ];\n        for (let style of tabStyles) {\n            newCorps = newCorps.replaceAll(style.quill, style.css);\n        }\n        return newCorps;\n    }\n}\n","import { Injectable } from '@nestjs/common';\nconst fs = require('fs');\nconst archiver = require('archiver');\nimport { createGzip } from 'zlib';\nimport { pipeline } from 'stream/promises';\nimport { createReadStream, createWriteStream } from 'fs';\n\n@Injectable()\nexport class ZipService {\n  async zipFolder(sourceFolderPath: string, zipFilePath: string, password?: string, zipLevel: number = 9): Promise<void> {\n    const output = await fs.createWriteStream(zipFilePath);\n    let archive: any;\n    if (!password) {\n      archive = await archiver.create('zip', { zlib: { level: zipLevel } });\n    } else {\n      archive = await archiver.create('zip-encrypted', { zlib: { level: 8 }, encryptionMethod: 'aes256', password: password });\n    }\n\n    return new Promise<void>((resolve, reject) => {\n      output.on('close', () => {\n        resolve();\n      });\n\n      archive.on('error', (err) => {\n        reject(err);\n      });\n\n      archive.pipe(output);\n\n      // Ajoutez le contenu du dossier au fichier zip\n      archive.directory(sourceFolderPath, false);\n\n      // Finalisez l'archive (écrivez les fichiers zip)\n      archive.finalize();\n    });\n  }\n\n  async gzipFile(source: string, destination: string): Promise<void> {\n    await pipeline(\n      createReadStream(source),\n      createGzip({ level: 9 }),\n      createWriteStream(destination),\n    );\n  }\n}\n"],"mappings":"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E,KAAK,QAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,QAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,QAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,QAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,UAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,QAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,QAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,QAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,QAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,UAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,QAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,UAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,QAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,QAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,QAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,QAAK,KAAK,KAAK;AAAA,IACtB,EAAE,KAAK,QAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,QAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,QAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,QAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,UAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,QAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,UAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,UAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,QAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,QAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,QAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,QAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,QAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,UAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,UAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,UAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,QAAK,KAAK,IAAI;AAAA,IACrB,EAAE,KAAK,QAAK,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","names":["import_common","import_operators","_init","import_common","_init","import_common","_init","path","import_common","_init","import_common","_init","import_common","_init","moment","import_common","fs","_init","path","import_common","fs","_init"]}