From 78676d4485b331c1e95c5ec2cd6a9a921ab1ac50 Mon Sep 17 00:00:00 2001 From: Alessio Dal Santo Date: Thu, 11 Sep 2025 11:41:03 +0200 Subject: [PATCH] -Creata documentazione riguardante il progetto --- .../DOCUMENTAZIONE_DETTAGLIATA_PROGETTO.md | 591 ++++++++++++++++++ .../Data Source=wwwroot/data/credentials.db | Bin 16384 -> 0 bytes 2 files changed, 591 insertions(+) create mode 100644 Data_Coupler/DOCUMENTAZIONE_DETTAGLIATA_PROGETTO.md delete mode 100644 Data_Coupler/Data Source=wwwroot/data/credentials.db diff --git a/Data_Coupler/DOCUMENTAZIONE_DETTAGLIATA_PROGETTO.md b/Data_Coupler/DOCUMENTAZIONE_DETTAGLIATA_PROGETTO.md new file mode 100644 index 0000000..e317574 --- /dev/null +++ b/Data_Coupler/DOCUMENTAZIONE_DETTAGLIATA_PROGETTO.md @@ -0,0 +1,591 @@ +# Data-Coupler: Documentazione Completa del Progetto + +## Indice +1. [Descrizione Generale del Progetto](#descrizione-generale-del-progetto) +2. [Architettura e Struttura del Progetto](#architettura-e-struttura-del-progetto) +3. [Mappatura dei Progetti della Soluzione](#mappatura-dei-progetti-della-soluzione) +4. [Funzionalità Dettagliate](#funzionalità-dettagliate) +5. [Mappa delle Funzioni e Procedure](#mappa-delle-funzioni-e-procedure) +6. [Riferimenti Esterni e Percorsi](#riferimenti-esterni-e-percorsi) +7. [Interconnessioni tra Componenti](#interconnessioni-tra-componenti) +8. [Stato delle Implementazioni](#stato-delle-implementazioni) +9. [Utilizzo e Configurazione](#utilizzo-e-configurazione) + +--- + +## Descrizione Generale del Progetto + +**Data-Coupler** è un sistema avanzato per l'accoppiamento e sincronizzazione di dati tra diverse fonti di dati e destinazioni. Il progetto è sviluppato in .NET 9.0 utilizzando Blazor Server e fornisce un'interfaccia web intuitiva per configurare, gestire ed eseguire operazioni di trasferimento dati. + +### Funzionalità Principali +- **Connessione Multi-Database**: Supporta SQL Server, MySQL, PostgreSQL, Oracle, SQLite, DB2, SAP HANA +- **Integrazione REST API**: Supporta API generiche, Salesforce, SAP Business One Service Layer +- **Elaborazione File**: Gestisce file Excel (.xlsx, .xls) e CSV +- **Sistema di Mapping**: Mappatura intelligente dei campi tra sorgenti e destinazioni +- **Gestione Associazioni**: Sistema di tracking delle chiavi per evitare duplicati +- **Gestione Profili**: Salvataggio e riutilizzo di configurazioni +- **Background Services**: Servizi in background per operazioni periodiche +- **Sicurezza**: Crittografia delle credenziali cross-platform + +### Caratteristiche Tecniche +- **Framework**: .NET 9.0, Blazor Server +- **Database**: SQLite con Entity Framework Core +- **UI**: Bootstrap 5, Font Awesome +- **Architettura**: Modulare con separazione delle responsabilità +- **Cross-Platform**: Windows, Linux, macOS + +--- + +## Architettura e Struttura del Progetto + +Il progetto segue un'architettura modulare con separazione chiara delle responsabilità: + +``` +Data-Coupler/ +├── Data_Coupler/ # Applicazione principale Blazor Server +├── DataConnection/ # Libreria per connessioni dati +├── CredentialManager/ # Gestione sicura delle credenziali +├── Components/ # Componenti UI riutilizzabili +└── Documentation/ # File di documentazione +``` + +### Principi Architetturali +1. **Separation of Concerns**: Ogni progetto ha responsabilità specifiche +2. **Dependency Injection**: Utilizzo estensivo di DI per loose coupling +3. **Factory Pattern**: Per la creazione di connessioni database e REST +4. **Repository Pattern**: Per l'accesso ai dati +5. **Service Layer**: Logica business separata dalla presentazione + +--- + +## Mappatura dei Progetti della Soluzione + +### 1. Data_Coupler (Progetto Principale) +**Tipo**: Applicazione Web Blazor Server +**Tecnologie**: .NET 9.0, Blazor Server, Bootstrap 5 +**Responsabilità**: Interfaccia utente principale e orchestrazione + +#### Strutture Principali: +- **Pages/**: Pagine Blazor per le diverse funzionalità + - `DataCoupler.razor(.cs)`: Pagina principale per il trasferimento dati + - `ProfilesManagement.razor(.cs)`: Gestione dei profili salvati + - `CredentialManagement.razor`: Gestione delle credenziali + - `KeyAssociations.razor`: Gestione delle associazioni chiavi +- **Extensions/DataCoupler/**: Metodi estesi per funzionalità specifiche + - `DatabaseMethod.cs`: Metodi per connessioni database + - `RESTMethod.cs`: Metodi per connessioni REST API +- **Services/**: Servizi dell'applicazione + - `DataConnectionFactory.cs`: Factory per connessioni dati +- **Models/**: Modelli di dati specifici dell'app + - `DataCouplerModels.cs`: Modelli per risultati trasferimenti +- **BackgroundServices/**: Servizi in background + - `BackgroundServices.cs`: Servizi periodici (attualmente placeholder) + +### 2. DataConnection (Libreria Core) +**Tipo**: Class Library +**Responsabilità**: Gestione connessioni database e REST API + +#### Strutture Principali: +- **DB/**: Gestione database + - **Interfaces/**: Interfacce per abstraction layer + - `IDatabaseManager.cs`: Interfaccia principale per database + - `IDatabaseSchemaProvider.cs`: Provider per schema discovery + - `IDatabaseDiscovery.cs`: Discovery di database disponibili + - **EF/**: Implementazioni Entity Framework + - `EFCoreDatabaseManager.cs`: Manager EF Core per database esistenti + - **DatabaseDiscovery/**: Discovery specifiche per DB type +- **REST/**: Gestione REST API + - **Interfaces/**: Interfacce REST + - **Implementations/**: Implementazioni specifiche (Salesforce, Generic) + - **Models/**: Modelli per richieste/risposte REST +- **CredentialManagement/**: Integrazione con CredentialManager + +### 3. CredentialManager (Gestione Credenziali) +**Tipo**: Class Library +**Responsabilità**: Gestione sicura delle credenziali + +#### Strutture Principali: +- **Data/**: Contesto Entity Framework + - `CredentialDbContext.cs`: DbContext per credenziali +- **Models/**: Modelli di dati + - `CredentialModels.cs`: DTOs per credenziali + - `CredentialEntity.cs`: Entità database + - `KeyAssociation.cs`: Modello per associazioni chiavi + - `DataCouplerProfile.cs`: Modello per profili salvati +- **Services/**: Servizi di gestione + - `CredentialService.cs`: Servizio principale per credenziali + - `DataCouplerProfileService.cs`: Gestione profili +- **Utilities/**: Utilità varie + - `EncryptionService.cs`: Crittografia cross-platform +- **Integration/**: Helper per integrazione + - `DataConnectionHelper.cs`: Utilità per DataConnection + +### 4. Components (Componenti UI) +**Tipo**: Razor Class Library +**Responsabilità**: Componenti UI riutilizzabili + +#### Componenti Principali: +- `ProfileManagement.razor(.cs)`: Componente per gestione profili +- `ProfileSelector.razor(.cs)`: Selettore di profili +- `ProfileSaver.razor(.cs)`: Componente per salvare profili + +--- + +## Funzionalità Dettagliate + +### 1. Gestione Sorgenti Dati + +#### Connessioni Database +- **Supporto Multi-DB**: SQL Server, MySQL, PostgreSQL, Oracle, SQLite, DB2, SAP HANA +- **Schema Discovery**: Automatic discovery di tabelle, colonne e metadati +- **Query Custom**: Supporto per query SQL personalizzate +- **Connection String Generation**: Generazione automatica connection string +- **Test Connessioni**: Validazione connessioni prima dell'uso + +#### Elaborazione File +- **Formati Supportati**: Excel (.xlsx, .xls), CSV +- **Multi-Sheet**: Gestione fogli multipli in Excel +- **Preview Data**: Anteprima dati con paginazione +- **Encoding Detection**: Rilevamento automatico encoding + +#### Connessioni REST API +- **API Generiche**: Supporto per REST API standard +- **Salesforce**: Integrazione specifica con autenticazione OAuth +- **SAP B1 Service Layer**: Integrazione con SAP Business One +- **Composite API**: Ottimizzazione per operazioni batch (Salesforce) + +### 2. Sistema di Mapping + +#### Mapping Campi +- **Drag & Drop**: Interfaccia intuitiva per mapping +- **Auto-Detection**: Rilevamento automatico campi simili +- **Validazione**: Controllo compatibilità tipi dati +- **Preview**: Anteprima risultati mapping + +#### Gestione Chiavi +- **Chiavi Sorgente**: Identificazione univoca record sorgente +- **Chiavi Destinazione**: Tracking ID destinazione +- **Associazioni**: Sistema di associazioni per evitare duplicati +- **Hash Verification**: Controllo modifiche tramite hash dati + +### 3. Trasferimento Dati + +#### Modalità di Trasferimento +- **Insert**: Creazione nuovi record +- **Update**: Aggiornamento record esistenti +- **Upsert**: Insert o update automatico +- **Batch Processing**: Elaborazione in lotti per performance + +#### Gestione Errori +- **Logging Dettagliato**: Log completi di ogni operazione +- **Error Handling**: Gestione granulare degli errori +- **Rollback**: Possibilità di rollback operazioni +- **Report Risultati**: Report dettagliati successi/errori + +### 4. Gestione Profili + +#### Salvataggio Configurazioni +- **Profili Completi**: Salvataggio di tutte le configurazioni +- **Metadati**: Nome, descrizione, data creazione/utilizzo +- **Versioning**: Gestione versioni profili +- **Export/Import**: Esportazione profili in JSON + +#### Gestione Profili +- **Lista Profili**: Visualizzazione tutti i profili salvati +- **Filtri**: Ricerca per nome, tipo, utilizzo +- **Statistiche**: Dashboard con statistiche utilizzo +- **Eliminazione**: Soft delete profili + +--- + +## Mappa delle Funzioni e Procedure + +### Data_Coupler.Pages.DataCoupler + +#### Metodi di Gestione Stato +- `OnInitializedAsync()`: Inizializzazione componente +- `LoadCredentials()`: Caricamento credenziali database/REST +- `LoadProfiles()`: Caricamento profili disponibili +- `ResetAllState()`: Reset completo stato applicazione + +#### Metodi Database (DatabaseMethod.cs) +- `ConnectToDatabase()`: Connessione database principale +- `ConnectToDatabaseWithSpecificDatabase(string)`: Connessione a DB specifico +- `ConnectToDatabaseWithSchema(string)`: Connessione con schema specifico +- `LoadTablesFromConnectedDatabase()`: Caricamento tabelle +- `LoadAvailableDatabases()`: Discovery database disponibili +- `SelectTable(string)`: Selezione tabella e caricamento schema +- `ValidateCustomQuery()`: Validazione query personalizzate +- `LoadQueryPreview()`: Anteprima risultati query + +#### Metodi REST (RESTMethod.cs) +- `ConnectToRestService()`: Connessione servizio REST +- `LoadRestMetadata()`: Caricamento metadati REST +- `TestRestConnection()`: Test connessione REST API + +#### Metodi File +- `ProcessFileUpload()`: Elaborazione file caricati +- `LoadFileData()`: Lettura dati da file +- `ParseExcelFile()`: Parsing file Excel +- `ParseCsvFile()`: Parsing file CSV + +#### Metodi Mapping +- `MapField(string, string)`: Mapping singolo campo +- `RemoveMapping(string)`: Rimozione mapping +- `ClearAllMappings()`: Reset tutti i mapping +- `ValidateMapping()`: Validazione configurazione mapping +- `AutoMapFields()`: Auto-mapping campi simili + +#### Metodi Trasferimento +- `StartDataTransfer()`: Avvio trasferimento standard +- `StartDataTransferWithComposite()`: Trasferimento con Composite API +- `ProcessRecord()`: Elaborazione singolo record +- `CreateAssociationAsync()`: Creazione associazione chiave +- `UpdateAssociationHashAsync()`: Aggiornamento hash associazione + +#### Metodi Profili +- `OnProfileLoaded()`: Caricamento profilo salvato +- `ApplyProfileConfiguration()`: Applicazione configurazione profilo +- `SaveCurrentProfile()`: Salvataggio profilo corrente + +### DataConnection.EF.EFCoreDatabaseManager + +#### Metodi Core +- `TestConnectionAsync()`: Test connessione database +- `GetDatabaseSchemaAsync()`: Recupero schema completo +- `GetAvailableDatabasesAsync()`: Lista database disponibili +- `ChangeDatabaseAsync(string)`: Cambio database corrente + +#### Metodi CRUD Generici +- `GetAsync()`: Query generiche con filtri +- `GetByIdAsync(object)`: Recupero per ID +- `CreateAsync(T)`: Creazione entity +- `UpdateAsync(T)`: Aggiornamento entity +- `DeleteAsync(T)`: Eliminazione entity + +#### Metodi SQL Raw +- `ExecuteRawSqlAsync(string, object[])`: Esecuzione SQL raw +- `ExecuteCommandAsync(string, object[])`: Comandi SQL + +### CredentialManager.Services.CredentialService + +#### Gestione Credenziali Database +- `SaveDatabaseCredentialAsync()`: Salvataggio credenziali DB +- `GetDatabaseCredentialAsync()`: Recupero credenziali DB +- `GetAllDatabaseCredentialsAsync()`: Lista tutte credenziali DB +- `TestDatabaseConnectionAsync()`: Test connessione DB + +#### Gestione Credenziali REST +- `SaveRestApiCredentialAsync()`: Salvataggio credenziali REST +- `GetRestApiCredentialAsync()`: Recupero credenziali REST +- `GetAllRestApiCredentialsAsync()`: Lista tutte credenziali REST +- `TestRestConnectionAsync()`: Test connessione REST + +#### Gestione Associazioni Chiavi +- `SaveKeyAssociationAsync()`: Salvataggio associazione +- `FindKeyAssociationByValueAsync()`: Ricerca per valore chiave +- `UpdateKeyAssociationAsync()`: Aggiornamento associazione +- `GetKeyAssociationsAsync()`: Lista associazioni + +### CredentialManager.Services.DataCouplerProfileService + +#### Gestione Profili +- `SaveProfileAsync()`: Salvataggio nuovo profilo +- `UpdateProfileAsync()`: Aggiornamento profilo esistente +- `GetAllProfilesAsync()`: Lista tutti i profili +- `GetProfileByIdAsync()`: Recupero profilo per ID +- `GetProfileByNameAsync()`: Recupero profilo per nome +- `DeleteProfileAsync()`: Eliminazione profilo (soft delete) +- `UpdateLastUsedAsync()`: Aggiornamento ultimo utilizzo + +#### Utilità Profili +- `ProfileExistsAsync()`: Verifica esistenza profilo +- `SerializeFieldMappings()`: Serializzazione mapping +- `DeserializeFieldMappings()`: Deserializzazione mapping +- `ToDto()`: Conversione a DTO +- `FromDto()`: Conversione da DTO + +--- + +## Riferimenti Esterni e Percorsi + +### Database SQLite Principale +**Percorso**: +- **Windows**: `%ProgramData%\Data_Coupler\credentials.db` +- **Linux**: `/var/lib/Data_Coupler/credentials.db` +- **macOS**: `/Library/Application Support/Data_Coupler/credentials.db` + +### Tabelle Database +1. **Credentials**: Memorizzazione credenziali crittografate +2. **KeyAssociations**: Associazioni chiavi sorgente-destinazione +3. **DataCouplerProfiles**: Profili di configurazione salvati + +### File di Configurazione +- `appsettings.json`: Configurazione generale +- `appsettings.Development.json`: Configurazione sviluppo +- `nuget.config`: Configurazione pacchetti NuGet + +### Dipendenze Esterne Principali +- **Microsoft.EntityFrameworkCore**: ORM per database +- **ExcelDataReader**: Lettura file Excel +- **System.Data.SqlClient**: SQL Server +- **MySqlConnector**: MySQL +- **Npgsql**: PostgreSQL +- **Oracle.ManagedDataAccess**: Oracle +- **IBM.Data.Db2**: DB2 + +### Porte di Default +- **Applicazione Web**: `http://localhost:7550` +- **SQL Server**: 1433 +- **MySQL**: 3306 +- **PostgreSQL**: 5432 +- **Oracle**: 1521 + +--- + +## Interconnessioni tra Componenti + +### Flusso di Dipendenze +``` +Data_Coupler (App) +├── CredentialManager (Gestione Credenziali) +├── DataConnection (Connessioni Dati) +├── Components (UI Components) +└── Background Services +``` + +### Interazioni Principali + +#### 1. Caricamento Credenziali +``` +Data_Coupler → CredentialManager.CredentialService → SQLite Database +``` + +#### 2. Connessione Database +``` +Data_Coupler → DataConnectionFactory → DataConnection.EF.EFCoreDatabaseManager → Database Target +``` + +#### 3. Connessione REST +``` +Data_Coupler → DataConnectionFactory → DataConnection.REST.Implementations → REST API +``` + +#### 4. Gestione Profili +``` +Data_Coupler → CredentialManager.DataCouplerProfileService → SQLite Database +``` + +### Pattern di Comunicazione + +#### Dependency Injection +Tutti i servizi sono registrati nel container DI e iniettati dove necessario: +```csharp +// Program.cs +builder.Services.AddDataConnectionCredentialManagement(dbPath); +builder.Services.AddScoped(); +``` + +#### Factory Pattern +Le connessioni sono create tramite factory per garantire configurazione corretta: +```csharp +var dbManager = await ConnectionFactory.CreateDatabaseManagerAsync(credentialName); +var restClient = await ConnectionFactory.CreateRestServiceClientAsync(credentialName); +``` + +#### Service Layer +La logica business è incapsulata in servizi dedicati: +- `CredentialService`: Gestione credenziali +- `DataCouplerProfileService`: Gestione profili +- `DataConnectionFactory`: Creazione connessioni + +--- + +## Stato delle Implementazioni + +### ✅ Funzionalità Completamente Implementate + +#### Gestione Credenziali +- ✅ Salvataggio/recupero credenziali database +- ✅ Salvataggio/recupero credenziali REST API +- ✅ Crittografia cross-platform +- ✅ Test connessioni +- ✅ Validazione credenziali + +#### Connessioni Database +- ✅ Supporto multi-database (SQL Server, MySQL, PostgreSQL, etc.) +- ✅ Schema discovery automatico +- ✅ Query personalizzate +- ✅ Gestione connection string + +#### Connessioni REST +- ✅ API generiche +- ✅ Integrazione Salesforce completa +- ✅ Salesforce Composite API per performance +- ✅ Autenticazione OAuth + +#### Elaborazione File +- ✅ Lettura Excel (.xlsx, .xls) +- ✅ Lettura CSV +- ✅ Preview dati con paginazione +- ✅ Gestione multi-sheet + +#### Sistema Mapping +- ✅ Mapping manuale campi +- ✅ Auto-detection campi simili +- ✅ Validazione mapping +- ✅ Preview risultati + +#### Gestione Associazioni +- ✅ Tracking chiavi sorgente-destinazione +- ✅ Prevenzione duplicati +- ✅ Hash verification per rilevare modifiche +- ✅ Gestione update vs insert intelligente + +#### Gestione Profili +- ✅ Salvataggio configurazioni complete +- ✅ Caricamento profili salvati +- ✅ Lista e gestione profili +- ✅ Statistiche utilizzo +- ✅ Export/import JSON + +### 🔄 Funzionalità Parzialmente Implementate + +#### Background Services +- 🔄 **Struttura base**: Implementata ma placeholder +- 🔄 **Servizi specifici**: Da implementare funzionalità specifiche +- 🔄 **Scheduling**: Da aggiungere scheduling operazioni + +#### Gestione Errori Avanzata +- 🔄 **Logging base**: Implementato +- 🔄 **Error recovery**: Parziale +- 🔄 **Rollback automatico**: Da implementare + +#### Performance Optimization +- 🔄 **Batch processing**: Implementato per Salesforce +- 🔄 **Parallelizzazione**: Parziale +- 🔄 **Caching**: Base implementato + +#### Security Features +- 🔄 **Autenticazione utente**: Da implementare +- 🔄 **Autorizzazione**: Da implementare +- 🔄 **Audit trail**: Parziale + +### ❌ Funzionalità Da Implementare + +#### Integrazione Database Avanzata +- ❌ **Supporto Stored Procedures**: Da implementare +- ❌ **Triggers**: Da implementare +- ❌ **Views materialized**: Da implementare + +#### API Extensions +- ❌ **GraphQL**: Da implementare +- ❌ **SAP B1 Service Layer completo**: Struttura presente ma da completare +- ❌ **Altri ERP**: Da aggiungere + +#### Data Transformation +- ❌ **Trasformazioni custom**: Da implementare +- ❌ **Formule/Calcoli**: Da implementare +- ❌ **Data cleansing**: Da implementare + +#### Monitoring & Analytics +- ❌ **Dashboard performance**: Da implementare +- ❌ **Metriche dettagliate**: Da implementare +- ❌ **Alerting**: Da implementare + +#### Advanced Features +- ❌ **Real-time sync**: Da implementare +- ❌ **Conflict resolution**: Da implementare +- ❌ **Multi-tenant**: Da implementare +- ❌ **REST API del Data Coupler**: Da implementare + +--- + +## Utilizzo e Configurazione + +### Configurazione Iniziale + +1. **Compilazione e Avvio**: + ```bash + dotnet run --project Data_Coupler/Data_Coupler.csproj + ``` + +2. **Accesso Web Interface**: + - URL: `http://localhost:7550` + - L'applicazione inizializza automaticamente il database SQLite + +### Workflow Tipico + +#### 1. Configurazione Credenziali +- Accedere alla sezione "Gestione Credenziali" +- Aggiungere credenziali database e/o REST API +- Testare le connessioni + +#### 2. Configurazione Trasferimento +- Selezionare tipo sorgente (Database/File) +- Configurare connessione sorgente +- Configurare destinazione REST API +- Definire mapping campi +- Configurare gestione chiavi + +#### 3. Esecuzione Trasferimento +- Avviare trasferimento dati +- Monitorare progresso +- Verificare risultati + +#### 4. Gestione Profili (Opzionale) +- Salvare configurazione come profilo +- Riutilizzare profili per operazioni ricorrenti + +### Configurazioni Avanzate + +#### Database Path Personalizzato +Modificare `Program.cs` per percorso custom: +```csharp +string customDbPath = "/path/to/custom/credentials.db"; +builder.Services.AddDataConnectionCredentialManagement($"Data Source={customDbPath}"); +``` + +#### Logging Personalizzato +Configurare logging in `Program.cs`: +```csharp +builder.Logging.AddConsole(); +builder.Logging.SetMinimumLevel(LogLevel.Debug); +``` + +#### Performance Tuning +- **Batch Size**: Configurabile nel codice per operazioni batch +- **Timeout**: Configurabile per connessioni database/REST +- **Memory**: Gestione automatica, configurabile per file grandi + +### Troubleshooting + +#### Problemi Comuni +1. **Database Lock**: Riavviare applicazione +2. **Credenziali non funzionanti**: Verificare test connessione +3. **File non leggibili**: Verificare formato e permissions +4. **API Rate Limiting**: Configurare delays appropriati + +#### Log Files +I log sono disponibili nella console dell'applicazione e possono essere configurati per output su file. + +--- + +## Conclusioni + +Data-Coupler rappresenta una soluzione robusta e flessibile per l'integrazione di dati tra diverse piattaforme. L'architettura modulare consente estensioni future, mentre le funzionalità già implementate coprono la maggior parte dei casi d'uso comuni. + +Il progetto è in uno stato maturo per quanto riguarda le funzionalità core, con spazio per miglioramenti in aree come monitoring, security avanzata e funzionalità enterprise. + +### Prossimi Sviluppi Consigliati +1. Implementazione sistema di autenticazione utenti +2. Dashboard analytics e monitoring +3. API REST per automazione +4. Supporto trasformazioni dati avanzate +5. Integrazione con sistemi di workflow + +--- + +**Versione Documentazione**: 1.0 +**Data**: 11 Settembre 2025 +**Autore**: Sistema di Documentazione Automatica Data-Coupler diff --git a/Data_Coupler/Data Source=wwwroot/data/credentials.db b/Data_Coupler/Data Source=wwwroot/data/credentials.db deleted file mode 100644 index c49af94f222fb0a27f426718c88f954254caaa0b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI%Z%czf90%}oM#W%m&-V0?9u&23<{XS3WW#FY=5iL>gAi*L(w3zTs%P~wdk4LX zyxNM&Mm-4@-yfWJp1=F!$47^q1H+F!dKQF3H>Mk;Ksb(UQA!Az8<(VdiA-{3eUsoO zjVbjUS--o^9W0SG_<0uX=z1Rwwb2teSE1n#?;g<`eJJ(#h3 zGVmNn-)Z{ip&R?bWwhruc86DAS#s<}3WVezSpxw92tWV=5P$##AOHafKmY;| zfWT}CEO9(BWl64-B(+plsVvu|YE6;XRYj^Os=O*mHA$MB|7Yvnuv-W~00Izz00bZa s0SG_<0uX=z1b!osWy#6^e*^>|009U<00Izz00bZa0SG_<0{>Uw8J9S$0RR91