{"_id":"@dapia-project/alteration-ts","_rev":"3-8cb99cac497e7f7a95b740a15cf32d47","name":"@dapia-project/alteration-ts","dist-tags":{"latest":"0.2.0"},"versions":{"0.0.1":{"name":"@dapia-project/alteration-ts","version":"0.0.1","keywords":[],"author":"","license":"ISC","_id":"@dapia-project/alteration-ts@0.0.1","maintainers":[{"name":"aymerictn","email":"aymeric.cretin@smartesting.com"},{"name":"morgan_leclercq","email":"morgan.leclercq@smartesting.com"}],"dist":{"shasum":"df42cd5ea0cbcbc472a03b95d1c91a65ffc42a9c","tarball":"https://registry.npmjs.org/@dapia-project/alteration-ts/-/alteration-ts-0.0.1.tgz","fileCount":64,"integrity":"sha512-7zXWgozZH9SkWL29jhht5FMchn8CJjVNGdMybZjBWom4G7bLS6zkIuYDWVFZGwS5w556ziJyGS1TxUhW1g8AYw==","signatures":[{"sig":"MEUCIGj1KHjc0evVpQ0mSVdimuKTCkW+IHWym3KoG6BPGXVmAiEA09lQbzbAoZIPd3z2X4FA38BbQuSQVB1PiX6V2jrXDx0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":119672},"type":"module","types":"./index.d.ts","gitHead":"2ad4346704ae3a3a4f15b8585526661e499bf5ef","scripts":{"test":"mocha --inspect -r ts-node/register 'tests/**/*.ts'","build":"tsc"},"_npmUser":{"name":"aymerictn","email":"aymeric.cretin@smartesting.com"},"_npmVersion":"10.7.0","description":"latex leader:\tmmd6-article-leader latex begin:\tmmd6-article-begin latex footer:\tmmd6-article-footer Base Header level : 3","directories":{},"_nodeVersion":"18.20.4","dependencies":{"chai-deep-closeto":"^0.1.1"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.7.0","chai":"^4.3.10","mocha":"^10.2.0","ts-node":"^10.9.2","ts-mocha":"^10.0.0","fast-check":"^3.19.0","typescript":"^5.3.3","@types/chai":"^4.3.11","@types/node":"^20.10.4","worldwindjs":"^1.9.5","@types/mocha":"^10.0.6","commons-math-interpolation":"^2.2.3"},"_npmOperationalInternal":{"tmp":"tmp/alteration-ts_0.0.1_1728998207196_0.11699792562008637","host":"s3://npm-registry-packages"}},"0.0.2":{"name":"@dapia-project/alteration-ts","version":"0.0.2","keywords":[],"author":"","license":"ISC","_id":"@dapia-project/alteration-ts@0.0.2","maintainers":[{"name":"aymerictn","email":"aymeric.cretin@smartesting.com"},{"name":"morgan_leclercq","email":"morgan.leclercq@smartesting.com"}],"dist":{"shasum":"04a5e7251e191eadb2f9b57122ec0def874da289","tarball":"https://registry.npmjs.org/@dapia-project/alteration-ts/-/alteration-ts-0.0.2.tgz","fileCount":64,"integrity":"sha512-fOY6kkJ6kqLWoA1wAkXIK34CwZn0gN3FTupyQkvLuu33WbnBGucgLgaZ+Lof2LEogd93wVWSxr8tgYNh0Tx3qA==","signatures":[{"sig":"MEUCIDV6BNuhDI5EVVZNIv2ziMAcsTxRGIjM3IWGhBZdaSV4AiEAgEat6VFQaRo6NiQZxbZWIOsYZV7OcI7wKqMaxUD8xEY=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":119674},"type":"module","types":"./index.d.ts","gitHead":"017f7f1e88c39ae724fbc8bd35529240553e5b96","scripts":{"test":"mocha --inspect -r ts-node/register 'tests/**/*.ts'","build":"tsc"},"_npmUser":{"name":"aymerictn","email":"aymeric.cretin@smartesting.com"},"_npmVersion":"10.7.0","description":"latex leader:\tmmd6-article-leader latex begin:\tmmd6-article-begin latex footer:\tmmd6-article-footer Base Header level : 3","directories":{},"_nodeVersion":"18.20.4","dependencies":{"chai-deep-closeto":"^0.1.1"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.7.0","chai":"^4.3.10","mocha":"^10.2.0","ts-node":"^10.9.2","ts-mocha":"^10.0.0","fast-check":"^3.19.0","typescript":"^5.3.3","@types/chai":"^4.3.11","@types/node":"^20.10.4","worldwindjs":"^1.9.5","@types/mocha":"^10.0.6","commons-math-interpolation":"^2.2.3"},"_npmOperationalInternal":{"tmp":"tmp/alteration-ts_0.0.2_1729068286823_0.6552312720091684","host":"s3://npm-registry-packages"}},"0.1.0":{"name":"@dapia-project/alteration-ts","version":"0.1.0","keywords":[],"author":"","license":"ISC","_id":"@dapia-project/alteration-ts@0.1.0","maintainers":[{"name":"aymerictn","email":"aymeric.cretin@smartesting.com"},{"name":"morgan_leclercq","email":"morgan.leclercq@smartesting.com"}],"dist":{"shasum":"1aef777169e5e14ce2a28afcde999e35b17ff165","tarball":"https://registry.npmjs.org/@dapia-project/alteration-ts/-/alteration-ts-0.1.0.tgz","fileCount":61,"integrity":"sha512-8FyncGZo3bheREDtgZpR9e0kU04ZFAdSb5PumF26Fuvc9tipbKBKLHsgmSSRk2kaX6gAS2REQN50I+Ay+UFESQ==","signatures":[{"sig":"MEYCIQCou/XxGilko8xwTwGzsAp5nIbtpdD1e6YPogTpU1z+jAIhAMNos6WX3VifnBEdp4JI13pmNzN9iysCbNzdeOhzzl+L","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":120986},"type":"module","types":"./index.d.ts","gitHead":"04224a2099520873af355b733f782b63f66a3663","scripts":{"test":"mocha --inspect -r ts-node/register 'tests/**/*.ts'","build":"tsc"},"_npmUser":{"name":"aymerictn","email":"aymeric.cretin@smartesting.com"},"_npmVersion":"10.7.0","description":"latex leader: mmd6-article-leader latex begin: mmd6-article-begin latex footer: mmd6-article-footer Base Header level : 3","directories":{},"_nodeVersion":"18.20.4","dependencies":{"chai-deep-closeto":"^0.1.1"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.7.0","chai":"^4.3.10","mocha":"^10.2.0","ts-node":"^10.9.2","ts-mocha":"^10.0.0","fast-check":"^3.19.0","typescript":"^5.3.3","@types/chai":"^4.3.11","@types/node":"^20.10.4","worldwindjs":"^1.9.5","@types/mocha":"^10.0.6","commons-math-interpolation":"^2.2.3"},"_npmOperationalInternal":{"tmp":"tmp/alteration-ts_0.1.0_1729599960285_0.2694196505185291","host":"s3://npm-registry-packages"}},"0.2.0":{"name":"@dapia-project/alteration-ts","version":"0.2.0","description":"latex leader: mmd6-article-leader latex begin: mmd6-article-begin latex footer: mmd6-article-footer Base Header level : 3","type":"module","scripts":{"test":"mocha --inspect -r ts-node/register 'tests/**/*.ts'","build":"tsc"},"keywords":[],"author":"","license":"ISC","devDependencies":{"@types/chai":"^4.3.11","@types/mocha":"^10.0.6","@types/node":"^20.10.4","chai":"^4.3.10","commons-math-interpolation":"^2.2.3","fast-check":"^3.19.0","mocha":"^10.2.0","ts-mocha":"^10.0.0","ts-node":"^10.9.2","tsx":"^4.7.0","typescript":"^5.3.3","worldwindjs":"^1.9.5"},"dependencies":{"chai-deep-closeto":"^0.1.1"},"_id":"@dapia-project/alteration-ts@0.2.0","gitHead":"3589b591a3ae12f476a0943c58abc1bd838d0e63","types":"./index.d.ts","_nodeVersion":"18.20.5","_npmVersion":"10.8.2","dist":{"integrity":"sha512-TM4nWrvUoOnNNZ3P9nyp5msVe200cbqOaeaVvtVP1Y2YPCnUut3R3fH4LOsnOHDAwrsIZDT/+Qdw8eKMX6rsRw==","shasum":"f219f02b30e6d6cf7c00937fddc7b7e715b19c7b","tarball":"https://registry.npmjs.org/@dapia-project/alteration-ts/-/alteration-ts-0.2.0.tgz","fileCount":61,"unpackedSize":121942,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEeN13PDAmcDUyPgjBnFqMWIrlWdg2SDeMMOp7FCnhMRAiBUiNLlD5UenPAg1efAAWV/YMW+d79M7ydRsyxXuM9iCw=="}]},"_npmUser":{"name":"aymerictn","email":"aymeric.cretin@smartesting.com"},"directories":{},"maintainers":[{"name":"morgan_leclercq","email":"morgan.leclercq@smartesting.com"},{"name":"aymerictn","email":"aymeric.cretin@smartesting.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/alteration-ts_0.2.0_1734516623812_0.5450465708012247"},"_hasShrinkwrap":false}},"time":{"created":"2024-10-15T13:16:47.111Z","modified":"2024-12-18T10:10:24.263Z","0.0.1":"2024-10-15T13:16:47.359Z","0.0.2":"2024-10-16T08:44:47.028Z","0.1.0":"2024-10-22T12:26:00.508Z","0.2.0":"2024-12-18T10:10:24.041Z"},"license":"ISC","keywords":[],"description":"latex leader: mmd6-article-leader latex begin: mmd6-article-begin latex footer: mmd6-article-footer Base Header level : 3","maintainers":[{"name":"morgan_leclercq","email":"morgan.leclercq@smartesting.com"},{"name":"aymerictn","email":"aymeric.cretin@smartesting.com"}],"readme":"latex leader: mmd6-article-leader\nlatex begin: mmd6-article-begin\nlatex footer: mmd6-article-footer\nBase Header level : 3\n\n# Documentation du moteur d'altération\n\nLe moteur d'altération permet au projet DApIA de générer des cas de tests. En\neffet, le projet à pour but de détecter des attaques par injection de fausses\ndonnées dans le cadre du protocole ADS-B.\nPour pouvoir confirmer le bon fonctionnement des modèles de détection, il faut\npouvoir générer des données de tests, c'et-à-dire des fichiers ADS-B, dont les\ndonnées auraient été altérés.\n\nLe moteur d'altération sert donc à écrire les scénarios de générations des données altérées.\nCelui-ci peut-être utilisé via une interface graphique, en utilisant un [>DSL],\nou directement via la librairie Typescript.\nDans ce document, nous allons présenter son utilisation code source, via les\nfonctionnalités offerte en Typescript.\n\n## Utilisation du moteur en Typescript\n\nLe moteur est basé sur un principe de primitives d'altérations qui sont combinées\npour créer des scénarios complexe d'attaque.\n\nVoici un exemple d'utilisation du moteur en Typescript :\n\n```Typescript\nlet engine = new Engine({\n\tactions : [\n\t\treplay({\n\t\t\tscope: timeWindow(start,end),\n\t\t\tsource: source_adsb,\n\t\t}),\n\t\talteration({\n\t\t\tscope: and(target(\"FA1312\"), timeWindow(start, end)),\n\t\t\tproperty: \"altitude\",\n\t\t\tmode: AlterationMode.DRIFT,\n\t\t\tvalue -25,\n\t\t}),\n]}).run(data)\n```\n\nLe moteur fonctionne en 2 temps,\n\n1. La déclaration des primitives d'altérations\n2. L'exécution et le calcul des résultats\n\nLa déclaration se fait par la création d'un objet de type `Engine`. Pour\npouvoir créer cet objet, il faut lui définir des `actions` qui sont une liste\nde primitives qui seront exécutés dans l'ordre.\nLa liste des fonctions de construction de primitive est présentée par la suite.\n\nUne fois l'objet créé, la fonction `run(recording: Message[])` peut être appelée\nsur un enregistrement représenté par une liste de messages. Cette fonction\nrenvoie le résultat sous la forme d'un objet `EngineResult`. Cet objet offre\ndifférentes fonctions de formatage pour pouvoir lire et obtenir l'enregistrement\naltéré.\n\n## Types de base du moteur\n\n### Message\n\nLe type `Message` représente une entrée d'un fichier ADS-B.\nIl contient plusieurs champs détailés ci-dessous.\nPour plus d'information sur la signification de chaque champ, vous pouvez vous\nrenseigner sur [ce site](http://woodair.net/sbs/article/barebones42_socket_data.htm?fbclid=IwAR2lIfO8Del8pBA_L5mAZIwJGA8VIPwl6mLp8Gusd5dAvKijnnCARlzueOQ)\n\n```Typescript\nexport type Message = {\n\t[index: string] : string | number | boolean | undefined,\n\n\tmessageType: \t\t\t\tstring,\n\ttransmissionType: \tnumber,\n\tsessionID: \t\t\t\t\tnumber,\n\taircraftID: \t\t\t\tnumber,\n\thexIdent: \t\t\t\t\tstring,\n\tflightID: \t\t\t\t\tnumber\n\ttimestampGenerated:\tnumber,\n\ttimestampLogged: \t\tnumber,\n\tcallsign?: \t\t\t\t\tstring,\n\taltitude?: \t\t\t\t\tnumber,\n\tgroundSpeed?: \t\t\tnumber,\n\ttrack?: \t\t\t\t\t\tnumber,\n\tlatitude?: \t\t\t\t\tnumber,\n\tlongitude?: \t\t\t\tnumber,\n\tverticalRate?: \t\t\tnumber,\n\tsquawk?: \t\t\t\t\t\tnumber,\n\talert?: \t\t\t\t\t\tboolean,\n\temergency?: \t\t\t\tboolean,\n\tspi?: \t\t\t\t\t\t\tboolean,\n\tonGround?: \t\t\t\t\tboolean,\n}\n```\n\nUn message peut facilement ajouter des champs, si ceux-ci sont définit dans le\nfichier ADS-B.\nLa fonction `parse(source : string)` permet de transformer un enregistrement\nADS-B, en une liste de messages.\n\n### Scope\n\nLe Scope est un type utilisé par les primitive d'altération pour savoir quel\nmessage doit être ciblé ou non.\nVoici la déclaration du type :\n\n```\nexport type Scope = (msg: Message) => boolean;\n```\n\nIl existe plusieurs scope prédéfinis, dont voici la liste :\n\n- `always : Scope` : cible tout les message\n- `never : Scope` : ne cible aucun message\n- `target(hexIdent: Icao): Scope` : permet de selectionner les message dont l'ICAO est équivalent à `hexIdent`\n- `timeWindow(lower_bound: number, upper_bound: number): Scope` : permet de sélectionner les message dont la date\n  d'émission (champ `timestampGenerated`) est comprise entre les deux bornes. Les valeurs de temps sont en milliseconde\n  depuis Epoch\n- `and(...scopes: Scope[]): Scope` : un message est ciblé, si l'ensemble des scopes en paramètre le cible\n- `not(scope: Scope): Scope ` : un message est ciblé seulement si le scope en paramètre ne le cible pas\n\nD'autre scope peuvent facilement être ajouté, en effet, le type Scope étant une fonction qui prend un message et renvoie\nun booléen, l'utilisateurice peut facilement définir de nouveau Scope.\n\n### Action\n\nLe type `Action` est un type abstrait qui permet de représenter une primitive d'altération.\nVoici la déclaration du type :\n\n```Typescript\nexport type Action = {\n\tprocessing: (recording: Message[]) => Message[]\n}\n```\n\nPour le moment, une primitive d'altération est un objet qui possède au moins la méthode `processing()` qui\nprend un enregistrement, et retourne cet enregistrement altéré.\n\nPour définir une primitive d'altération, il faut donc renvoyer un objet contenant cette méthode.\nLe code source peut servir d'exemple pour comprendre la logique interne de la librairie.\n\n## Présentation des primitives d'altérations\n\nCette section présente les différentes primitives d'altération, qui combinées\npermette de mettre en place un scénario d'altération.\n\n### _alteration_, modification de propriété\n\nLa modification de propriété permet de modifier les valeurs des différents\nchamps d'un enregistrement ciblé.\n\nLa fonction _alteration_ permet de construire cette primitive. Celle-ci prend\nen paramètre les variable de configuration suivante :\n\n```typescript\ntype AlterationConfig = {\n\tscope : Scope,\n\tmodifications: Modification[],\n}\n\ntype Modification = {\n\tproperty: string,\n\tvalue: number | string | boolean,\n\tmode : AlterationMode,\n}\n\nenum AlterationMode = { REPLACE | OFFSET | DRIFT | NOISE }\n```\n\nLa variable `property` permet de sélectionner le champ à modifier (voir la\ndéfinition d'un message).\nLa variable `value` est la nouvelle valeur à utiliser, en fonction du mode\nd'altération représenté par `mode`\n\nIl existe 4 modes d'altérations :\n\n- **REPLACE** : remplace la valeur du champ par `value`;\n- **OFFSET** : ajoute `value` au champ;\n- **DRIFT** : fait \"dévier\" la valuer du champ de `value` à chaque pas de temps,\n  c'est-à-dire, ajouter au $i-ième$ message la valuer $i \\times value$;\n- **NOISE** : ajoute un bruit alératoire tiré entre $[-value, value]$.\n\n### _creation_, création d'un avion fantôme\n\nLa création permet de calculer et de créer un avion \"fantôme\", qui suit une\ntrajectoire paramétrée par des points de passages.\n\nLa fonction _creation()_ permet de construire cette primitive. Celle-ci prend\nen paramètre la configuration ci-dessous.\n\n```Typescript\ntype CreationConfig = {\n\tstart: number,\n\tend: number,\n\ttempalte: Template,\n\twaypoints: Point[],\n\n\ttimeOffset: () => number,\n}\n```\n\nLes arguments `start` et `end` permettent de venir délimiter dans le temps la\ncréation.\n`template` permet de définir un pattern à respecter lors de la création d'un\nnouveau message, cela permet de préremplir un champ pour les futurs messages.\n`waypoints` est une liste de point de passage, définis par un quadruplet\n`[lattitude, longitude, altitude, timestamp]`\n`timeOffset` permet de définir la manière de décaler dans le temps les messages.\n\n### _cut_, suppression d'une sous-trajectoire, avec continuité\n\nLa primitive _cut_ permet de supprimer une partie d'une trajectoire, et de\nvenir \"recoller\" la fin de la trajectoire juste avant la suppression.\n\nLa fonction `cut()` permet de construire cette primitive. Celle-ci prend en\nparamètre la configuration ci-dessous.\n\n```Typescript\ntype CutConfig = {\n\tstart: number,\n\tend: number,\n\tscope: Scope,\n}\n```\n\nLa fonction va supprimer les messages entre `start`et `end`, si ceux-ci sont\nciblés par la fonction `scope`.\n\n### _delete_, suppression de message\n\nLa suppression de message permet de retirer les messages ciblés à une certaine\nfréquence.\n\nLa fonction `delete()` permet de construire cette primitive. Celle-ci prend en\nparamètre la configuration suivante :\n\n```Typescript\ntype DeleteConfig = {\n\tscope: Scope,\n\tfrequency?: number,\n}\n```\n\nLe paramètre `frequency` définit le nombre de message ciblé entre deux message\nsupprimé.\n\n### _replay_, rejeu d'un enregistrement\n\nLe rejeu permet de réémettre des messages stockés dans un fichier ADS-B en\nadaptant la date d'émission pour coïncider avec le premier message ciblé.\nCela permet de venir faire croire qu'un aéronef refait un vol. Cette trame\npeut être altérée par \"modification de propriété\" avant d'être inserée dans\nl'enregistrement cible.\n\nLa fonction `replay()` permet de construire cette primitive. Celle-ci prend\nen paramètre la configuration suivante :\n\n```Typescript\ntype ReplayConfig = {\n\tscope: Scope,\n\tsource: readonly Message[],\n\talterations?: readonly AlterationConfig[],\n\toffset?: number,\n}\n```\n\nLes messages à rejouer sont stockés dans la variable `source`.\nLa variable `offset` permet de faire un décalage dans le temps par rapport au\npremier message ciblé par `scope`.\nLa variable `alterations` permet de définir plusieurs modifications de propriété\nà appliquer avant l'insertion.\n\n### _rotation_, faire pivoter la trajectoire\n\nPivoter une trajectoire permet de faire dévier la trajectoire cible d'un\nangle donné.\n\nLa fonction \"rotation()\" permet de construire cette primitive. Celle-ci\nprend en paramètres la configuration suivante :\n\n```Typescript\ntype RotationConfig = {\n\tscope: Scope,\n\tangle: number,\n}\n```\n\n### _trajectoryModification_, détournement d'avion\n\nLe détournement d'un avion permet de venir modifier la trajectoire de celui-ci,\npour le faire passer à certains points de passage.\n\nLa fonction `trajectoryModification()` permet de construire cette primitive.\nCelle-ci prend en paramètre la configuration suivante :\n\n```Typescript\ntype TrajectoryModificationConfig = {\n\ttargets: string[],\n\tscope: Scope,\n\twaypoints: Point[],\n\tallPlanes?: boolean\n}\n```\n\nLes icaos avions ciblé par l'attaque sont contenus dans `targets`. Si `allPlanes`\nest positionné à `true`, alors cette liste est ignorée et tout les avions\nsont ciblés.\nSeuls les messages ciblés par `scope`, et dont l'ICAO est contenu dans la liste,\nseront modifiés.\nAucun nouveau message ne sera créé, seuls les messages existant seront modifiés\npour faire passer l'avion par les points de passages `waypoints`.\n\n## Suites et améliorations du moteur d'altération\n\nLe moteur d'altération est un outil intéressant pour analyser les données linéaire en ADS-B\net les altérées. Pour le moment le moteur avait pour but de venir remplacer une ancienne\nimplémentation en Java.\n\nIl est cependant possible de penser à de nouvelles fonctionnalités et amélioration.\n\n### Amélioration de l'existants\n\nCertaines structures de données ont été choisie au début de l'implémentation du moteur et\nnécessiterait une refonte.\n\nNotamment les `Action` et `Scope` qui possède deux design différents. En effet, les `Action` sont\npensés comme étant des _commandes_, c'est-à-dire un objet qui contient les informations nécessaires\nà une exécution. Cela permet de retarder l'exécution des primitives d'altération, de pouvoir garder\nune trace des actions réalisés, des futures optimisations, etc ...\n\nÀ l'inverse, les `Scope` sont de simple fonction. Sachant que Typescript est un langage ayant\ndes aspects fonctionnels, cela permet tout de même de stocker les informations\nnécessaires à l'exécution de la fonction, et de l'effectuer plus tard. Mais on perd\ntoute une couche d'information qui pourrait se révéler utile.\nDe plus, il semble naturel d'essayer d'uniformiser les structures de données.\n\n### Tests du moteur : utilisation de test par proriétée\n\nActuellement le moteur possède une base de tests héritée de son ancienne implémentation en Java.\nCelle-ci possède des lacunes et, a surtout le rôle de tests de non-régression.\n\nApporter des tests unitaires solides est un défi, qui peut se révéler impossible, dû à la nature\ndes données (grandes données difficilement prédictibles, grande précision en nombre flotant, manque\nd'une définition formelle des primitives, etc ...).\n\nIl peut être alors intéressant d'effectuer des tests par propriétés.\nUne ébauche de cette technique est contenue dans la base de code. Cependant, cette exploration a permis\nde soulever certains points de blocage pour l'utilisation ces tests :\n\n1. **Un code peu lisible** : les propriétés à tester étant complexe, le code du test doit se situer\n   entre (i) apporter la certitude que le test est conforme à la définition ; (ii) être lisible.\n   Il se trouve que ces deux points se révèle antagoniste. En effet, pour apporter une certitude de\n   conformité, il est intéressant d'utiliser le style fonctionnel proposé par Typescript, qui est\n   plus difficile à lire.\n2. **Un problème pour générer les données** : les données d'entrées de tests sont difficiles à générer.\n   Il faudrait pour cela pouvoir créer une trace ADS-B et les paramètres de la primitive, dans des espaces\n   de possibilités immenses.\n   Il faut donc choisir des protocoles pour générer des cas de tests intéressants, en apportant une\n   couche logique à celle-ci (l'aléatoire ne suffit pas)\n\n3. **Un manque de traçabilité des erreurs** : Une fois qu'une erreur a été détecté, la librairie de\n   tests par propriétés (fast-check) nous renvoie la donnée générée qui a fait échouer le test.\n   Cependant, cette donnée ne donne que peu d'information sur le test. Notamment, il manque :\n\n- le message où le test échoue\n- les actions qui ont été éxécutées sur ce message\n- les états intermédiaires des données altérées\n\nPour résoudre ces problèmes, il semblerait intéressant de développer une sur-couche autour de\nla librairie de test par propriété qui permettrait de résoudre ces points sans ajouter\nla charge redondante de les gérer à l'utilisateurice.\nCette sur-couche devrait pouvoir permettre de définir un test, avec des fonctions prédéfinies qui\npermettent d'écrire de manière explicite le test.\nEt de manière cachée, gérer un journal qui gardera plus d'information sur le test que le fait\nfast-check par défaut, dans le but d'afficher ces informations si un test échoue.\n\n### Ajout de template d'exécution\n\nPour le moment, les actions ne peuvent s'exécuter que l'une à la suite de l'autre.\nCependant, avec l'utilisation de **commandes** et de **template** il serait possible\nd'imaginer des flux d'exécution plus complexe (par exemple : deux suites d'actions\ns'exécutes sur la donnée d'entrée, puis sont assemblés par la suite, avec ou sans données\npartagées, etc ...)\n\nPour cela, il faudrait redéfinir des objets qui suivent le patron de conception **template**,\nou **visiteur**, c'est-à-dire, il faudrait stocker un arbre représentant un graph d'exécution\nde l'attaque, puis le parcourir pour produire le résultat.\n\n### Optimisation par paralélisation des actions\n\nActuellement, les actions s'exécutent séquentiellement. Sachant que la plupart d'entre elles\nn'ont besoin que du message courant pour faire leur attaque, il serait possible\nde faire s'exécuter une action dès que la précédente aurait produit un message.\n\nPour cela, il faudrait modifier le type `Action` pour ajouter une fonction qui\npermettrait l'utilisation de données partagées, puis d'implémenter\npour chaque action une version paralèle.\nCe travail devrait être faciliter si des **templates** ont été dévellopés avant (par exemple\npour la modification de propriété, ou la suppression, sont deux actions qui appliquent un\nmême traitement à chaque message, c'est-à-dire une fonction _map_)\n","readmeFilename":"README.md"}