# 🛰️ MKII / Magnetometer MKii est un dispositif de mesure magnétique, il est constitué de 7 capteurs immergés et reliés via un cable de 300m à une application Magnetometer chargée de l'acquisiion des données. ```diagram PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDsgYmFja2dyb3VuZC1jb2xvcjogdHJhbnNwYXJlbnQ7IGNvbG9yLXNjaGVtZTogbGlnaHQgZGFyazsiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHdpZHRoPSI2OTFweCIgaGVpZ2h0PSIzMzZweCIgdmlld0JveD0iLTAuNSAtMC41IDY5MSAzMzYiIGNvbnRlbnQ9IiZsdDtteGZpbGUgaG9zdD0mcXVvdDtlbWJlZC5kaWFncmFtcy5uZXQmcXVvdDsgYWdlbnQ9JnF1b3Q7TW96aWxsYS81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV2luNjQ7IHg2NDsgcnY6MTM1LjApIEdlY2tvLzIwMTAwMTAxIEZpcmVmb3gvMTM1LjAmcXVvdDsgdmVyc2lvbj0mcXVvdDsyOC4xLjEmcXVvdDsmZ3Q7Jmx0O2RpYWdyYW0gaWQ9JnF1b3Q7dkRvY2ItM19fUzN4eVhZRWNySVQmcXVvdDsgbmFtZT0mcXVvdDtQYWdlLTEmcXVvdDsmZ3Q7N1ZoTGI2TXdFUDQxWENNd2o1QmprelM3aDY1VXFZZnRuaW9YSFBDdXdjaVlQUGJYN3ppWWh3TnRVMjJhcUZJakpaa1pqeC96ZWI0eHhuSVgyZTZid0VYNmc4ZUVXY2lPZDVhN3RCQnlQQlRBbjdMc2Ewc1lPTFVoRVRUV1RwM2hnZjRsMm1ocmEwVmpVaHFPa25NbWFXRWFJNTduSkpLR0RRdkJ0NmJibWpOejFnSW5aR0I0aURBYlduL1NXS1k2Q2pUdDdOOEpUZEptWmllWTFTMFpicHgxSkdXS1k3N3RtZHhieTEwSXptVXRaYnNGWVFxOEJwZTYzK3FGMW5aaGd1VHlwQTUrM1dPRFdhV0Qwd3VUK3laYXdhczhKcXFEYmJuemJVb2xlU2h3cEZxM3NMOWdTMlhHUUhOQTFNTVJJY251eFRVNWJhU1FJb1JuUklvOXVEUWRiQTJPemc3a2EzM2JZUjNNdEMzdDRleTYyb2oxL2lidDJCMEVJR2dVeGhHWkR1SW5NV3krVnJtUUtVOTRqdGx0WjUyYkNIVStkNXdYR3BmZlJNcTl6bVJjU1c2aVJuWlVQdmJrWDJxb2lhKzE1VTZQZkZEMmpaSkRaSTk5cGRkTHFWMjNnOWIxaTI4VUIwRE5lVTVxeTRvcVFBN3RheEFYbkhGeGlONjFiZDhtYTdDWFV2QS94R2h4bHZORnUrY0twdGQzSEZEbGxZaTBsMDQwaVVWQ3RKYzNuaGVDTUN6cHhoejlmL1lZdlNmcG5iZVQvZ2l5K25NZU1yU1ZRcFBCZDBiSU1NYUZNMUJoOWtXRnkxREJIVkxCdnhBVjNNOURCUys0SGhYQ0x5cGNoZ3Jla0FydWhhamdmUjRxdUw1M05TcTg2NG54dWpCTm5ldFZqR0FBMDJReXNkcm4vZzRzQ0UrYWlHQkdreHprQ01Ja0FNdGNnVURoK25Hakd6SWF4NGNTTXdhdFdYYk9nS0kvdXg2S3pWUTlHS2ZxWW9jTFNTcFJmajR3UGZjSVROKy9ISmpPMjlTTktyRnBtZHM3RkNLR3k1SkdKclltT3MxeDFjZ2ZlVnhkOFpMaW9QRU43bTJnUDdLQmplM2tZMHZQY004cHJLKzdIQi9sajRlT0VxTmV2ZTdWdi9rZkR4U2FBdzB1ejNYTWc0RWdJZkMrNTFZb2gvSWRDdzd0MTlkMWRPRnhBOE1maEhvRlhjYTNlM0FhQ1U2NC9OSHM4QUtvbityYXRLUlpBak13K2d5L0VhUEZFeFpTaVR3cktxZ3ZBTVRxRG9vVEw1NGNGTzdnT3lueTVBeDFBeDNCaU1KaEVRNUgwaTQ4UjkwWVhoTHVvSFlTQ3dWTVZkdG5BVktpSktCYmR1R2F2T2E1TlBodTI2dlZtVjVFb1JlNGRvbGFQWHdhdmVlbEJNenRXUDFJZ1RlWXNzOTNBQ0p2bk44ZkFDcW8zWnZVdWxSMDc2UGQyMzg9Jmx0Oy9kaWFncmFtJmd0OyZsdDsvbXhmaWxlJmd0OyI+PGRlZnMvPjxnPjxnIGRhdGEtY2VsbC1pZD0iMCI+PGcgZGF0YS1jZWxsLWlkPSIxIj48ZyBkYXRhLWNlbGwtaWQ9IjE1Ij48Zz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iNjkwIiBoZWlnaHQ9IjMzMCIgZmlsbD0iI2ZmZmZmZiIgc3R5bGU9ImZpbGw6IGxpZ2h0LWRhcmsoI2ZmZmZmZiwgdmFyKC0tZ2UtZGFyay1jb2xvciwgIzEyMTIxMikpOyBzdHJva2U6IGxpZ2h0LWRhcmsocmdiKDAsIDAsIDApLCByZ2IoMjU1LCAyNTUsIDI1NSkpOyIgc3Ryb2tlPSIjMDAwMDAwIiBwb2ludGVyLWV2ZW50cz0iYWxsIi8+PC9nPjwvZz48ZyBkYXRhLWNlbGwtaWQ9IjciPjxnPjxwYXRoIGQ9Ik0gMTgwIDI3NSBMIDI1NCAyNzUiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMWRiYyIgc3R5bGU9InN0cm9rZTogbGlnaHQtZGFyayhyZ2IoMCwgMjksIDE4OCksIHJnYigxNzgsIDIwMywgMjU1KSk7IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHBvaW50ZXItZXZlbnRzPSJzdHJva2UiLz48L2c+PC9nPjxnIGRhdGEtY2VsbC1pZD0iMiI+PGc+PHJlY3QgeD0iMTIwIiB5PSIyNjAiIHdpZHRoPSI2MCIgaGVpZ2h0PSIzMCIgcng9IjQuNSIgcnk9IjQuNSIgZmlsbD0iIzMzMzMzMyIgc3R5bGU9ImZpbGw6IGxpZ2h0LWRhcmsocmdiKDUxLCA1MSwgNTEpLCByZ2IoMTkzLCAxOTMsIDE5MykpOyBzdHJva2U6IGxpZ2h0LWRhcmsocmdiKDAsIDAsIDApLCByZ2IoMjU1LCAyNTUsIDI1NSkpOyIgc3Ryb2tlPSIjMDAwMDAwIiBwb2ludGVyLWV2ZW50cz0iYWxsIi8+PC9nPjwvZz48ZyBkYXRhLWNlbGwtaWQ9IjkiPjxnPjxwYXRoIGQ9Ik0gNDIwIDI3NSBMIDYxMCAyNzUiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMWRiYyIgc3R5bGU9InN0cm9rZTogbGlnaHQtZGFyayhyZ2IoMCwgMjksIDE4OCksIHJnYigxNzgsIDIwMywgMjU1KSk7IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHBvaW50ZXItZXZlbnRzPSJzdHJva2UiLz48L2c+PC9nPjxnIGRhdGEtY2VsbC1pZD0iMyI+PGc+PHJlY3QgeD0iMzYwIiB5PSIyNjAiIHdpZHRoPSI2MCIgaGVpZ2h0PSIzMCIgcng9IjQuNSIgcnk9IjQuNSIgZmlsbD0iIzMzMzMzMyIgc3R5bGU9ImZpbGw6IGxpZ2h0LWRhcmsocmdiKDUxLCA1MSwgNTEpLCByZ2IoMTkzLCAxOTMsIDE5MykpOyBzdHJva2U6IGxpZ2h0LWRhcmsocmdiKDAsIDAsIDApLCByZ2IoMjU1LCAyNTUsIDI1NSkpOyIgc3Ryb2tlPSIjMDAwMDAwIiBwb2ludGVyLWV2ZW50cz0iYWxsIi8+PC9nPjwvZz48ZyBkYXRhLWNlbGwtaWQ9IjgiPjxnPjxwYXRoIGQ9Ik0gMzE0IDI3NSBMIDM2MCAyNzUiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMWRiYyIgc3R5bGU9InN0cm9rZTogbGlnaHQtZGFyayhyZ2IoMCwgMjksIDE4OCksIHJnYigxNzgsIDIwMywgMjU1KSk7IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHBvaW50ZXItZXZlbnRzPSJzdHJva2UiLz48L2c+PC9nPjxnIGRhdGEtY2VsbC1pZD0iNCI+PGc+PHJlY3QgeD0iMjU0IiB5PSIyNjAiIHdpZHRoPSI2MCIgaGVpZ2h0PSIzMCIgcng9IjQuNSIgcnk9IjQuNSIgZmlsbD0iIzMzMzMzMyIgc3R5bGU9ImZpbGw6IGxpZ2h0LWRhcmsocmdiKDUxLCA1MSwgNTEpLCByZ2IoMTkzLCAxOTMsIDE5MykpOyBzdHJva2U6IGxpZ2h0LWRhcmsocmdiKDAsIDAsIDApLCByZ2IoMjU1LCAyNTUsIDI1NSkpOyIgc3Ryb2tlPSIjMDAwMDAwIiBwb2ludGVyLWV2ZW50cz0iYWxsIi8+PC9nPjwvZz48ZyBkYXRhLWNlbGwtaWQ9IjUiPjxnPjxyZWN0IHg9IjYxMCIgeT0iMjYwIiB3aWR0aD0iNjAiIGhlaWdodD0iMzAiIHJ4PSI0LjUiIHJ5PSI0LjUiIGZpbGw9IiMzMzMzMzMiIHN0eWxlPSJmaWxsOiBsaWdodC1kYXJrKHJnYig1MSwgNTEsIDUxKSwgcmdiKDE5MywgMTkzLCAxOTMpKTsgc3Ryb2tlOiBsaWdodC1kYXJrKHJnYigwLCAwLCAwKSwgcmdiKDI1NSwgMjU1LCAyNTUpKTsiIHN0cm9rZT0iIzAwMDAwMCIgcG9pbnRlci1ldmVudHM9ImFsbCIvPjwvZz48L2c+PGcgZGF0YS1jZWxsLWlkPSI2Ij48Zz48cmVjdCB4PSI0OTAiIHk9IjI2MCIgd2lkdGg9IjYwIiBoZWlnaHQ9IjMwIiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiIHBvaW50ZXItZXZlbnRzPSJhbGwiLz48L2c+PGc+PGc+PHN3aXRjaD48Zm9yZWlnbk9iamVjdCBzdHlsZT0ib3ZlcmZsb3c6IHZpc2libGU7IHRleHQtYWxpZ246IGxlZnQ7IiBwb2ludGVyLWV2ZW50cz0ibm9uZSIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgcmVxdWlyZWRGZWF0dXJlcz0iaHR0cDovL3d3dy53My5vcmcvVFIvU1ZHMTEvZmVhdHVyZSNFeHRlbnNpYmlsaXR5Ij48ZGl2IHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiBzdHlsZT0iZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IHVuc2FmZSBjZW50ZXI7IGp1c3RpZnktY29udGVudDogdW5zYWZlIGNlbnRlcjsgd2lkdGg6IDU4cHg7IGhlaWdodDogMXB4OyBwYWRkaW5nLXRvcDogMjc1cHg7IG1hcmdpbi1sZWZ0OiA0OTFweDsiPjxkaXYgc3R5bGU9ImJveC1zaXppbmc6IGJvcmRlci1ib3g7IGZvbnQtc2l6ZTogMDsgdGV4dC1hbGlnbjogY2VudGVyOyBjb2xvcjogIzAwMDAwMDsgIj48ZGl2IHN0eWxlPSJkaXNwbGF5OiBpbmxpbmUtYmxvY2s7IGZvbnQtc2l6ZTogMTJweDsgZm9udC1mYW1pbHk6IEhlbHZldGljYTsgY29sb3I6IGxpZ2h0LWRhcmsoIzAwMDAwMCwgI2ZmZmZmZik7IGxpbmUtaGVpZ2h0OiAxLjI7IHBvaW50ZXItZXZlbnRzOiBhbGw7IHdoaXRlLXNwYWNlOiBub3JtYWw7IHdvcmQtd3JhcDogbm9ybWFsOyAiPi4uLiA8L2Rpdj48L2Rpdj48L2Rpdj48L2ZvcmVpZ25PYmplY3Q+PHRleHQgeD0iNTIwIiB5PSIyNzkiIGZpbGw9ImxpZ2h0LWRhcmsoIzAwMDAwMCwgI2ZmZmZmZikiIGZvbnQtZmFtaWx5PSJIZWx2ZXRpY2EiIGZvbnQtc2l6ZT0iMTJweCIgdGV4dC1hbmNob3I9Im1pZGRsZSI+Li4uIDwvdGV4dD48L3N3aXRjaD48L2c+PC9nPjwvZz48ZyBkYXRhLWNlbGwtaWQ9IjEwIj48Zz48cmVjdCB4PSIzMzAiIHk9IjMwNSIgd2lkdGg9IjYwIiBoZWlnaHQ9IjMwIiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiIHBvaW50ZXItZXZlbnRzPSJhbGwiLz48L2c+PGc+PGc+PHN3aXRjaD48Zm9yZWlnbk9iamVjdCBzdHlsZT0ib3ZlcmZsb3c6IHZpc2libGU7IHRleHQtYWxpZ246IGxlZnQ7IiBwb2ludGVyLWV2ZW50cz0ibm9uZSIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgcmVxdWlyZWRGZWF0dXJlcz0iaHR0cDovL3d3dy53My5vcmcvVFIvU1ZHMTEvZmVhdHVyZSNFeHRlbnNpYmlsaXR5Ij48ZGl2IHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiBzdHlsZT0iZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IHVuc2FmZSBjZW50ZXI7IGp1c3RpZnktY29udGVudDogdW5zYWZlIGNlbnRlcjsgd2lkdGg6IDU4cHg7IGhlaWdodDogMXB4OyBwYWRkaW5nLXRvcDogMzIwcHg7IG1hcmdpbi1sZWZ0OiAzMzFweDsiPjxkaXYgc3R5bGU9ImJveC1zaXppbmc6IGJvcmRlci1ib3g7IGZvbnQtc2l6ZTogMDsgdGV4dC1hbGlnbjogY2VudGVyOyBjb2xvcjogIzAwMDAwMDsgIj48ZGl2IHN0eWxlPSJkaXNwbGF5OiBpbmxpbmUtYmxvY2s7IGZvbnQtc2l6ZTogMTJweDsgZm9udC1mYW1pbHk6IEhlbHZldGljYTsgY29sb3I6IGxpZ2h0LWRhcmsoIzAwMDAwMCwgI2ZmZmZmZik7IGxpbmUtaGVpZ2h0OiAxLjI7IHBvaW50ZXItZXZlbnRzOiBhbGw7IHdoaXRlLXNwYWNlOiBub3JtYWw7IHdvcmQtd3JhcDogbm9ybWFsOyAiPjcgY2FwdGV1cnM8L2Rpdj48L2Rpdj48L2Rpdj48L2ZvcmVpZ25PYmplY3Q+PHRleHQgeD0iMzYwIiB5PSIzMjQiIGZpbGw9ImxpZ2h0LWRhcmsoIzAwMDAwMCwgI2ZmZmZmZikiIGZvbnQtZmFtaWx5PSJIZWx2ZXRpY2EiIGZvbnQtc2l6ZT0iMTJweCIgdGV4dC1hbmNob3I9Im1pZGRsZSI+NyBjYXB0ZXVyczwvdGV4dD48L3N3aXRjaD48L2c+PC9nPjwvZz48ZyBkYXRhLWNlbGwtaWQ9IjExIj48Zz48cGF0aCBkPSJNIDEyMCAyNzUgUSAzMCAyMzAgMjUgMTcwIFEgMjAgMTEwIDEyNC4wMiA3Mi4xOCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAxZGJjIiBzdHlsZT0ic3Ryb2tlOiBsaWdodC1kYXJrKHJnYigwLCAyOSwgMTg4KSwgcmdiKDE3OCwgMjAzLCAyNTUpKTsiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgcG9pbnRlci1ldmVudHM9InN0cm9rZSIvPjxwYXRoIGQ9Ik0gMTI4Ljk1IDcwLjM4IEwgMTIzLjU3IDc2LjA2IEwgMTI0LjAyIDcyLjE4IEwgMTIxLjE3IDY5LjQ4IFoiIGZpbGw9IiMwMDFkYmMiIHN0eWxlPSJmaWxsOiBsaWdodC1kYXJrKHJnYigwLCAyOSwgMTg4KSwgcmdiKDE3OCwgMjAzLCAyNTUpKTsgc3Ryb2tlOiBsaWdodC1kYXJrKHJnYigwLCAyOSwgMTg4KSwgcmdiKDE3OCwgMjAzLCAyNTUpKTsiIHN0cm9rZT0iIzAwMWRiYyIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBwb2ludGVyLWV2ZW50cz0iYWxsIi8+PC9nPjwvZz48ZyBkYXRhLWNlbGwtaWQ9IjEyIj48Zz48aW1hZ2UgeD0iMTMwIiB5PSIzMCIgd2lkdGg9IjgwIiBoZWlnaHQ9IjgwIiB4bGluazpocmVmPSJkYXRhOmltYWdlL3BuZztiYXNlNjQsaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUh3QUFBQmxDQVlBQUFDUHg0ZnRBQUFnQUVsRVFWUjRYdTJkQ1hRYzFabnZ2MWJ2VW5lclcxdHIzNzFiWHVRRlc4WUdzKzlaZ0JBbUx3bERRaWJKOEpJNFpBakpPMG1ZNFdTZDVERlo0SVVYRXNnRUJzSXlRSmhnWW9ObGJMQXh0aVZMdHZaZDFyN3ZVa3N0OWZ2K3QvcTJxdHV0eGJJc1c1cDN6OUdSVkYxVlhWVy8rNjMzdTdjMDlOKzQzYjFuajdubXlLa2Job1pHdG9Wb05GRTJpK1YvSFRteXIyMHBQeExOVXI0NWVXOVhYMzIxWldCWWN5M0FqbytQYlNHUFo2V0hOTmFKY1hlb3grUFJUVXlNRTM0aUlwMnY1Sjg0ZVBkU2ZpWkxDcmdFT3pMc3VzMmo4YXgzajQ3R0E2eEdRemIzMkpqZ0tPSGk3NUFRclI5YnZjSFV0Mzd0d3hFdnYveXA4YVVLZlZFQ3o4bTVJYWFudi9mV0VJMDJSdzFXcTlYYTNPNHhtaGhYSkJZL1U3VkEySEsvU0VmVTdoTW5EaDc4LzhBdndSTUlCR3ZRNjFQSEp5aDZmTnhON3JGUi9tRzRESFdNL3c3V3VBTUUzUTdZOW9nWXlseWVUS2taYTZtL3A0MzI3LzJiT0pjNTFQcVQ0dE5IdjNNSmJuZEJ2dkt5a1BCMW0zZXNjTHZjT1ZKaUFaWTBPZ0YyYk5SRmtGb0FCbGkxMUU0bHBYaHlFclpPWjZEWXBFeGFuaGxMaWFscktDVXBucEtUWWlncUtsbzhZS1BSUUxXMWRmVHd0eDZob1lFKzBobU1SUlVsSjljdXlOTy9CRit5b01BQlZ1UFIzaGFpQ2RrMk91WktBZGdRblRsNllueU1Sa2RIYU5RMUlzQzZYTU9zbHNjb1JLcy9MNVZzdFRrb09XMDV4U2NsZTlKU0V6VHhjZkdVRUI5TkpvYXExU25uMG1wMXBOTXBrcS9YNjN6bjMvUE5IMUI5VmFHdzYySGhscFdGSno0b3V3UThMdnBYWGhUZ2FyQm1jOWc2RDNsaU9leXhqb3k2TlNQRC9RSXE0RXF3d2U1eU90aDZ2WUdpbk1ua1RFeW4xT1FFanpNdVhwTVFHMEVSRVJGZXFCTU1Ua002aHF0QTFwQmVBcDhDL1BNdnZFcXZ2L1NDMk45aUMvOVd3Y2xEdjdqb1QvOFNmTUVGQWQrOCtlcXJ4endUbXlDeFByQjZzODNOYW5oNHFJOWNJME1DTFA0ZW41anczWjQySkdUR1c1WEF6V2FMVU1teENja1V6OUlhNDB5bDZFZ3JWQzhaZE1ybEc3U3NON1RzaTNQVHNQQ0dhQlJwMXVzOS9MZEdTQzJnZTBMNG1CRGxPaUR4YW1rdkxpbW5uLzNvUitKNmRYcjl1MlhGSjY2YjhTSVg0UTR6QXIvNzdwZTBOVFZQN2dUWTBGRHJUWHhBc3NrVW1qU3UwWnZkSTcyZW9lRmhsdHBCd2cvQVNnY3F4Q3RkZ2M5a0t0Z0E3SWgwc3VTbVVteGlBc1U2NHlrcTJrbDJ1ODEzQ3IyV2d5eXZtdGRxSnp0Tk1QQ1RLbnlDSlQzRUY0SUZTanVneS9iTlBZOVFSK3RaMG1nMDdzUjR1K1Bnd1lNRGk1RHB0SmZzQXk2eVRvZnpyeGh5dVc0TXQwZHNsbUQxSnBONVlIQ0lSb1lHMktucG9hRkJTTzdnbEo2eC9MYnBnT3YwSm5MR3AxRjRUQm81WXhQSTZZd21xejJPYktIblhxdmU2MmhydlhaWFNLNEt2S0t5US95a1hkbW1TSHd3OElBdXpnTXBWNm40cDU5NXdYTm8vMytKRHgwUkVSOC9jU3ozalNVSEhQYldHWmZ4Z2Q0WUZvbWJHM2NOVUVkN0cvWDF0Rk4vYndlTmpBejczZk5Vb1k1Nkp6VnNpOFV1UXFDNGxCVVVFWk5NanFoNHNvZmIvYzVwMUUrcWUvbUJVZSt2OW1jQ0x5VmVMZTBUSWF5SE5EcWZtdGRxRmR1dVZ2TnEyMzdzb3p6NncvOTlTcWgxTmxGUG55azg4c0NTQTM3ZExmZlVHVUlqa210Szg2aTdzL2tjd09lbzVDbGlXemhTNFk0WWhodEx4dWdzc29USDhQL1JaRENHaWxCS3g1TGtEQjlucVpwVW9ZSG5EZ1llKzZqaHp3YThJWVRqY3RocnR1MnprWFlKbmMwVGZmOTdQNlNlemhaSS9wTE11bWx1dlAyem52cWFjbXB1cko1Vlo0YUVtME50Rk8xTUpFZmNjakxhTThnZUdVZldjQ1d1UlZPeVhHN3lzS00ySVg3NGY4NSs2YmhUeERrRUExK2JxZ1BNSlBXQjRLSG0wZFEyUGhoNDZkUkIyb1BaOXFkWXdvOGZQUzdzdU4xbXYzNnBaZDAwa1BDenRWWEpyYzExNXdBSDNLaVlSSXFLVFNFelMyMUVUQXIvSkpHUlBXZWgvamtoSWdDTFZLWmIvSjRPT0Q0TDRYUEdoTU4raHRDWWUwTDhucWtEQk1LZlR1TFY0QTBoTGhyWG1Oa3puNVI0dFpxSEdSRFFWWjc4d1VNZjBhc3ZQaWV5ZUVaVDZKTEx1bW5XcnN2NW5kNW8rbUpONVdueDNCMFJUdHA0N1FNVUZiK1M0U2I0V1BnR0h6ajdOZTdOVWM4Rk9Eb0dXbnlVTVFDMFAvZ3d2WXNHeDR5RTM2T2VNREpvQmpuNVp2WTdaamJnZFNIaklpUVR2a2VBbWhmU3pqWWRrWU9VOXZhT2Jucjg1LytiZlpoT0N0SHBsbHpXVFlOWU9pd2lQcmZnK0g3eE1Oa3BwL3UrOXhhUmpzTWhkOTlGQVM3VG8zRVJrMTZ5djVTZkc2Y0R2THBKK0hyTk1IdnRJVUtTMGFTcU4rcGNyTjZWYlJJNi9oYmc0ZFdIR1B4aWQwaTcxZ3YvVjcvNkhWV1djdFlONXN0aVhsSlpOdzNpN0VGUHJ2dll3ZGRvM0t1U2IzL2dTVXJJdk9LaUFvZDlSM002K0VHclVxZ3lUSkp3VFNGS2xEQWVFaVorQjRMSE5vTTNBd3Z3c25IS2xnQWRiU3J3QnIzSjM2blRLOUwrVHU0UmV2dU5WK0NEdU1Pc3RrZVdVdFpOeEp5dzQxVmxSY25kWGEzaUFXWHZ2Sk8yM3ZiZGl3NWNxdmNvbTVZMWk4bFBnZ1ZJMkY1dkM3VDFCcDJiSmREL21ObUFoN1Fya3U1VjgxNXBWOXYycy9VTjlNelR2K2RFMGdDci9KQWxsWFVUd0RkdXZ2cGwwb1RjSmUxNHRET0o3dnptNndzQ25JYzdSWFBhdFp3S25Sek9WRXY5aFlMWDZ5Wm9uTUw4Skg0bU5mK2JKMzVQVGZXbEFFNXhNUmJyVXNtNkNlRDMzdmZnVjV1YXVwNlFkaHgyN3A0OUw1TE5FZVdUc1BsMDJtRERsWkFORGlDOGZNV1JpN1I2S0N4TVVkMkJEUjFBRFI2ZnE2VWVFbyttbHZwQWlRZDROSjAzRjREY2daKzA4ejlRODVEMi9mc09lZDQvc0ZjOG4vRHc4Q1dUZFJNM2hOS2cwS2hWL1dvN2Z1MG5IcVJsbSs5Y1VPQVN1c0V3cWFyVlVpOHZ4c3lESXVvMkYvQVN1bzRIWURRODJDTFRyZEtwcTYydXBUOC8vNXpJdWhrTnBpV1RkZlBsMHErLy9YTWRsY1Y1a2RLT1o2eklwdXMvTnpsQ3VCQVN6Z1dHZ2lNUDBsQ0V4UjhxdHB0MC9wVXQ2bzR4azhUUEpPMXE4SUErT3VxbVozNzNPMDliVzdPRzQvVEdzcEtUaVVGVnp5TGI2QU8rZmVldCt6bHZmcDIwNDNvZWZ2ejhkOS9FVUtHNHBZVUVqZ1JPYUppRjRNd0ZhNEhnalRxbGMzaEN2S0daS3BtalZ2VW0zWWpZYjBKakVxR2Mwa2ttMVR5Z28wbUozNy92TFRyKzRYR3hMZHhpV3hLMWJqN2dtNi9ZL2JHdzhMalhwUjNIVGQ1ODMrT1VzbXpESlFIdVlmdHVOaG5JYmxVNm5HbUs0aGVEYXBCRmdwZndqZG9oY1N4RzUyUXphTjArR3k3QlMraGlYN2J2VXRwTFNrdnByVGRlRXlWV2VyMXhTV1RkL0laSEI4K09ET1Y5OEZjeGdBSzF0ajduNDdUMXBnY3ZHWERrNGNOQ1RUN29FbG93K0ZPQnh6RUdyODJmQ3J3c2VjSUFqNFNPMzNnT0wvN0h5OVRWMGNTRFFNYmpSUVZIdC9wNnppTDl3NjhBQXZGNFkzMXRNZ1pTQU56dWNOTGRlNTYvcE1EaHdldDV4QzNHeGtPYmV2L1Vxa0dqcU9nUW5VcUNBNFpWcGRSTDZHcUpoN1NyQWF2QlM2ZnV6YmR5cWVMTU1SR2VSZG9qbkl0OVpvb2ZjTVRqb2JiSXUwb0xQL0QxM3pzZi9LUElxUyswRFlkS0Z5TnQzcEFOSTIxT3V5cVRwb0lmQ0Y2dm1VekRJZ1dyVnZWcWlVY05vNGZ0ZVREd1V0cExTcXM5dWZ2ZTFDQ1VaQ0c0di9qMHNXY1dxWENMeS9ZRGpyeDZUT3FxWElSbnN1Mjg1WXUwY3R1bkx6bHd6OFFZNTRaNFRKMVRzU2c5RG13bWczKzFscEhUcExKTjV0MDVjNmFkalBNaDliSndWUTdUVG9acmlzUFkxVE5JYi8zbERScm82K1Rvd2JMb3B5S2RVOU9HOFhFTUhQUjBLMm5XMU16MUlqeTcxQklPNE9NVEhqSEFFUnVwakxTZEwzaEZ1cFhVS3NCcldSTm92WjFuT3ZCdjczMkhhcXRLZUVvYTlhMi9hV2ZzeTQ4LzdsOEd0SWhFL2h6Z09UdHZMWE9OdVpmWFZoYUkyMEEyNnA2SFhvS1hLdjZIaXIzUTRkR3BNbTB5RGtkWUZxalNKWEFjaXlyVVdJZU9ZVTFXendUQ24wN2lKWGdKSGY4SEF5K2x2ZkJNQlowNGNrQVVjbGl0MWtXZGRUc0grUHBOdXg2S2pVLzUrWW1qeW5BcDJ1NTdIcVBVNVpzdkcrQWU3M2g4dElQdEw4ZmNhdkR5bXRVZFFBMWZyZW9sZUhYVlRURHdIWjFkZEdEZlBsSEFxZGNaRm5YVzdSemdTTE1hclVuOVJRWEhSTmt4V3VhbVQ5RE9XNzUwV1FISFVDNGlDUWxkclZVREpWOVBTcld4WHFmbFBIbW91R2U5ZG9RMWhSd3ZkN0dLMS9uVjJ3RzhhbUlLdmZ2Tys5VFNVTTVlbm1kUlo5MkMxcVh2dU9xT3h2NytudmpHZXI1QmJnalBQdkhnczVjZGNBazUyajQ1bFFnU0w5dDA0SVVhMTdORDRHM3lPRFY0dGJRWG5LNmc0dndqU3NjeDZSWnRVVVJRNENoN0NvK0srNklNei9BUVVCUVJFWjEwV2Rod3FIUlpyT0YySy9uMXVDaUxyOFpjcU9xQVdqa0ozNnpLeDBQaWc0R1haZFpTMVFOOFMwczdIWHYvWFRHNWtaTXdpM1lxVWxEZ3FGVlBURjFYaXF5Ym5FbXk4ZG92MDRhY2oxMjJ3QUhPYXJXVHhhZ2tVOVNWTTRGU3p5cmV3emJlZCs5VGdjZDVwTVM3ZU5Uc1E2NW03V3ByZ1BPMmFJc2lnZ0xIalY1ei9kMURqWTAxNWc2K1FUU0VaN3Z2L2NsbERaeG5VUWlicmpQNGo2bEwrS0U4ZU9LbVVOTFJFSWQwSVVLNnB3T3ZWdlBZdDZpNGlsQy9qK2F3aFMvS3JOdVV3SkYxTTVnc2QxV1dubERzRm9kbmQzMzllY0tRNUtVT3k0S3BkTUNXeldTSkpLdCs4Qnp3c3NiTjRCZk96UjU4VzNzdjVSMTdUNVJqYzJYem9zeTZUUWtjV2JmSXVLVGN2STl5aFZSRHRWMTExdzhvT1dQRDVRa2N0Qm42NkppaTBxM2hVV1F6S3JuMlFJbWZLL2lSNFRFcXpEc3VwbUZ4ZGUraXpMcE5DVnlxOVpycUV2TUFUeUpFUzk5d08rMjQ4ZjVGQVJ6WEcycHhrQ05VS2FxUXphZ2FadFdwNHE1QXFaOUsxWmNYbHhCbTZyRFR1Q2luSWswTFhCWkZOSGpETTVzdGtqNzJsYWNGY1BVa0JEek0yYzQ4RWZ0TlVkTTIyMHhiVUpVZUlPRVNzTUVVUnRHMmMyOXpKdkRTeGdzTjRYWHc0TnkxdG5kcVpIZ1daakl2dXFLSUtZR2pYcjJvOUJlZmk0N0wrRU54d1NHZmhOenk5NzhpTzg4QVhRekFFVUtob1RDUzF4QVFUVDJVaXYvUEYvekl5QWdWRithSnFkTWFUY2lpSzRxWVZzSUJ2Vy9rVFRleWJpNlhVajJ5NFpxdjBPcE4xd3JncmdrdUZmTHdZZ0RqeXVqVnVEY21WdjVXVk9uNHVCSW5ZNWtQTkFNUFdJaHFWZS9uWTI3TVNWUHM3bnhMdUFRdW9ZY1pQYVJPczg0R3ZsVDFVdUtOdWpGTlNXa0R0VFZWa1h2Y3ZlaW1JazBMSEE4S2d5bTlmZDNMMjFycUJaVGt0RFcwNVpNLzg0TWJETHFlUTU4UnQySXdKWFNkQjl1NGhJZzdpVlRyQ3dYY1BjWnp2c1BDeVdHWnJKT2JDcjZVK21BMkh1QmIyN28wTWp4YmJGbTNHWUd2enRyK1kwZDAvQ1BsUmNjRVBJeWEzZlNsUHhGc1l6Q0pWa3U2bE9KZ2tvNWowUUZjYmkyRkVFczlSdUc4VmFzempaYk4xb2FySlJ6QTBRS2hZOXRNNExHUGhBK0pIeG9lb1lxaWs0c3k2ellqY0N5T1o0MTB0cDdtUFBMWW1HSVRkMy9xTVlwSXl2WURyb0NlOUlobFo1aEt0ZnMrNTNNQ09KcUVmakdCSy9CTUZCTng3dm9pZ1VPcVV1VkQ0bDE4YTJPREhUVFEyK1hwNmUzVzRCb3gyWkJOMWFMS3VzMElIQThJZ3lsZG5hM3hIZTJOWXJKZHhwWlBVOWFWbnhHUTFCSjlvZEFYQ3ZqbzZCQ1hRVWNJWnc1MlBiQ3B3V01KbEo3dWJocm83L0xOZjVmN0Evalk2T2lpQ3M5bUJWd01wdGdkWHlndks5QUFPSklhMTk3dlg5cWxWdS9Cd0U4bjZlTmV6VUhqZzBLdFgyd0pCM0EwZ3lHVWx5R1pMS0xRbXBRVm84Wkgra1JKRXp6eHFScGdvNDBNRFM2cWhmeG1CUnlES1hGeDZhVUZKOTd6M2Y5dEQveVdkSmJKQlFQVUR5YW90ODQyV3cxZGV1MkJxbDB0NWZoTWV2RHFpcGNMc2VHNFRnbGNEZDN0ZHRGUWY3Y29jZ2kycENjQVIwUmF1RWJkVFQxZGc3N2xRT0Y4aGxuc2l5WThteFZ3UEJnTXBwdzlXMlhHeWs1b09iYy9SQW1yYnZSeGx2WTlHSGdmNkdtZ1R5WGxzbVBNSjNCY1kyVFlPS2tYRVBTcGFlK1MybUo5VjlZNGlVa3A5TG43SHFERDd4Mmc0dUl6WW0zV2xzWU9CbzVsUkhnb2htZkltSGtSQmMrRXJuM2wybldQdWdkM1BYVTVMNzg5YStESXVuR2UrcnJHdWhMeGJESldiYUhzMjM4NHBjcFRkd0JJNm5UUTFWSU90WTQyeG11dnF1dmFMaFE0emhsdVlNbmtaQXpzTVNZSm90WThzRW5wdG9hYjZKWmJicVhYWG51Vkp5U01zUG8zTUd5VE9LYTN0MGZNWjlkNk93ZWtmL1hxdGJUNzJwdllKSG1vcnI3bXBaR3hzYS8vNjZNUHQwejVnQzdSQjdNR0xnZFRwRnJIeW9sM1B2Ulh3aHcwZFZPSFFnS2MxejRIZzQ3NFhLM2FnMG01Vk90ekFZN3Z0K2s0TWNTbFdoS3krbG9EZ1V2WXlpcFVFelRJWHJtUnBkZkFvQUZjdlQ5Z2gxbDRXVkJld05kdXQxTjBWQlJsWlc4VmE4YWd1ZGl0cjYycCtxQzFxZUVmbm5qOHAwV1hpTzg1WHp0cjREZ1NhcjJ1dHR3OE9OQXRUblRMRjM1RDlyaXNxYVhjbTlvTWhLNE8yU1QwUUNtWHp0djVBc2ZGbUR5OUFqSkd0YUNhZzdWZzBnM0lzdUZ6OThRUWd6YUsrV1p5ZjBoNVZIUU14Y2JHaVJVZ3RWb2x5emcwMkUvSGozOUkxMTkvRTIzZXZwTzFnVXc2VFZCTlpXVnBXMGZIOTMvNWt4KzhmS25Cbnhkd09aalMzRkFwcmp2cjZuK2dUYnMvSzBwOEE3MzAwVEdsL2x0S1BLRDdnZmFxK2FCU0h1Q3RRd3ZNSk9FbWQ1dndyQUZaTGg4bVBlbVpnS3RCWThaSkNKWVRVYWw3TE54bjU1V2FZM21aVUtPQlYzWms2UjRaY1ZGUFR4ZEZSVWJScWpVYkZha2U3cUhHcGlZcU9KVlAyWnV1b0N1MjdhQlFxeEx2VDNCTmZVTkRVMHRIUzhzdmYvcllJeis1Vk9EUEM3aWNZVnAyK24xeHZRNWVrTytUM3d5K0hLbUVDL0NCMEdIUDFTcmVOYUpVbFlwdDBnU005dmpDczZtQTYwWWFxSys3aGRXMXNxKzZ6UWEyQkEyNElUclV1eXMyWGY2MldLd1VIY01ML0hxWENuWHpjaFdkblczS1ZPYklTREU1WTJCd2tOVzNpOWF1V2NQaGFvelFCdkRrSzhyUFVHVmxPV1drWjlEV2JWZng0b1dUeTQxMmRIUU5NL2huaWp2cXZyWFFreHJPQ3pnZUJ0UjZWZVVaTXhiWWhSMy91Mzk2aFN3UktlSkJhZmlCeWRVWDhUYURRT2pCVkx1QTc3WGxhdUJ3M3FUakpvR1Bzb25RRE5aUmQwY0REZmIzVGlza3dZQkxrQUR0Zzh1ZzFaQ05yTUlqMkI1SFJjWDR3ak5JTXBvekpvYXZkWUtMTEJRelliVnk0U1NyOVBqRVZOWXNyU3pCalJRVEhjM3J0anNvekJvbEZ1SnZiS2ltRDk0L1RDbXA2U3p4TzNrWjhEamZkWThNRGxORlplWCtzWW54enkyVWczZmV3S0hXQndmN3IydHJyaFVYZnYxbmYwRXJzMi95ZS9odWxyWng3dVVTK2t4U0hnejRPRXM0cEgxb2tNSDJWL095MXJYaUZSV3lUZmY2aTBEWTU5anJFSDdiZ2twbFF5cnRkZ2V2T3Vua0JmcVVoRXBmWDYrb2pJMlA0NG1VREhtQXZ4dUZqSkdSTVp5aFUrclpYYXpXQVQrUmwvdm10enVRaWJOM0k0TmQxTkxhUmhiTzRsa3NTbTBkSEQ1b2d2THljcmJ0UmxiM09aU1Nub0xsUGNYblkxeWxjN2EycG5SZ2FQQ0xQLzcrdzVNek9hZnQwblA3OEx5QlE2MGJ3eUplcnlwUlZrWllrWFVsM1hEL1UreXRUNWFTakkyTzhVM2dCK0VZdi8xZ0JyWHVCM3lraXdaN1cybTQvYlNvRU1VNjdNSGFUTURWUUlYcTVpWEExTWZnOHpCV3paRXN6VkRSQ2tCbGdNVm1DeGY3TmpXZEZlWW9KamFlckx6UE1NOFhSMGVBNDRheTUzNysyOHI3cmxxeFFrQWRIY1c5S3RMZjI5dkxOcjVIZEpBSWg4MEh2WTA3QXhyT3RXYjFha3Bmc1ZhOGlvUGZuMFlUL05QYzFOTFMzOVh6Nkw5ODd4dFB6UTNwOUVlZE4zQ2NEbXFkMDZ4bWpFQmhJT0wreDQ2UWhkV2JiT2NEZk5URjZkU2hOb1piSnlDM05kVndqRHdjTk5zbHp6OFZiQ3hQZ3M5a1dDWDI5NjcxSm84QkdFZEVKRXNmdjFYQmEyK2hpUUFSMHRmYTJzSkxaL01VWXkvVTdxNU9zUjMvb3cxeEtqVTBsQXNxMkltRDg5YmQwODJPbkpFMVJBUkx1VlpJTmI0RFRYWUFLZG5MTWpPRkZrQzllMzl2RzUwcEtoSWRaOVhxVGJRc000Mk12UGlCYkoyZDNjT05aK3YrcmFvbzdYdnptY2laRTNDbzliNis3dXM2V1FKaHh6L0pzMUxpVXBXbFFkQm1VdW1qV0dCL29KSGhWbE5QN1dIeEZnSTVvV0FtcUlLaDZnVnpVTjl5THJkNFp4bDVGd253VTlsNnRyYzJzb1dIaStsSmVBc0MvQUg4RFpDZEhXMjhRclNpZm9jWktNNFB5VFZ5Y2dWU2o1VWdvQkdnM2lIQkxTMU52azRBQnkwaElRRkxld20xanM5SFhkNWlEODdLWVp2c0FQRGcwZVMrZ2FvZXI5UmFucGxDWVRhYmtIYTAvdTQrYW1wdW5MZEV6cHlBQzdWdURIMnRwcnBVSEwvMW1udHB3L1hmRkJjb1BWKzEvY1oycU1iaDdtcHFyQzJpcnVyM0NEN0FWQytTbTFaZE13dzFaSnhEVEdYVytzZmJBQVJKNUVFZjN3TlhsdkpXSERZWFF3UmsvTi9UMVNYQ0xrZzlKQTZRQndiNnhmOFlVV3ZuRndiZ0dQd3ZPalJEUm1ld001ald0amF4RDlLclJwT1NoTUxmQm9ZdEd6b0F6Qm8wQUxaM2RYV0xhdzROcy9JNXpjTGVReHV3QXljNjQxVlgzMEJXTmdQcU5qYnNvck9OOVJlY3lKa1RjRnlJVk90NDRPSDJxSFBDTTJtN1IzcnFxS1d1Z09vSzMySkpydmRORVpydXpRcEJCeThZTkRKZWdJMFFES2xSS2MxQzZyM09GaElsa09aUTFRSi82R3dkSFIwc1dYWWg1UUFLYUZEdEFJYzJOTWl2K0dESFNrbzF0dUVjMEFEWUZ4b0J4MkViOXBNYUFNNHBHdFIrSENkamZKQVpNRjdOSmM0OU5DUWNXRnlYWEdvTThPSEl5Wm13NkRnd0N6dDNYVXZoRWVFK0NWZERoNTMzY0R3UEIyK3VpWnc1QTVkcXZidFRXVGpnN204OFQyWmJ2T2pKby8wTjFGU2RkdzVrZWZIbkF4dVFzZHdIR29ZaTFaRGwrV0M3SWMzNGdWMUdlQWdvNkJqUlRxZlliYUMvVHlRL0VGZWpBU0xzTS9iWHc0dnU3eGN3Y1E0SkhVNFoyakMvS2NIdWNBakk4T0poc3ZBWnRFTWtKMTdRQnZuN0lPbW9DSUlRd05hakV3QXlHc0QyOUNsUkJqUURycm0xdFZYc3QzNWpEbTNZdEY3VUdzZ21WWG9nY1BYL0xjMnQ1NTNJbVJOdythWWpZMmpZQWFuVzEreThYOFNsTmZsdlVIdXJNajFwcWpZVGNBQTJoMXFFVk1pWDEwMTRxMkp3VHVtQm04eWh3dFBXQzJkTncvYVhiUzBEZ2VlTmtBcjJHQ0dQeFdvVis3VHpBd1pNL0VBeUFSMFNMNzEwUU94ajc5ckVUdHNJUTBZS1ZTNEZDcUM5SEk5YnZBQ3hIelFFUG9jYWRyRUc2R1VIRGliRXdUOUl1eUpzYTIxckVlY0haRGg1L2R6eFdwcWJLQ0V4MlM4dWgvU3EyMnlBS3gzSnd4RkJuMGprdERmMmZQdkpKeCtkOWsxTWN3SXVMMHdtWVFMZi9UblRLeUpOWVFaZWppdU1lcnN4cml3ZEhMT0FqQ2JmZHdiSXNwUklmaWZQM0JScnVzdVJLN2tVQ1d3d09nS3FVMlFiSGg0U0hRS1NLKzAyT2dEK1IrZ0Y2UUk0aEVYU3UrYzNPdms2Ukh0YnE1QitPRmZvUEppamhuZ2RXZ0NkRVNFYU5BZU9nY29YSFFqT0hsOGp0QURNQkQ1M3NRMkg1NC92WGJGOEpXM2V1b09uSFB1dlUzTWh3T1g5dXZnYWEycnJwMDNrWEJCd21ZVHBhR3YwNjUzQmdHdDVBWjNJeUdpNmN1ZFZJajZ0cUNpandRRWxPUU83Qm51SHhJb0lxVHoraStGRC9VRzFxNGNreDdCWUhnUEFaNUFhT0VxUU1qTkxQU1FhRHgwcFQ2aDJnQWNvQUpGaEZVQXFXVUZlV0lEUEE0ZXNqVU15akhkamhBenFHcllmRWcySW9pUHkrV0FHNE5oQlE4aU9Bd25IUFNPVDJOM2RKVHFSVVBlc2Fad3hzV0kwTFMxanBWK1dMVkQ3elFkd2VjNXh6b00wTlRVRVRlUmNFSEFNbVJwdGtiazE1YWQ4MTYrR0xkN1dhekhTUGZmOEhXMitJb2VlK2orL0Z1b01FeE9oWXRIYW1qdlo3dmNIMWY0R1ZyM3EwU3A0c25pUXZaM2Q1T1FVSmFRYzJTOUluRGswVkVneEhqWUE0ek5vQnlRNEFCdHFYRXE1VlAzUVROaFBjYzZVRGdMSUdQS0Z1b2FUSnVKd1BsYXU5NElMZFRpVVYxNGlac2M1Y1N3U1RjUHNuS0hGeGllSVJBMHljTXRXWklrQkZQZ1AwN1g1Qks3K25sYTJLUTFuNjc0bVIrb3VDRGhPTElkTWg0Y1YwNkVHYmpTYWFkZnVLK25BdS91RUpBSWUxQ1BHa2lHTlVIZnE4WE1oS1d5RG9iWnhIanhNQUI1aGdKQTBTQXBVTWlDakFUVFVLaHFTSHpnV240bEY5UGp0d2RMV1E4MmpFMGhvZ0NuVnNwUmFDNDl0QXdvMEFDUmFldmtTSkxiak9LbXloZmJnYmVnVVhkd3A0QXhHczgzSE5hWm5yT2JYVktjS3YwSzJTd1ZjZkQrbmhrdkx5dmIvNlBzUDNYREJ3T1dRS2Q2S0ZLakt3eXcyR25FcFFKUXNHSTh4c3lRZ0JsWTNDVnJ1QThpai9DQWpHSm9DaHIxaTdod0FwaVJCT0RIQ0hRQmFBZzhjblFmcU9vWWZPangwMkY3aGZiT3F4anc0YUJSNDJYQVdvZUxSU2JBTjE0UHpRZ1BBZVpNaEdKdzNlT2JZSm1Odm1VcVZpUmw4SDY0TGpoMDZBYVI1eGNxMXZNYTgvMHY0TGlWd1hnWmFSQlY0NytzRXJ3NWRVbFo4NVFVRGx5L0p3YXVZb1NMaGVGbDRKUWJZWkJteWFYbTFZOWpxd0NaQnEwZXg0SGtESmtDSU1pUytZSHp1Y0VRSzV3cVNncVFJdEFPa1huUU9MTVBCRWc3N2phYThaM3hDL0ErSmwzOER1TXp4dzV1R0k0VnJnTnJHZG5RZ2RCU29jR2xLY0Q1SU1rQVBEQXlJQkFuZVBRNXB4N0Fwa2kwMU5kV2lrK0djMTkxd0I2MVl0ZXljZTExSUNjY29IU1pNakhHSGhFYUVoQnREalhUaVpIN2NCUVBIbmFGdW5VZVU0cEhhN0dpdjVtSjl4U1pqVHJrNnRneFJ2WlJRL1pKWDJHcEFIV0ViaUwvUjRJa0RHTGFqaGd6bkZ1UFdLRDVRcVhqOEQya2NaSTlZVnJjQUZxUU9qaG5YalF1WStCeVNqRzBBRE9rM2gvcXYzUXB2V3paMFVHZ0RxRzRjSzRkTm9YSGk0NU9FbGlnNmM0cER2V2IyVDNaUVRYVWxuYTJwRlZwazQ5YXRkT3R0ZC9KN3pPTVhUS1ZEbXMxOGJ6ekRsWVk0S2hDZ3VWbDVaTTg5T2tHbkMwOS9HUU15OHdJY2kvTG1mL1Jlc3JwYkI4S1dud25vSG5iWU5LemFoMGQ1SFZlTUcrc0ZMR1Z0VlNWVktqMXpIQ2MrNCsyUWNwa1phK1A0RmczSHdqa1VuN0h0aDBvSFpOaFZXWm9FQ1lWcWxwMEFKZ1doRXV3NmJEMGtYVFowSGh3dlRRV09rZkUyUnI1UUFKRjM4aU0ySDdHMCs3bzc2S3BycnlHTEFjdUJhaWt2L3pROTgvc25xS3Fzak9lbWg5Sm1ybmk1NFliYmVURWt4MFZ6MmlCUVlheGxFTGNmUDE1QVZ2N2V4TlFrbm1BUkpvWjBxeW9ybnl3K0ZmODFPUUF6TDhCLytQTW5TbXcyeDhvLy9mRXBydCtxRXM4dUlqcVNicnp4Rm40OWRCSy9XZUNYTkR3d0xHeUp5V3dnRzB1YVZNV0R2YnorS1hjQ00zdTFJcGNOaVdVZ2tHS1JiK1p0QURyS2tnWm5EdElMK3dscFYvTFhKaUZ0MktZZXBRSnN0ZU1HYVpXU0NqTUIrNncySmZDd3BickhOVmc0VVlLT2tKQ1FKTUxHK3ZvYUljWHJOMnlpcTYvOUdLV2xzZlI2WDc4bGdjUGtvSDF3NURqOXgzTlBVME45cmJqK25Kd3JhUmZueDAzZWNmUno5RDFrNER3VEw1RG1NTE9KZWdZRzZYUkJzUUM5YTJjT3hVU0YwM3RIVDNaVmxKVCthN0JTcW5rQi90MS8rY1crMVZscnJvZGo4T1pmWGhIanZEazdyaFQzQmRYWjJkTkgzM240NjBKbDR3SDA5L0tRSXNOQ0Jzcm5TYk5FQ29sbE95b2wzY0xTQmFod3ZGQXFqRTZBeitIUVFmV0gyK3ppZjlocDJGWTBxRzE0eDhpZEMzdk1IUVRIQTZKSXdYcVRNTmdYa2l3a1dtWHpFY09qNDZXbXBJcU9WMXBTTExRR3IxQkpHN2RmeVErWjQzUStyeG1MOTA0QkhMRTgycjc5QittTjEvOU01YThWaWd3QUFBeHJTVVJCVk1WbGxKaVNTTnUyNWRDV0hidDhSUlpxOExNQmp2MXRQSVJxTkZ1cHRibVpQZTlLenQvSDBJNmNMYXk2VFZSVGQ1YmVQL3lSVU4zQk9oVzJ6UXZ3cnoveXozZHYzcnIxSmFUNTRDREFlMTIrTE1OYjhjS0ZFS3lTQjRaRzZFLy8vZ3dkZmU4OU1SSWtNMlRLaER5dkN2ZUdiYmd3U0d3ZnB5cmxvQWhnUVczTERnSzdEcWNPVHA2WU5DQkdueXdpczRZR2RRMlBIcDBNR2dYaGtsek5DV2xUR2RwaFg0Ums2SUFvVW95S2pCQU9ZMmxwaVlpbnQrMjRtYUtUbE5lZEFEYmFiSUYvZFB3VXZmelNjOVRTMU1pbW9KMHJlRFMwZlBWeTJuYkZObHE3Y1l1djRnWG5uQTQ0N0xMRHlubDZGcDVLZnZsT1RXMmpHRC9mdW1XRFdJK3V1S3lLeWtvclB2M3dOeDc0ODFTZzVmWjVBWTZUUWEwbnBhYXRGREZmOFNtS1MwaW45ZXRXODBOWGtoR3lGUlNXMHJOL2VFS2tIWkU5ZzdSYnd5ZUhNT1hJbFBJMlltVlFCSzJITTFpQWpXMkFDeTFnWXk4WmpwM016Y051b3hOZ0h5dUhoSERLNE5SQjVVTkRTSnVPOHlBc0U0VU9yQ2t5TTFlS1lVclVwSFh3MkhoU2FwWW5lL04yalprQjQzM2tidS9Dd3JNQlBzekRtRWVPZnNTYTdpV2hLWGJ1dXA0N2twTTFWWmludENSUDg1YzNYdWNNNHlqZCs1bFAwWXExa3pVRXdZQmJXV1hidkdWU1o0b3JxSzJqaDUvcENxNnd5UlRQNVBUcENrL0JtYnlkNTFNV05XL0EvM0hQdDlla3BxMDQ0M1RHME50NytlVTRQSGlRdFg0TFpXU21VaFRudWRYZ0IvbWh2UHpuRitud3dmMUN4VU5DaDdrRHdITUhMRWl0dWhZY3NNUndxUEFCZU1BRXNUbXI2VDZXY2xubGdnZWd2SzlFSjhJMk9ITUk3MlMyVFdvR09HSFlCNDVZOXNhTnRHcmRSbDZrNXl6OTZkbG51YWJOUmx1MjM4clRpMkMzT2NMQVd3dG5DYnlqczRNT0g4cmw2VWpGb2hOdHpON09uUzVNUkJzbWRxb0F2THVuUzFOU2xNL0NrQ1lTTStvbWdhUE96YzdINFRwUitYTWk3N1RRZHB1eTE0cENDemliSjArZVBubnExTEhQejJXQ3c3d0J4OFVEK3NwVjY4L3MzL2VtdUVqVWJFZnpxNmhUVTVLRFNudFplUzIvOHZFMzFOdlhJNlIzRURseFZzbDRTRExEaHQ5UzByR1BuTjZEWkF0VU51dzVtcDBCeWpnYy8wdVZMOHdBbXcwWll5L2p3WXVOMmRzb09Wa1ZNckhEMU5MY1RrYy95S1dUSndyb2l1MmJhY1dhYlNJWFBoUHdzOVZjbFhwNHZ5OTNVRmRmSjRaYWtaRFpmYzNOd2x5ME50ZUtvb2VzOWRsa1lXY3hXRE95dytld1dZVlo2dUtDakZNRlJhSmpYckUxbThjZ0hEeiswTStkcWZ4a2VVM2xiUmRTNFRxdndIRWo5Lzc5bDY5SlMwNTh0NFJERXd3d0lGU0M0NFZpL2N5TURISTZJLzJrZllSNzdPdXYvU2ZsdnZzM0liMUlva0Rha2M5V2c4YTUwWWtBR1NvZEhqdlV2ZXdBc0pFeVV5ZVRKcklPRFI0NXhwdzNidDRnbko0QWg5aXYyS0N5b29aeUQremxUamhCMjdadm9lV3JOcENlUFdBMHFkTHhkM1ZSSVIzTTNVdk5qWjIwNTFzUGNkbFRxNmhUazFVcnB3dnp4YlhlOHJIL3djT2cyWDc1Q0RWd1hBOEtIOHhtSTUxbGsxSlFXTXpEcTNhMnp4dTVzNFJTUTNNSE8yS0hYdXBzN1AzQ1RFT2ZRWHRTd01aNUI0N3pZN3pjRm5QeUFJOEk3MnBzVkViU2NGTWJzL21OeGR3MloyY0pSMDQyVE1DcnJXdWtmMy8ydDhLR3d1NE9zVnFHSnc1cFJ5ZEFXS1oraDVwNHR4bWJBNHlnU1pVdmJiZk16cVZuTEtOTm0zTm8rZkowckp6b2E5TUJ4MDZqM0xGS0dOamV2WWU0NXR6QnhRbTdLV2xaSmszd1VoOWxKWVgwenQ2M2hFTWFsYmlhTzUyWlRZeU9NbEs1VkZtclJBcDUrZm5DeTk5eDlUVys3MVJuMmhCRjJNTWpLRHBDS1k0b3E2cWhDdmE0a3pnOXUzclZjcEZScksxcjVoa3NlWDR4OUd5QXpyVFBSUUV1dnhUU0hoM2hlTGUycmxaSUoxUWNmbU1oSDZqNXBBU25BQS9nYUlpMy8vYjJYbjdRYi9yaTdjQVFUdHBpSkZOZ0F2aDF6MExTNFlTaEU4QlIyN1JwcXhoemRqaXM1M2kvK0o2WmdDdjdjQXFYSTR2ajdHbi9kZDhSMnJKeEZWVVdGMUszUzAvaGpqaXVUK000bjB2Y3NDd0lnSXZyZDdYVHJxdHVvTGg0SjQxN0p1ZXBLZmZHNzFYbE1mRElpQ2p1L0ZaaGl5SE5rT3JNNVJtME1qTmRuT05NU1MwVkZaNzh6c1dham5SUmdlTUdJTzJhMFBmK2M4elZkMGRPem00QkhBM1EwYlp0VlR4VkNSMS9OelEyMGZQUFBjT3pOdW9GZU9UTkliMXd4SlFLbURFUmFzSEdRYVhEZ2NQTWpzMWJkMUpXMWlyaE1Nb1c2UDJlRDNCNWpsNjJuMi96QXZuSDgwdElPOXhFMnZCTXpwdEhDdUJZRWlReU1wUnV2dVBqSXJVWkNCcm5RRWlGL0R2aTg0R0JJWkdSUTAzQTJyVXJLQ0UrbmtOSUY1VlVWSGFkTGl6NDhzV2VjSGpSZ2N1SEJtbFBTc2w0a1ZjaGpwYkFSVjZmSzE0UVU2YXlFd1Y3TGh1a1BUZjNYZnJyZi8zRlZ6OE8xUzZrbWNITEFvZ04yWnRwZTg1T0xpRjJUbG40NXp1cDk0L1pTcmo2T0tRdzYrdWJhTysrdzFSOXRsTXNLSkMxTm9OdXZQbG1NZjFJTmdsY3E4Rjd6bXdVdzFFTFl1VzJEbDZZTjc5UW1KOTFHOVlMZGQ3ZU8weUZwL0phOGs1OCtKa1hudm50QVFqSGZOYWdCOTQzL2w4dzRGTGFROElPUGM1bHVldWR6cmhkZ2JOT2QrN1lJdDd5cTViMmx0WU9ldkdGWjZtZXpZS2MzUkdIaEFnbkw3SzNiQ2V6YWluRldkZUJCZFFpek9ZNGFZTXhlNVJmUGl1bUg0MjUvU2N3NGg1UmplcmtZZG9JdTVJQWFtaHNFYUdWVnNlNTlXekUrMkZjT01INStQeFRwVTJOOVhmTkpiUUtCbksyMnhZVXVQcWlFTUo1Tk5iVGRydEZYSU5jb0M4ekk1MVdMazg3UjlyTDJYdnU1N3d4UE5qMHRPQXYrcDBOdUxtb2RCd3owL0NtalJNM1VOdk9TSzZWNCtMRnl1cDZFVm9odzdjdWE3VVlYSUdHeUM4NHRhQ1RCd003d2lVRExpL2tudnNlL0ZWaVF1TC94T2dhRnZBWmRYTnloVzNkTlZkdDk3dFcrZnFxcVNZdkNDaUJ1cHEzelljTm53NDQxSFppUWl5RmNuSUZvRThWbGxObFZSVWxKQ2RTQmp1bWFPVVZWVlJkVXoxdm9kVnNwZm1TcS9SZ0Z3QzdwYk1jdU1wa2pud253bUhWQURnYW9HUGFUV1o2cXBEMjZVREw4eTRVY0todGVOdXBpVEhpcTN0NEpCQjU4M3FPeWRlc1N1SG9JNTU2aHNhb3ZMUjQrUDNEN3o4OU1iaHJ6OFcyemJQdEJKZGN3dFVYK3FuUC8rTWJ6dGlFT3lSd1RMb3pjU2dEVHg1MmZTYm9GeHM0aGlPUk9vYmFSbXZ0N0JWRG9haUUyYkIrRGM4TGo2Qm1YdEtyb3ZSTVM5N3hFNCs5OE94dm5wd3RpSVhhNzdJQ2pwdUdOdzlwajRweWFBQmN2ajlNeHUxRFBOSTFWYnNZd0VWdW15ZFlRRzFIT3NJNWhCcWhocFpPT25UNHFMZ01lTndXenBJMTh5U0hqMDdrdGRmVzFIM2xwVC8rNXRXRkFuaSszM1BaQWNjTnlOZzlKU1h0RHBNcFZMd3dUcjVTYWwzV1N0K2tnY0NiblUvZzhNUXhGZ0MxYldiSkJ1anlxanI2OEtOOGtSOWZ2bklGeDkxYXFqM2J6b01aeDg2NFhmMmZYbWlQKzN4aFkvL0xFcmk4a1U5OS9zRTduYkh4cjBUeitpZ0Fyb3lHWVE1MktLVWtKL2pxdHViVGhodjQvSEZ4Y1F4YW1ZTUcwRWRQbnVhc1dCbWxjSTFhVXJxU0Vhc3VLK1dpd0pPSFN2THo3MTVNN3hTL3JJRUxhZCt6eDJ3Yk5iek5BeSs3SkhCWkE1Zk95MmFvczJvWEl1RmhySll4L0ppZUZNdVZMaTdxN082bDk0L21VVFVYR3l4Zm1jWUpsQVRlUGtwbHhlVmMwM2JrMXhNTy9iY1hla0dldVVoMDRER1hQWEMxdEdkbVpMNFNIWVdVcWxKT2pQdzVFalVKOGRGQzJzOFhPQVpVVUdxY2tSTFB5M0t3ZldiUXplM2RkQ0QzQTEreGdkVVJUWU9jQnMwdk9NTnJ0QlQvV25yY0M1RVZtdy9BaXhZNEx2eXJYMzNVb3JmcGptYW1wNitWd0ZHbzRPSkNnWmlZYUNIdGdkQ0R4ZUZJa3lKSnNpd3RnWWR1alFKMFJVMGpnejVNbytNNldzbVZPblkyRzYxTnJid3N4Nm4yczdWMWoxNk9IdmRjT3NTaWtYRDF6ZDE3MzROZnpjN09mZ0p6dkFCY3czRXhJTHA1dWN0WVp3VFBSSmtjZWxVRFIyd1AwTERQQU4zRmFodWgxZC8yNVZLSTNrSXJ1TjRNeFlrMU5VMVVVbEp3cHEyMTRldkljYy9sd1Y2dXh5eEs0SGlZLy9Ub3oySkhSMGIzYjFpWHRWYkhzVHFtMUtCcUJFT2FTYkhSL0Z1cHBRTndLMWVxSXF4S2pGTVNKUUNOMEtxam81MTZlYTAwOTFnSTJYaHR0V29la3k0cXlqOTAvTmo3WHlvODhVSFo1UXJ0UXE1cjBRS1hOLzN0Ny8za2tkUzA5QjlqcFVNQWgxckhhSnFjcUkrd0N2WlpncTZxYStKcWxsNmUxdHN2eW55cjJDa0xOUms4ZzRNOWJ6WlVWRHl3bUR6dXVZQmY5TUNsdEhQaFgrNnExYXRXU3VBaHZKeVluYWZwSnNaR2lodzNScTBnOVMwdGJWUllWTUh6cDl0NVNzN0FrQzNVK1B2RjZuSC90d1V1Yi95UlIzLzZvdzNyTmowU0htN1dBRGdTSTJqZDdHVlhWOWRSNFpseThRcXFNZGRnWjF0VDdZOExUaDc2eFZ3ZTJtSStaa2xJdUJxQUtKZk9YUFhPdXF5c1dBQ3ZZdEJIUGp6RnF4eTMwT2hRVjMxUFo5dlhUaHpMRGI0aThHSW1PY3RyWDNMQTVYMy80SWYvOWtSU1d1cW45NzY5cjVPellhL2FyZGJIbDdwOW5nM3ovd2NqMEllT1BUVHcxQUFBQUFCSlJVNUVya0pnZ2c9PSIvPjwvZz48L2c+PGcgZGF0YS1jZWxsLWlkPSIxMyI+PGc+PHJlY3QgeD0iMjAiIHk9IjE3MCIgd2lkdGg9IjYwIiBoZWlnaHQ9IjMwIiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiIHBvaW50ZXItZXZlbnRzPSJhbGwiLz48L2c+PGc+PGc+PHN3aXRjaD48Zm9yZWlnbk9iamVjdCBzdHlsZT0ib3ZlcmZsb3c6IHZpc2libGU7IHRleHQtYWxpZ246IGxlZnQ7IiBwb2ludGVyLWV2ZW50cz0ibm9uZSIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgcmVxdWlyZWRGZWF0dXJlcz0iaHR0cDovL3d3dy53My5vcmcvVFIvU1ZHMTEvZmVhdHVyZSNFeHRlbnNpYmlsaXR5Ij48ZGl2IHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiBzdHlsZT0iZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IHVuc2FmZSBjZW50ZXI7IGp1c3RpZnktY29udGVudDogdW5zYWZlIGNlbnRlcjsgd2lkdGg6IDU4cHg7IGhlaWdodDogMXB4OyBwYWRkaW5nLXRvcDogMTg1cHg7IG1hcmdpbi1sZWZ0OiAyMXB4OyI+PGRpdiBzdHlsZT0iYm94LXNpemluZzogYm9yZGVyLWJveDsgZm9udC1zaXplOiAwOyB0ZXh0LWFsaWduOiBjZW50ZXI7IGNvbG9yOiAjMDAwMEZGOyAiPjxkaXYgc3R5bGU9ImRpc3BsYXk6IGlubGluZS1ibG9jazsgZm9udC1zaXplOiAxMnB4OyBmb250LWZhbWlseTogSGVsdmV0aWNhOyBjb2xvcjogbGlnaHQtZGFyaygjMDAwMEZGLCAjY2RjZGZmKTsgbGluZS1oZWlnaHQ6IDEuMjsgcG9pbnRlci1ldmVudHM6IGFsbDsgd2hpdGUtc3BhY2U6IG5vcm1hbDsgd29yZC13cmFwOiBub3JtYWw7ICI+TGlnbmU8YnIgLz4zMDBtPC9kaXY+PC9kaXY+PC9kaXY+PC9mb3JlaWduT2JqZWN0Pjx0ZXh0IHg9IjUwIiB5PSIxODkiIGZpbGw9IiMwMDAwRkYiIGZvbnQtZmFtaWx5PSJIZWx2ZXRpY2EiIGZvbnQtc2l6ZT0iMTJweCIgdGV4dC1hbmNob3I9Im1pZGRsZSI+TGlnbmUuLi48L3RleHQ+PC9zd2l0Y2g+PC9nPjwvZz48L2c+PGcgZGF0YS1jZWxsLWlkPSIxNCI+PGc+PHJlY3QgeD0iMTQwIiB5PSIxMTAiIHdpZHRoPSI2MCIgaGVpZ2h0PSIzMCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJub25lIiBwb2ludGVyLWV2ZW50cz0iYWxsIi8+PC9nPjxnPjxnPjxzd2l0Y2g+PGZvcmVpZ25PYmplY3Qgc3R5bGU9Im92ZXJmbG93OiB2aXNpYmxlOyB0ZXh0LWFsaWduOiBsZWZ0OyIgcG9pbnRlci1ldmVudHM9Im5vbmUiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHJlcXVpcmVkRmVhdHVyZXM9Imh0dHA6Ly93d3cudzMub3JnL1RSL1NWRzExL2ZlYXR1cmUjRXh0ZW5zaWJpbGl0eSI+PGRpdiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIgc3R5bGU9ImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiB1bnNhZmUgY2VudGVyOyBqdXN0aWZ5LWNvbnRlbnQ6IHVuc2FmZSBjZW50ZXI7IHdpZHRoOiA1OHB4OyBoZWlnaHQ6IDFweDsgcGFkZGluZy10b3A6IDEyNXB4OyBtYXJnaW4tbGVmdDogMTQxcHg7Ij48ZGl2IHN0eWxlPSJib3gtc2l6aW5nOiBib3JkZXItYm94OyBmb250LXNpemU6IDA7IHRleHQtYWxpZ246IGNlbnRlcjsgY29sb3I6ICMwMDAwMDA7ICI+PGRpdiBzdHlsZT0iZGlzcGxheTogaW5saW5lLWJsb2NrOyBmb250LXNpemU6IDEycHg7IGZvbnQtZmFtaWx5OiBIZWx2ZXRpY2E7IGNvbG9yOiBsaWdodC1kYXJrKCMwMDAwMDAsICNmZmZmZmYpOyBsaW5lLWhlaWdodDogMS4yOyBwb2ludGVyLWV2ZW50czogYWxsOyB3aGl0ZS1zcGFjZTogbm9ybWFsOyB3b3JkLXdyYXA6IG5vcm1hbDsgIj5Qb3N0ZSBkZSB0cmF2YWlsPC9kaXY+PC9kaXY+PC9kaXY+PC9mb3JlaWduT2JqZWN0Pjx0ZXh0IHg9IjE3MCIgeT0iMTI5IiBmaWxsPSJsaWdodC1kYXJrKCMwMDAwMDAsICNmZmZmZmYpIiBmb250LWZhbWlseT0iSGVsdmV0aWNhIiBmb250LXNpemU9IjEycHgiIHRleHQtYW5jaG9yPSJtaWRkbGUiPlBvc3RlIGRlIHQuLi48L3RleHQ+PC9zd2l0Y2g+PC9nPjwvZz48L2c+PC9nPjwvZz48L2c+PHN3aXRjaD48ZyByZXF1aXJlZEZlYXR1cmVzPSJodHRwOi8vd3d3LnczLm9yZy9UUi9TVkcxMS9mZWF0dXJlI0V4dGVuc2liaWxpdHkiLz48YSB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLC01KSIgeGxpbms6aHJlZj0iaHR0cHM6Ly93d3cuZHJhd2lvLmNvbS9kb2MvZmFxL3N2Zy1leHBvcnQtdGV4dC1wcm9ibGVtcyIgdGFyZ2V0PSJfYmxhbmsiPjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTBweCIgeD0iNTAlIiB5PSIxMDAlIj5UZXh0IGlzIG5vdCBTVkcgLSBjYW5ub3QgZGlzcGxheTwvdGV4dD48L2E+PC9zd2l0Y2g+PC9zdmc+ ``` C'est une application web moderne et responsive pour la visualisation de données de capteurs en temps réel avec des coordonnées X, Y, Z. Elle comprend : - un logiciel d'acquisition - une interface IHM - un service windows pour synchroniser l'heure avec un GPS - un simulateur Python - un utilitaire pour lister les ports COM disponibles ## 📋 Dépôt Source - Capteurs : [Sources]() - Partie IHM : [Sources](https://gitea.aipice.local/HEXA-H/Mkii-IHM) - Acquisition : [Sources](https://gitea.aipice.local/HEXA-H/Hdlc) - Service GPS : [Sources](https://gitea.aipice.local/HEXA-H/GpsTimeSvc) - Simulateur : [Sources]() - Liste COM : [Sources]() ## ✨ Fonctionnalités ### Caractéristiques principales - **Graphiques en Temps Réel** : Visualisation des données issue des capteurs en direct. - **Graphiques Intelligent** : graphiques dynamique avec capacités de zoom, survol des valeurs, ... - **Support Multi-capteurs** : affichage de 7 capteurs simultanément - **Vues Individuelles/Combinées** : Affichage de l'ensemble des capteurs ainsi que le détail pour chacun - **Contrôles d'Échelle et Décalage** : Ajustement en temps réel des valeurs d'échelle et de décalage des capteurs - **Synchronisation de l'heure**: synchronisation de l'heure sur une référence fiable (GPS) ### Simulateur Programme créé pour simuler le fonctionnement des la partie acquisition. - **Simulateur Toujours Actif** : Le programme fonctionne en continu en arrière-plan - **Contrôle d'Acquisition Instantané** : Réagit aux ordres de démarrage / arret - **Communication d'État YAML** : Mises à jour d'état en temps réel via fichier `status.yaml` - **Données** : Génère les données pour tous les capteurs configurés indépendamment de l'état activé ### Interface Utilisateur IHM - **Interface Modale** : Sélection des capteurs, intégration de fichiers et paramètres dans des popups (modal box) - **Suivit d'acquisition** : rafraichissment des graphiques uniquement en mode acquisition - **État en Temps Réel** : Affichage en direct de l'état de l'acquisition et du nombre d'échantillons - **Design Responsive** : Interface basée sur Bootstrap. ### Magnetometer - **Simulateur Continu** : Génération de données de capteurs basée sur Python avec contrôle instantané - **Lecteur CSV Magnétomètre** : Importer et relire des fichiers de données historiques - **Lancement d'Application Externe** : Démarrer des applications externes et lire leurs fichiers de données - **Entrée Temps Réel** : Prêt pour l'intégration de matériel de capteurs en direct ### Gestion de Configuration - **Sauvegardes Automatiques** : Sauvegardes de configuration horodatées. - **Mappage Dynamique des Capteurs** : Configurer les capteurs sans modifications de code ### Gestion des Données - **Fichiers CSV** : Chaque acquisition crée des fichiers de données horodatés - **Navigateur de Fichiers Historiques** : Charge et analyse les sessions de données précédentes ### Déploiement de Production - **PHP 8.2/Apache** : Serveur web professionnel avec configuration personnalisée - **Python 3.12** : pour la partie acquisition et simulateur - **Cpp** : pour certains outils anexes (synchro GPS, ...) ## 🚀 Démarrage Rapide ### Déploiement de Production (Docker) 1. **Installation** 2. **Accéder à l'Application :** - Interface Web : `http://localhost` ### Configuration de Développement 1. **Installer les Dépendances Python :** ```bash pip install -r requirements.txt ``` 2. **Démarrer le Simulateur Continu :** ```bash python3 sensor_simulator.py --rate 10 ``` 3. **Démarrer l'Application :** ```bash cd setup && ./startup.sh ``` 4. **Démarrer le Simulateur de Capteurs :** ```bash # Démarrage de base (contrôle manuel via interface web) ./start_simulator.sh # Démarrage automatique avec projet et campagne ./start_simulator.sh --project test_project --campaign demo_run ``` 5. **Contrôler l'Acquisition :** - Interface Web : Utiliser les contrôles modaux ou l'interface principale - CLI : `python3 simulator_control.py start --project monproject --campaign test` ## 🎮 Contrôle de l'acquisition / du simulateur ### Communication par Fichier d'État L'IHM et Magnetometer.exe lisent régulièrement le fichier `config/status.yaml`, la communication se fait au travers de ce fichier. ```yaml acquisition: campaign: _ commands: [] current_file: _ project: _ sample_count: 0 status: Stopped ``` ### Démarrage de l'application Magnetometer.exe modifie le champs `status:` lors de l'initialisation des capteurs. Quand les capteurs sont correctement initialisés, status prend la valeur `status: Ready` ### Lancement d'une acquisition L'IHM place dans status.yaml, les informations nécessaires : ```yaml ... commands: - type: start project: campaign: ... ``` Le programme Magnetometer.exe 'voit' cette demande et déclanche la lecture des capteurs, il vide le champs 'commands', puis met à jour les informations à transmettre à l'IHM ```yaml acquisition: campaign: commands: [] current_file: MAGNETOMETER___.csv project: sample_count: status: Running ``` ### Arret d'une acquisition L'IHM place dans status.yaml, les informations nécessaires : ```yaml ... commands: - type: stop ... ``` Le programme Magnetometer.exe 'voit' cette demande et arrete la lecture des capteurs, il vide le champs 'commands', puis met à jour les informations. ```yaml acquisition: campaign: - commands: [] current_file: - project: - sample_count: 0 status: Idle ``` ### Arret de magnetometer.exe Le programme Magnetometer.exe met à jour les informations comme suit : ```yaml acquisition: campaign: - commands: [] current_file: - project: - sample_count: 0 status: Not Running ``` ## 📁 Fichiers de Données ### Génération CSV Automatique - **Basé sur Session** : Chaque acquisition crée un nouveau fichier horodaté - **Format** : `SENSOR_YYYY-MM-DD_HH-MM-SS_projet_campagne.csv` - **Localisation** : Dossier `c:/Mkii/data/` - **En-têtes** : Timestamp, Time_s, Bx, By, Bz, Temperature, Angle_X, Angle_Y, Angle_Z ### Accès aux Données Historiques - **Navigateur de Fichiers** : Interface modale pour la sélection de fichiers historiques - **Lecture** : Lecture en temps réel des données historiques - **Importation** : Télécharger des fichiers CSV externes pour analyse ## 🏗️ Architecture ### Composants du Système Le diagramme suivant représente le principe de fonctionnement de l'application. Nous retrouvons les deux processus IHM et Magnetometer.exe qui sont deux applications autonomes. Elles échangent leurs informations au travers du fichier `c:/Mkii/config/status.yaml` ```diagram PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDsgYmFja2dyb3VuZC1jb2xvcjogdHJhbnNwYXJlbnQ7IGNvbG9yLXNjaGVtZTogbGlnaHQgZGFyazsiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHdpZHRoPSI2NTFweCIgaGVpZ2h0PSI1MzFweCIgdmlld0JveD0iLTAuNSAtMC41IDY1MSA1MzEiIGNvbnRlbnQ9IiZsdDtteGZpbGUgaG9zdD0mcXVvdDtlbWJlZC5kaWFncmFtcy5uZXQmcXVvdDsgYWdlbnQ9JnF1b3Q7TW96aWxsYS81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV2luNjQ7IHg2NDsgcnY6MTM1LjApIEdlY2tvLzIwMTAwMTAxIEZpcmVmb3gvMTM1LjAmcXVvdDsgdmVyc2lvbj0mcXVvdDsyOC4xLjEmcXVvdDsmZ3Q7Jmx0O2RpYWdyYW0gaWQ9JnF1b3Q7emNDNXU0Y0d2TlZUUW1oaElKUFImcXVvdDsgbmFtZT0mcXVvdDtQYWdlLTEmcXVvdDsmZ3Q7N1psZGI2TTZFSVovVFc0ckRJRW1sMDNhN2g2cDFhNjJGM3Z0d0FCV0RZNk1zMG4yMTU4eG1LK1liSEowU0t1VnFDSVZqNy9meHg3alllYXRzOE1YU2JmcHE0aUF6MXduT3N5OHg1bnJrcmtiNEQ5dE9WYVdSVUFxUXlKWlpBcTFoamYyRzR6Uk1kWWRpNkRvRlZSQ2NNVzJmV01vOGh4QzFiTlJLY1crWHl3V3ZOL3JsaVpnR2Q1Q3ltM3JUeGFwMU16Q3ZXL3RYNEVsYWQwekNaWlZUa2Jyd21ZbVJVb2pzZStZdktlWnQ1WkNxT29wTzZ5QmEvRnFYYXA2ejJkeW00Rkp5TlUxRmVweC9LSjhaeVpuQnFhTzlXeWwyT1VSNkFyT3pGdnRVNmJnYlV0RG5idEh2bWhMVmNZeFJmRFJOQWRTd2VIc21FZ3pVMXdpSURKUThvaEZUQVhQak1rc2pzQWs5NjNTZ1c5c2FVZGx2NjVIRGQya2Fia1ZBQitNQm1jRVhQd1hQY2hsUFJKSkk0WVRYd3N1WkZuZlc2K2Y4US96Qk5aaVNrL1RkOGFSenAzM3RXdlNIZkVhVzFjOGJ3engzTXZhNFhyZjZzZHd0NEhMNG0wcXBWODJqWUdHNzBtcC83ZWQ0aXdIWTQrb2ZQL1dxT25jT1g3ZjZKWldYVEptbkhkWXhISHNoaUhhQ3lYRk8zUnlvbUFUK01FNFdQdytsWVVOaFN3R29KQXhvSGdUbEdFbzg4VW5VcGxiVlA3NSttcUJ3Y21wdnZpVXN5VFhxSENTZ0tLc3RBUU1UNllIazVHeEtPTG5LUFk5ZVN4eVpjNVdNcEttaFBRMUpRUCtKeGh5UHlOSTZsdVN2dElrQjZWYkFua0hCL2o3OWZYOXo5TTNzUFF0RkZXNzR1NUlVVDdMcCt4WnhxbjJCWlVPSmtmckVxYU1SeS8wS0haNmROaEkrRjZuVnFtUTdEZVdwelVRekphMWlwN1RLL0dtYTVvMkpSUlk1bnN0SkRreHZkSkRyK0FMTFZROUdzRTUzUlpzdzJ1L2xWR1pzSHdsRkM2ZEQzdnBjWmNuSi9lUU94bzZ1WmNqb0wyMzBLNUZsdEU4d2pZZnp1MmF2blBPUmNXNjQ4bU5xZDVTSEdMMXB3MVY2Rk1oVDE3S1lvL3oxdkxEVEZhYkJGYVBlZm5HbkdKRndCWldXOEZ5VmM3ZVgrRVA5Vmc3ZC83TXg3R3VNVTNhTlA1MGNZbHZZemtPbjdLU0RlQmkySU5lRUxpQmNVblRUYk5VeCtBZURITS85bmZtSmN4ajdHRDczYmJhd1NWa1orSjhTODREdDVpYmNhNFA0UTVvdkFuSExKbGM5UzFjOVp4Y3laYTRZOEFsOWk2R3ZCQnk4dFVqZ0hlR3lYK0NzeWIyYmJvQXlmUnVtekRmRnZPSCttcjdmcDVzcDYxOGM4YkxqMlJzMy9idFE5akVZR0lPaHdjZG9zWjVRaDZaeDhlUTA2SmdZWDNLMnVhT1BQMWJhTlVUUkZaRSsrSngxNVhHR1RyT2FxTUVUaFg3MWU5Z1NERFR4M2U5Y2pwQmc1TkxyWHQ2VEJaaUowTXd0ZHhPTVB1a0lmY2tvbU1GTlZHNkJKVFZVTW12bWZoMVNPMW93NFMwSlhIdjM0Wm9FN083QVZFN3ZqRVJiVW5NNXhmMjFyVklUME5ZMXRvWUVha2QxNWlRbmtkcWJhNXJrUWJPeHlGZFdraWZHZDVTQWE4L1oxNlliaG5kTlozVlY3TC85ZFh6NUxQbjBLZTdrVUs3bUd5L01GY1EydS8wM3RPLyZsdDsvZGlhZ3JhbSZndDsmbHQ7L214ZmlsZSZndDsiPjxkZWZzPjxsaW5lYXJHcmFkaWVudCB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSIgaWQ9ImRyYXdpby1zdmctZXppT1hHa3k5OHBvZzRtTGxWd2MtZ3JhZGllbnQtbGlnaHQtZGFya19mZmZmZmZfdmFyXy0tZ2UtZGFyay1jb2xvcl8xMjEyMTJfLTEtbGlnaHQtZGFya19jY2ZmZmZfMDAyNTI1Xy0xLXMtMCI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3R5bGU9InN0b3AtY29sb3I6IGxpZ2h0LWRhcmsoI2ZmZmZmZiwgdmFyKC0tZ2UtZGFyay1jb2xvciwgIzEyMTIxMikpOyBzdG9wLW9wYWNpdHk6IDE7IiBzdG9wLW9wYWNpdHk9IjEiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNDQ0ZGRkYiIHN0eWxlPSJzdG9wLWNvbG9yOiBsaWdodC1kYXJrKHJnYigyMDQsIDI1NSwgMjU1KSwgcmdiKDAsIDM3LCAzNykpOyBzdG9wLW9wYWNpdHk6IDE7IiBzdG9wLW9wYWNpdHk9IjEiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48Zz48ZyBkYXRhLWNlbGwtaWQ9IjAiPjxnIGRhdGEtY2VsbC1pZD0iMSI+PGcgZGF0YS1jZWxsLWlkPSIyMCI+PGc+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjY1MCIgaGVpZ2h0PSI1MzAiIGZpbGw9IiNmZmZmZmYiIHN0eWxlPSJmaWxsOiBsaWdodC1kYXJrKCNmZmZmZmYsIHZhcigtLWdlLWRhcmstY29sb3IsICMxMjEyMTIpKTsgc3Ryb2tlOiBsaWdodC1kYXJrKHJnYigwLCAwLCAwKSwgcmdiKDI1NSwgMjU1LCAyNTUpKTsiIHN0cm9rZT0iIzAwMDAwMCIgcG9pbnRlci1ldmVudHM9ImFsbCIvPjwvZz48L2c+PGcgZGF0YS1jZWxsLWlkPSIxOCI+PGc+PHJlY3QgeD0iMjEwIiB5PSIxODAiIHdpZHRoPSIyNDAiIGhlaWdodD0iMzMwIiByeD0iMzYiIHJ5PSIzNiIgZmlsbC1vcGFjaXR5PSIwLjUiIGZpbGw9InVybCgjZHJhd2lvLXN2Zy1lemlPWEdreTk4cG9nNG1MbFZ3Yy1ncmFkaWVudC1saWdodC1kYXJrX2ZmZmZmZl92YXJfLS1nZS1kYXJrLWNvbG9yXzEyMTIxMl8tMS1saWdodC1kYXJrX2NjZmZmZl8wMDI1MjVfLTEtcy0wKSIgc3R5bGU9ImZpbGw6IHVybCgmcXVvdDsjZHJhd2lvLXN2Zy1lemlPWEdreTk4cG9nNG1MbFZ3Yy1ncmFkaWVudC1saWdodC1kYXJrX2ZmZmZmZl92YXJfLS1nZS1kYXJrLWNvbG9yXzEyMTIxMl8tMS1saWdodC1kYXJrX2NjZmZmZl8wMDI1MjVfLTEtcy0wJnF1b3Q7KTsgc3Ryb2tlOiBsaWdodC1kYXJrKHJnYigwLCAwLCAwKSwgcmdiKDI1NSwgMjU1LCAyNTUpKTsiIHN0cm9rZT0iIzAwMDAwMCIgc3Ryb2tlLW9wYWNpdHk9IjAuNSIgcG9pbnRlci1ldmVudHM9ImFsbCIvPjwvZz48L2c+PGcgZGF0YS1jZWxsLWlkPSIyIj48Zz48cGF0aCBkPSJNIDIwIDIwIEwgMTgwIDIwIEwgMjAwIDQwIEwgMjAwIDE1MCBMIDQwIDE1MCBMIDIwIDEzMCBMIDIwIDIwIFoiIGZpbGw9IiNmZmYyY2MiIHN0eWxlPSJmaWxsOiBsaWdodC1kYXJrKHJnYigyNTUsIDI0MiwgMjA0KSwgcmdiKDQwLCAyOSwgMCkpOyBzdHJva2U6IGxpZ2h0LWRhcmsocmdiKDIxNCwgMTgyLCA4NiksIHJnYigxMDksIDgxLCAwKSk7IiBzdHJva2U9IiNkNmI2NTYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgcG9pbnRlci1ldmVudHM9ImFsbCIvPjxwYXRoIGQ9Ik0gMjAgMjAgTCAxODAgMjAgTCAyMDAgNDAgTCA0MCA0MCBaIiBmaWxsLW9wYWNpdHk9IjAuMDUiIGZpbGw9IiMwMDAwMDAiIHN0eWxlPSJmaWxsOiBsaWdodC1kYXJrKHJnYigwLCAwLCAwKSwgcmdiKDIzNywgMjM3LCAyMzcpKTsiIHN0cm9rZT0ibm9uZSIgcG9pbnRlci1ldmVudHM9ImFsbCIvPjxwYXRoIGQ9Ik0gMjAgMjAgTCA0MCA0MCBMIDQwIDE1MCBMIDIwIDEzMCBaIiBmaWxsLW9wYWNpdHk9IjAuMSIgZmlsbD0iIzAwMDAwMCIgc3R5bGU9ImZpbGw6IGxpZ2h0LWRhcmsocmdiKDAsIDAsIDApLCByZ2IoMjM3LCAyMzcsIDIzNykpOyIgc3Ryb2tlPSJub25lIiBwb2ludGVyLWV2ZW50cz0iYWxsIi8+PHBhdGggZD0iTSA0MCAxNTAgTCA0MCA0MCBMIDIwIDIwIE0gNDAgNDAgTCAyMDAgNDAiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2Q2YjY1NiIgc3R5bGU9InN0cm9rZTogbGlnaHQtZGFyayhyZ2IoMjE0LCAxODIsIDg2KSwgcmdiKDEwOSwgODEsIDApKTsiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgcG9pbnRlci1ldmVudHM9ImFsbCIvPjwvZz48L2c+PGcgZGF0YS1jZWxsLWlkPSIzIj48Zz48cGF0aCBkPSJNIDQ1MCAyMCBMIDYxMCAyMCBMIDYzMCA0MCBMIDYzMCAxNTAgTCA0NzAgMTUwIEwgNDUwIDEzMCBMIDQ1MCAyMCBaIiBmaWxsPSIjZmZmMmNjIiBzdHlsZT0iZmlsbDogbGlnaHQtZGFyayhyZ2IoMjU1LCAyNDIsIDIwNCksIHJnYig0MCwgMjksIDApKTsgc3Ryb2tlOiBsaWdodC1kYXJrKHJnYigyMTQsIDE4MiwgODYpLCByZ2IoMTA5LCA4MSwgMCkpOyIgc3Ryb2tlPSIjZDZiNjU2IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHBvaW50ZXItZXZlbnRzPSJhbGwiLz48cGF0aCBkPSJNIDQ1MCAyMCBMIDYxMCAyMCBMIDYzMCA0MCBMIDQ3MCA0MCBaIiBmaWxsLW9wYWNpdHk9IjAuMDUiIGZpbGw9IiMwMDAwMDAiIHN0eWxlPSJmaWxsOiBsaWdodC1kYXJrKHJnYigwLCAwLCAwKSwgcmdiKDIzNywgMjM3LCAyMzcpKTsiIHN0cm9rZT0ibm9uZSIgcG9pbnRlci1ldmVudHM9ImFsbCIvPjxwYXRoIGQ9Ik0gNDUwIDIwIEwgNDcwIDQwIEwgNDcwIDE1MCBMIDQ1MCAxMzAgWiIgZmlsbC1vcGFjaXR5PSIwLjEiIGZpbGw9IiMwMDAwMDAiIHN0eWxlPSJmaWxsOiBsaWdodC1kYXJrKHJnYigwLCAwLCAwKSwgcmdiKDIzNywgMjM3LCAyMzcpKTsiIHN0cm9rZT0ibm9uZSIgcG9pbnRlci1ldmVudHM9ImFsbCIvPjxwYXRoIGQ9Ik0gNDcwIDE1MCBMIDQ3MCA0MCBMIDQ1MCAyMCBNIDQ3MCA0MCBMIDYzMCA0MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZDZiNjU2IiBzdHlsZT0ic3Ryb2tlOiBsaWdodC1kYXJrKHJnYigyMTQsIDE4MiwgODYpLCByZ2IoMTA5LCA4MSwgMCkpOyIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBwb2ludGVyLWV2ZW50cz0iYWxsIi8+PC9nPjwvZz48ZyBkYXRhLWNlbGwtaWQ9IjQiPjxnPjxyZWN0IHg9IjgwIiB5PSI4MCIgd2lkdGg9IjYwIiBoZWlnaHQ9IjMwIiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiIHBvaW50ZXItZXZlbnRzPSJhbGwiLz48L2c+PGc+PGc+PHN3aXRjaD48Zm9yZWlnbk9iamVjdCBzdHlsZT0ib3ZlcmZsb3c6IHZpc2libGU7IHRleHQtYWxpZ246IGxlZnQ7IiBwb2ludGVyLWV2ZW50cz0ibm9uZSIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgcmVxdWlyZWRGZWF0dXJlcz0iaHR0cDovL3d3dy53My5vcmcvVFIvU1ZHMTEvZmVhdHVyZSNFeHRlbnNpYmlsaXR5Ij48ZGl2IHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiBzdHlsZT0iZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IHVuc2FmZSBjZW50ZXI7IGp1c3RpZnktY29udGVudDogdW5zYWZlIGNlbnRlcjsgd2lkdGg6IDU4cHg7IGhlaWdodDogMXB4OyBwYWRkaW5nLXRvcDogOTVweDsgbWFyZ2luLWxlZnQ6IDgxcHg7Ij48ZGl2IHN0eWxlPSJib3gtc2l6aW5nOiBib3JkZXItYm94OyBmb250LXNpemU6IDA7IHRleHQtYWxpZ246IGNlbnRlcjsgY29sb3I6ICMwMDAwMDA7ICI+PGRpdiBzdHlsZT0iZGlzcGxheTogaW5saW5lLWJsb2NrOyBmb250LXNpemU6IDE2cHg7IGZvbnQtZmFtaWx5OiBIZWx2ZXRpY2E7IGNvbG9yOiBsaWdodC1kYXJrKCMwMDAwMDAsICNmZmZmZmYpOyBsaW5lLWhlaWdodDogMS4yOyBwb2ludGVyLWV2ZW50czogYWxsOyB3aGl0ZS1zcGFjZTogbm9ybWFsOyB3b3JkLXdyYXA6IG5vcm1hbDsgIj5JSE08L2Rpdj48L2Rpdj48L2Rpdj48L2ZvcmVpZ25PYmplY3Q+PHRleHQgeD0iMTEwIiB5PSIxMDAiIGZpbGw9ImxpZ2h0LWRhcmsoIzAwMDAwMCwgI2ZmZmZmZikiIGZvbnQtZmFtaWx5PSJIZWx2ZXRpY2EiIGZvbnQtc2l6ZT0iMTZweCIgdGV4dC1hbmNob3I9Im1pZGRsZSI+SUhNPC90ZXh0Pjwvc3dpdGNoPjwvZz48L2c+PC9nPjxnIGRhdGEtY2VsbC1pZD0iNSI+PGc+PHJlY3QgeD0iNTIwIiB5PSI4MCIgd2lkdGg9IjYwIiBoZWlnaHQ9IjMwIiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiIHBvaW50ZXItZXZlbnRzPSJhbGwiLz48L2c+PGc+PGc+PHN3aXRjaD48Zm9yZWlnbk9iamVjdCBzdHlsZT0ib3ZlcmZsb3c6IHZpc2libGU7IHRleHQtYWxpZ246IGxlZnQ7IiBwb2ludGVyLWV2ZW50cz0ibm9uZSIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgcmVxdWlyZWRGZWF0dXJlcz0iaHR0cDovL3d3dy53My5vcmcvVFIvU1ZHMTEvZmVhdHVyZSNFeHRlbnNpYmlsaXR5Ij48ZGl2IHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiBzdHlsZT0iZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IHVuc2FmZSBjZW50ZXI7IGp1c3RpZnktY29udGVudDogdW5zYWZlIGNlbnRlcjsgd2lkdGg6IDU4cHg7IGhlaWdodDogMXB4OyBwYWRkaW5nLXRvcDogOTVweDsgbWFyZ2luLWxlZnQ6IDUyMXB4OyI+PGRpdiBzdHlsZT0iYm94LXNpemluZzogYm9yZGVyLWJveDsgZm9udC1zaXplOiAwOyB0ZXh0LWFsaWduOiBjZW50ZXI7IGNvbG9yOiAjMDAwMDAwOyAiPjxkaXYgc3R5bGU9ImRpc3BsYXk6IGlubGluZS1ibG9jazsgZm9udC1zaXplOiAxNnB4OyBmb250LWZhbWlseTogSGVsdmV0aWNhOyBjb2xvcjogbGlnaHQtZGFyaygjMDAwMDAwLCAjZmZmZmZmKTsgbGluZS1oZWlnaHQ6IDEuMjsgcG9pbnRlci1ldmVudHM6IGFsbDsgd2hpdGUtc3BhY2U6IG5vcm1hbDsgd29yZC13cmFwOiBub3JtYWw7ICI+TWFnbmV0b21ldGVyLmV4ZTwvZGl2PjwvZGl2PjwvZGl2PjwvZm9yZWlnbk9iamVjdD48dGV4dCB4PSI1NTAiIHk9IjEwMCIgZmlsbD0ibGlnaHQtZGFyaygjMDAwMDAwLCAjZmZmZmZmKSIgZm9udC1mYW1pbHk9IkhlbHZldGljYSIgZm9udC1zaXplPSIxNnB4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj5NYWduZXRvLi4uPC90ZXh0Pjwvc3dpdGNoPjwvZz48L2c+PC9nPjxnIGRhdGEtY2VsbC1pZD0iNiI+PGc+PHBhdGggZD0iTSAyNjAgMjUwIEwgMjYwIDIyMCBMIDQwMCAyMjAgTCA0MDAgMjUwIiBmaWxsPSIjZmZmZmZmIiBzdHlsZT0iZmlsbDogbGlnaHQtZGFyaygjZmZmZmZmLCB2YXIoLS1nZS1kYXJrLWNvbG9yLCAjMTIxMjEyKSk7IHN0cm9rZTogbGlnaHQtZGFyayhyZ2IoMCwgMCwgMCksIHJnYigyNTUsIDI1NSwgMjU1KSk7IiBzdHJva2U9IiMwMDAwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgcG9pbnRlci1ldmVudHM9ImFsbCIvPjxwYXRoIGQ9Ik0gMjYwIDI1MCBMIDI2MCAzMTAgTCA0MDAgMzEwIEwgNDAwIDI1MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwMDAwIiBzdHlsZT0ic3Ryb2tlOiBsaWdodC1kYXJrKHJnYigwLCAwLCAwKSwgcmdiKDI1NSwgMjU1LCAyNTUpKTsiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgcG9pbnRlci1ldmVudHM9Im5vbmUiLz48cGF0aCBkPSJNIDI2MCAyNTAgTCA0MDAgMjUwIiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAwMDAiIHN0eWxlPSJzdHJva2U6IGxpZ2h0LWRhcmsocmdiKDAsIDAsIDApLCByZ2IoMjU1LCAyNTUsIDI1NSkpOyIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBwb2ludGVyLWV2ZW50cz0ibm9uZSIvPjwvZz48Zz48Zz48c3dpdGNoPjxmb3JlaWduT2JqZWN0IHN0eWxlPSJvdmVyZmxvdzogdmlzaWJsZTsgdGV4dC1hbGlnbjogbGVmdDsiIHBvaW50ZXItZXZlbnRzPSJub25lIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiByZXF1aXJlZEZlYXR1cmVzPSJodHRwOi8vd3d3LnczLm9yZy9UUi9TVkcxMS9mZWF0dXJlI0V4dGVuc2liaWxpdHkiPjxkaXYgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiIHN0eWxlPSJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogdW5zYWZlIGNlbnRlcjsganVzdGlmeS1jb250ZW50OiB1bnNhZmUgY2VudGVyOyB3aWR0aDogMTM4cHg7IGhlaWdodDogMXB4OyBwYWRkaW5nLXRvcDogMjM1cHg7IG1hcmdpbi1sZWZ0OiAyNjFweDsiPjxkaXYgc3R5bGU9ImJveC1zaXppbmc6IGJvcmRlci1ib3g7IGZvbnQtc2l6ZTogMDsgdGV4dC1hbGlnbjogY2VudGVyOyBjb2xvcjogIzAwMDAwMDsgIj48ZGl2IHN0eWxlPSJkaXNwbGF5OiBpbmxpbmUtYmxvY2s7IGZvbnQtc2l6ZTogMTJweDsgZm9udC1mYW1pbHk6IEhlbHZldGljYTsgY29sb3I6IGxpZ2h0LWRhcmsoIzAwMDAwMCwgI2ZmZmZmZik7IGxpbmUtaGVpZ2h0OiAxLjI7IHBvaW50ZXItZXZlbnRzOiBhbGw7IHdoaXRlLXNwYWNlOiBub3JtYWw7IHdvcmQtd3JhcDogbm9ybWFsOyAiPnN0YXR1cy55YW1sPC9kaXY+PC9kaXY+PC9kaXY+PC9mb3JlaWduT2JqZWN0Pjx0ZXh0IHg9IjMzMCIgeT0iMjM5IiBmaWxsPSJsaWdodC1kYXJrKCMwMDAwMDAsICNmZmZmZmYpIiBmb250LWZhbWlseT0iSGVsdmV0aWNhIiBmb250LXNpemU9IjEycHgiIHRleHQtYW5jaG9yPSJtaWRkbGUiPnN0YXR1cy55YW1sPC90ZXh0Pjwvc3dpdGNoPjwvZz48L2c+PGcgZGF0YS1jZWxsLWlkPSI3Ij48Zz48cmVjdCB4PSIyNjAiIHk9IjI1MCIgd2lkdGg9IjE0MCIgaGVpZ2h0PSIzMCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJub25lIiBwb2ludGVyLWV2ZW50cz0iYWxsIi8+PC9nPjxnPjxnPjxzd2l0Y2g+PGZvcmVpZ25PYmplY3Qgc3R5bGU9Im92ZXJmbG93OiB2aXNpYmxlOyB0ZXh0LWFsaWduOiBsZWZ0OyIgcG9pbnRlci1ldmVudHM9Im5vbmUiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHJlcXVpcmVkRmVhdHVyZXM9Imh0dHA6Ly93d3cudzMub3JnL1RSL1NWRzExL2ZlYXR1cmUjRXh0ZW5zaWJpbGl0eSI+PGRpdiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIgc3R5bGU9ImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiB1bnNhZmUgY2VudGVyOyBqdXN0aWZ5LWNvbnRlbnQ6IHVuc2FmZSBmbGV4LXN0YXJ0OyB3aWR0aDogMTMwcHg7IGhlaWdodDogMXB4OyBwYWRkaW5nLXRvcDogMjY1cHg7IG1hcmdpbi1sZWZ0OiAyNjZweDsiPjxkaXYgc3R5bGU9ImJveC1zaXppbmc6IGJvcmRlci1ib3g7IGZvbnQtc2l6ZTogMDsgdGV4dC1hbGlnbjogbGVmdDsgbWF4LWhlaWdodDogMjZweDsgb3ZlcmZsb3c6IGhpZGRlbjsgY29sb3I6ICMwMDAwMDA7ICI+PGRpdiBzdHlsZT0iZGlzcGxheTogaW5saW5lLWJsb2NrOyBmb250LXNpemU6IDEycHg7IGZvbnQtZmFtaWx5OiBIZWx2ZXRpY2E7IGNvbG9yOiBsaWdodC1kYXJrKCMwMDAwMDAsICNmZmZmZmYpOyBsaW5lLWhlaWdodDogMS4yOyBwb2ludGVyLWV2ZW50czogYWxsOyB3aGl0ZS1zcGFjZTogbm9ybWFsOyB3b3JkLXdyYXA6IG5vcm1hbDsgIj5Db21tYW5kczo8L2Rpdj48L2Rpdj48L2Rpdj48L2ZvcmVpZ25PYmplY3Q+PHRleHQgeD0iMjY2IiB5PSIyNjkiIGZpbGw9ImxpZ2h0LWRhcmsoIzAwMDAwMCwgI2ZmZmZmZikiIGZvbnQtZmFtaWx5PSJIZWx2ZXRpY2EiIGZvbnQtc2l6ZT0iMTJweCI+Q29tbWFuZHM6PC90ZXh0Pjwvc3dpdGNoPjwvZz48L2c+PC9nPjxnIGRhdGEtY2VsbC1pZD0iOCI+PGc+PHJlY3QgeD0iMjYwIiB5PSIyODAiIHdpZHRoPSIxNDAiIGhlaWdodD0iMzAiIGZpbGw9Im5vbmUiIHN0cm9rZT0ibm9uZSIgcG9pbnRlci1ldmVudHM9ImFsbCIvPjwvZz48Zz48Zz48c3dpdGNoPjxmb3JlaWduT2JqZWN0IHN0eWxlPSJvdmVyZmxvdzogdmlzaWJsZTsgdGV4dC1hbGlnbjogbGVmdDsiIHBvaW50ZXItZXZlbnRzPSJub25lIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiByZXF1aXJlZEZlYXR1cmVzPSJodHRwOi8vd3d3LnczLm9yZy9UUi9TVkcxMS9mZWF0dXJlI0V4dGVuc2liaWxpdHkiPjxkaXYgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiIHN0eWxlPSJkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogdW5zYWZlIGNlbnRlcjsganVzdGlmeS1jb250ZW50OiB1bnNhZmUgZmxleC1zdGFydDsgd2lkdGg6IDEzMHB4OyBoZWlnaHQ6IDFweDsgcGFkZGluZy10b3A6IDI5NXB4OyBtYXJnaW4tbGVmdDogMjY2cHg7Ij48ZGl2IHN0eWxlPSJib3gtc2l6aW5nOiBib3JkZXItYm94OyBmb250LXNpemU6IDA7IHRleHQtYWxpZ246IGxlZnQ7IG1heC1oZWlnaHQ6IDI2cHg7IG92ZXJmbG93OiBoaWRkZW47IGNvbG9yOiAjMDAwMDAwOyAiPjxkaXYgc3R5bGU9ImRpc3BsYXk6IGlubGluZS1ibG9jazsgZm9udC1zaXplOiAxMnB4OyBmb250LWZhbWlseTogSGVsdmV0aWNhOyBjb2xvcjogbGlnaHQtZGFyaygjMDAwMDAwLCAjZmZmZmZmKTsgbGluZS1oZWlnaHQ6IDEuMjsgcG9pbnRlci1ldmVudHM6IGFsbDsgd2hpdGUtc3BhY2U6IG5vcm1hbDsgd29yZC13cmFwOiBub3JtYWw7ICI+c3RhdHVzOiA8L2Rpdj48L2Rpdj48L2Rpdj48L2ZvcmVpZ25PYmplY3Q+PHRleHQgeD0iMjY2IiB5PSIyOTkiIGZpbGw9ImxpZ2h0LWRhcmsoIzAwMDAwMCwgI2ZmZmZmZikiIGZvbnQtZmFtaWx5PSJIZWx2ZXRpY2EiIGZvbnQtc2l6ZT0iMTJweCI+c3RhdHVzOiA8L3RleHQ+PC9zd2l0Y2g+PC9nPjwvZz48L2c+PC9nPjxnIGRhdGEtY2VsbC1pZD0iMTAiPjxnPjxwYXRoIGQ9Ik0gMjYwIDM4MCBMIDI2MCAzNTAgTCA0MDAgMzUwIEwgNDAwIDM4MCIgZmlsbD0iI2ZmZmZmZiIgc3R5bGU9ImZpbGw6IGxpZ2h0LWRhcmsoI2ZmZmZmZiwgdmFyKC0tZ2UtZGFyay1jb2xvciwgIzEyMTIxMikpOyBzdHJva2U6IGxpZ2h0LWRhcmsocmdiKDAsIDAsIDApLCByZ2IoMjU1LCAyNTUsIDI1NSkpOyIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHBvaW50ZXItZXZlbnRzPSJhbGwiLz48cGF0aCBkPSJNIDI2MCAzODAgTCAyNjAgNDcwIEwgNDAwIDQ3MCBMIDQwMCAzODAiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMDAwMCIgc3R5bGU9InN0cm9rZTogbGlnaHQtZGFyayhyZ2IoMCwgMCwgMCksIHJnYigyNTUsIDI1NSwgMjU1KSk7IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHBvaW50ZXItZXZlbnRzPSJub25lIi8+PHBhdGggZD0iTSAyNjAgMzgwIEwgNDAwIDM4MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwMDAwIiBzdHlsZT0ic3Ryb2tlOiBsaWdodC1kYXJrKHJnYigwLCAwLCAwKSwgcmdiKDI1NSwgMjU1LCAyNTUpKTsiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgcG9pbnRlci1ldmVudHM9Im5vbmUiLz48L2c+PGc+PGc+PHN3aXRjaD48Zm9yZWlnbk9iamVjdCBzdHlsZT0ib3ZlcmZsb3c6IHZpc2libGU7IHRleHQtYWxpZ246IGxlZnQ7IiBwb2ludGVyLWV2ZW50cz0ibm9uZSIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgcmVxdWlyZWRGZWF0dXJlcz0iaHR0cDovL3d3dy53My5vcmcvVFIvU1ZHMTEvZmVhdHVyZSNFeHRlbnNpYmlsaXR5Ij48ZGl2IHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiBzdHlsZT0iZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IHVuc2FmZSBjZW50ZXI7IGp1c3RpZnktY29udGVudDogdW5zYWZlIGNlbnRlcjsgd2lkdGg6IDEzOHB4OyBoZWlnaHQ6IDFweDsgcGFkZGluZy10b3A6IDM2NXB4OyBtYXJnaW4tbGVmdDogMjYxcHg7Ij48ZGl2IHN0eWxlPSJib3gtc2l6aW5nOiBib3JkZXItYm94OyBmb250LXNpemU6IDA7IHRleHQtYWxpZ246IGNlbnRlcjsgY29sb3I6ICMwMDAwMDA7ICI+PGRpdiBzdHlsZT0iZGlzcGxheTogaW5saW5lLWJsb2NrOyBmb250LXNpemU6IDEycHg7IGZvbnQtZmFtaWx5OiBIZWx2ZXRpY2E7IGNvbG9yOiBsaWdodC1kYXJrKCMwMDAwMDAsICNmZmZmZmYpOyBsaW5lLWhlaWdodDogMS4yOyBwb2ludGVyLWV2ZW50czogYWxsOyB3aGl0ZS1zcGFjZTogbm9ybWFsOyB3b3JkLXdyYXA6IG5vcm1hbDsgIj5jb25maWcueWFtbDwvZGl2PjwvZGl2PjwvZGl2PjwvZm9yZWlnbk9iamVjdD48dGV4dCB4PSIzMzAiIHk9IjM2OSIgZmlsbD0ibGlnaHQtZGFyaygjMDAwMDAwLCAjZmZmZmZmKSIgZm9udC1mYW1pbHk9IkhlbHZldGljYSIgZm9udC1zaXplPSIxMnB4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIj5jb25maWcueWFtbDwvdGV4dD48L3N3aXRjaD48L2c+PC9nPjxnIGRhdGEtY2VsbC1pZD0iMTEiPjxnPjxyZWN0IHg9IjI2MCIgeT0iMzgwIiB3aWR0aD0iMTQwIiBoZWlnaHQ9IjMwIiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiIHBvaW50ZXItZXZlbnRzPSJhbGwiLz48L2c+PGc+PGc+PHN3aXRjaD48Zm9yZWlnbk9iamVjdCBzdHlsZT0ib3ZlcmZsb3c6IHZpc2libGU7IHRleHQtYWxpZ246IGxlZnQ7IiBwb2ludGVyLWV2ZW50cz0ibm9uZSIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgcmVxdWlyZWRGZWF0dXJlcz0iaHR0cDovL3d3dy53My5vcmcvVFIvU1ZHMTEvZmVhdHVyZSNFeHRlbnNpYmlsaXR5Ij48ZGl2IHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiBzdHlsZT0iZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IHVuc2FmZSBjZW50ZXI7IGp1c3RpZnktY29udGVudDogdW5zYWZlIGZsZXgtc3RhcnQ7IHdpZHRoOiAxMzBweDsgaGVpZ2h0OiAxcHg7IHBhZGRpbmctdG9wOiAzOTVweDsgbWFyZ2luLWxlZnQ6IDI2NnB4OyI+PGRpdiBzdHlsZT0iYm94LXNpemluZzogYm9yZGVyLWJveDsgZm9udC1zaXplOiAwOyB0ZXh0LWFsaWduOiBsZWZ0OyBtYXgtaGVpZ2h0OiAyNnB4OyBvdmVyZmxvdzogaGlkZGVuOyBjb2xvcjogIzAwMDAwMDsgIj48ZGl2IHN0eWxlPSJkaXNwbGF5OiBpbmxpbmUtYmxvY2s7IGZvbnQtc2l6ZTogMTJweDsgZm9udC1mYW1pbHk6IEhlbHZldGljYTsgY29sb3I6IGxpZ2h0LWRhcmsoIzAwMDAwMCwgI2ZmZmZmZik7IGxpbmUtaGVpZ2h0OiAxLjI7IHBvaW50ZXItZXZlbnRzOiBhbGw7IHdoaXRlLXNwYWNlOiBub3JtYWw7IHdvcmQtd3JhcDogbm9ybWFsOyAiPnNlbnNvcnM6PC9kaXY+PC9kaXY+PC9kaXY+PC9mb3JlaWduT2JqZWN0Pjx0ZXh0IHg9IjI2NiIgeT0iMzk5IiBmaWxsPSJsaWdodC1kYXJrKCMwMDAwMDAsICNmZmZmZmYpIiBmb250LWZhbWlseT0iSGVsdmV0aWNhIiBmb250LXNpemU9IjEycHgiPnNlbnNvcnM6PC90ZXh0Pjwvc3dpdGNoPjwvZz48L2c+PC9nPjxnIGRhdGEtY2VsbC1pZD0iMTIiPjxnPjxyZWN0IHg9IjI2MCIgeT0iNDEwIiB3aWR0aD0iMTQwIiBoZWlnaHQ9IjMwIiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiIHBvaW50ZXItZXZlbnRzPSJhbGwiLz48L2c+PGc+PGc+PHN3aXRjaD48Zm9yZWlnbk9iamVjdCBzdHlsZT0ib3ZlcmZsb3c6IHZpc2libGU7IHRleHQtYWxpZ246IGxlZnQ7IiBwb2ludGVyLWV2ZW50cz0ibm9uZSIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgcmVxdWlyZWRGZWF0dXJlcz0iaHR0cDovL3d3dy53My5vcmcvVFIvU1ZHMTEvZmVhdHVyZSNFeHRlbnNpYmlsaXR5Ij48ZGl2IHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiBzdHlsZT0iZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IHVuc2FmZSBjZW50ZXI7IGp1c3RpZnktY29udGVudDogdW5zYWZlIGZsZXgtc3RhcnQ7IHdpZHRoOiAxMzBweDsgaGVpZ2h0OiAxcHg7IHBhZGRpbmctdG9wOiA0MjVweDsgbWFyZ2luLWxlZnQ6IDI2NnB4OyI+PGRpdiBzdHlsZT0iYm94LXNpemluZzogYm9yZGVyLWJveDsgZm9udC1zaXplOiAwOyB0ZXh0LWFsaWduOiBsZWZ0OyBtYXgtaGVpZ2h0OiAyNnB4OyBvdmVyZmxvdzogaGlkZGVuOyBjb2xvcjogIzAwMDAwMDsgIj48ZGl2IHN0eWxlPSJkaXNwbGF5OiBpbmxpbmUtYmxvY2s7IGZvbnQtc2l6ZTogMTJweDsgZm9udC1mYW1pbHk6IEhlbHZldGljYTsgY29sb3I6IGxpZ2h0LWRhcmsoIzAwMDAwMCwgI2ZmZmZmZik7IGxpbmUtaGVpZ2h0OiAxLjI7IHBvaW50ZXItZXZlbnRzOiBhbGw7IHdoaXRlLXNwYWNlOiBub3JtYWw7IHdvcmQtd3JhcDogbm9ybWFsOyAiPnNlcmlhbDo8L2Rpdj48L2Rpdj48L2Rpdj48L2ZvcmVpZ25PYmplY3Q+PHRleHQgeD0iMjY2IiB5PSI0MjkiIGZpbGw9ImxpZ2h0LWRhcmsoIzAwMDAwMCwgI2ZmZmZmZikiIGZvbnQtZmFtaWx5PSJIZWx2ZXRpY2EiIGZvbnQtc2l6ZT0iMTJweCI+c2VyaWFsOjwvdGV4dD48L3N3aXRjaD48L2c+PC9nPjwvZz48ZyBkYXRhLWNlbGwtaWQ9IjEzIj48Zz48cmVjdCB4PSIyNjAiIHk9IjQ0MCIgd2lkdGg9IjE0MCIgaGVpZ2h0PSIzMCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJub25lIiBwb2ludGVyLWV2ZW50cz0iYWxsIi8+PC9nPjxnPjxnPjxzd2l0Y2g+PGZvcmVpZ25PYmplY3Qgc3R5bGU9Im92ZXJmbG93OiB2aXNpYmxlOyB0ZXh0LWFsaWduOiBsZWZ0OyIgcG9pbnRlci1ldmVudHM9Im5vbmUiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHJlcXVpcmVkRmVhdHVyZXM9Imh0dHA6Ly93d3cudzMub3JnL1RSL1NWRzExL2ZlYXR1cmUjRXh0ZW5zaWJpbGl0eSI+PGRpdiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIgc3R5bGU9ImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiB1bnNhZmUgY2VudGVyOyBqdXN0aWZ5LWNvbnRlbnQ6IHVuc2FmZSBmbGV4LXN0YXJ0OyB3aWR0aDogMTMwcHg7IGhlaWdodDogMXB4OyBwYWRkaW5nLXRvcDogNDU1cHg7IG1hcmdpbi1sZWZ0OiAyNjZweDsiPjxkaXYgc3R5bGU9ImJveC1zaXppbmc6IGJvcmRlci1ib3g7IGZvbnQtc2l6ZTogMDsgdGV4dC1hbGlnbjogbGVmdDsgbWF4LWhlaWdodDogMjZweDsgb3ZlcmZsb3c6IGhpZGRlbjsgY29sb3I6ICMwMDAwMDA7ICI+PGRpdiBzdHlsZT0iZGlzcGxheTogaW5saW5lLWJsb2NrOyBmb250LXNpemU6IDEycHg7IGZvbnQtZmFtaWx5OiBIZWx2ZXRpY2E7IGNvbG9yOiBsaWdodC1kYXJrKCMwMDAwMDAsICNmZmZmZmYpOyBsaW5lLWhlaWdodDogMS4yOyBwb2ludGVyLWV2ZW50czogYWxsOyB3aGl0ZS1zcGFjZTogbm9ybWFsOyB3b3JkLXdyYXA6IG5vcm1hbDsgIj5ncHM6PC9kaXY+PC9kaXY+PC9kaXY+PC9mb3JlaWduT2JqZWN0Pjx0ZXh0IHg9IjI2NiIgeT0iNDU5IiBmaWxsPSJsaWdodC1kYXJrKCMwMDAwMDAsICNmZmZmZmYpIiBmb250LWZhbWlseT0iSGVsdmV0aWNhIiBmb250LXNpemU9IjEycHgiPmdwczo8L3RleHQ+PC9zd2l0Y2g+PC9nPjwvZz48L2c+PC9nPjxnIGRhdGEtY2VsbC1pZD0iMTQiPjxnPjxwYXRoIGQ9Ik0gMTMxLjY2IDE3Ni40MSBMIDEyNC44NyAxODQuNDMgTCAxMjAuMzggMTYwLjMyIEwgMTQ0LjkgMTYwLjc2IEwgMTM4LjEyIDE2OC43OCBMIDIzOC4zNCAyNTMuNTkgTCAyNDUuMTMgMjQ1LjU3IEwgMjQ5LjYyIDI2OS42OCBMIDIyNS4xIDI2OS4yNCBMIDIzMS44OCAyNjEuMjIgWiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwMDAwIiBzdHlsZT0ic3Ryb2tlOiBsaWdodC1kYXJrKHJnYigwLCAwLCAwKSwgcmdiKDI1NSwgMjU1LCAyNTUpKTsiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgcG9pbnRlci1ldmVudHM9ImFsbCIvPjwvZz48L2c+PGcgZGF0YS1jZWxsLWlkPSIxNSI+PGc+PHBhdGggZD0iTSA1My4xNSAxNzguNDEgTCA0NC45IDE4NC45MSBMIDQ1LjMxIDE2MC4zOSBMIDY5LjI1IDE2NS43MiBMIDYxIDE3Mi4yMiBMIDI0MS44NSA0MDEuNTkgTCAyNTAuMSAzOTUuMDkgTCAyNDkuNjkgNDE5LjYxIEwgMjI1Ljc1IDQxNC4yOCBMIDIzNCA0MDcuNzggWiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwMDAwIiBzdHlsZT0ic3Ryb2tlOiBsaWdodC1kYXJrKHJnYigwLCAwLCAwKSwgcmdiKDI1NSwgMjU1LCAyNTUpKTsiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgcG9pbnRlci1ldmVudHM9ImFsbCIvPjwvZz48L2c+PGcgZGF0YS1jZWxsLWlkPSIxNiI+PGc+PHBhdGggZD0iTSA0MjcuMzIgMjU5Ljc1IEwgNDM0Ljc1IDI2Ny4xNyBMIDQxMC4zNSAyNjkuNjUgTCA0MTIuODMgMjQ1LjI1IEwgNDIwLjI1IDI1Mi42OCBMIDUwMi42OCAxNzAuMjUgTCA0OTUuMjUgMTYyLjgzIEwgNTE5LjY1IDE2MC4zNSBMIDUxNy4xNyAxODQuNzUgTCA1MDkuNzUgMTc3LjMyIFoiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMDAwMCIgc3R5bGU9InN0cm9rZTogbGlnaHQtZGFyayhyZ2IoMCwgMCwgMCksIHJnYigyNTUsIDI1NSwgMjU1KSk7IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHBvaW50ZXItZXZlbnRzPSJhbGwiLz48L2c+PC9nPjxnIGRhdGEtY2VsbC1pZD0iMTciPjxnPjxwYXRoIGQ9Ik0gNDI0LjQ4IDQwNi4wMSBMIDQzMy40MiA0MTEuNTIgTCA0MTAuMjYgNDE5LjU3IEwgNDA3LjAyIDM5NS4yNyBMIDQxNS45NiA0MDAuNzcgTCA1NTUuNTIgMTczLjk5IEwgNTQ2LjU4IDE2OC40OCBMIDU2OS43NCAxNjAuNDMgTCA1NzIuOTggMTg0LjczIEwgNTY0LjA0IDE3OS4yMyBaIiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAwMDAiIHN0eWxlPSJzdHJva2U6IGxpZ2h0LWRhcmsocmdiKDAsIDAsIDApLCByZ2IoMjU1LCAyNTUsIDI1NSkpOyIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBwb2ludGVyLWV2ZW50cz0iYWxsIi8+PC9nPjwvZz48ZyBkYXRhLWNlbGwtaWQ9IjE5Ij48Zz48cmVjdCB4PSIzMDAiIHk9IjE4MCIgd2lkdGg9IjYwIiBoZWlnaHQ9IjMwIiBmaWxsPSJub25lIiBzdHJva2U9Im5vbmUiIHBvaW50ZXItZXZlbnRzPSJhbGwiLz48L2c+PGc+PGc+PHN3aXRjaD48Zm9yZWlnbk9iamVjdCBzdHlsZT0ib3ZlcmZsb3c6IHZpc2libGU7IHRleHQtYWxpZ246IGxlZnQ7IiBwb2ludGVyLWV2ZW50cz0ibm9uZSIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgcmVxdWlyZWRGZWF0dXJlcz0iaHR0cDovL3d3dy53My5vcmcvVFIvU1ZHMTEvZmVhdHVyZSNFeHRlbnNpYmlsaXR5Ij48ZGl2IHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiBzdHlsZT0iZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IHVuc2FmZSBjZW50ZXI7IGp1c3RpZnktY29udGVudDogdW5zYWZlIGNlbnRlcjsgd2lkdGg6IDU4cHg7IGhlaWdodDogMXB4OyBwYWRkaW5nLXRvcDogMTk1cHg7IG1hcmdpbi1sZWZ0OiAzMDFweDsiPjxkaXYgc3R5bGU9ImJveC1zaXppbmc6IGJvcmRlci1ib3g7IGZvbnQtc2l6ZTogMDsgdGV4dC1hbGlnbjogY2VudGVyOyBjb2xvcjogIzAwMDAwMDsgIj48ZGl2IHN0eWxlPSJkaXNwbGF5OiBpbmxpbmUtYmxvY2s7IGZvbnQtc2l6ZTogMTJweDsgZm9udC1mYW1pbHk6IEhlbHZldGljYTsgY29sb3I6IGxpZ2h0LWRhcmsoIzAwMDAwMCwgI2ZmZmZmZik7IGxpbmUtaGVpZ2h0OiAxLjI7IHBvaW50ZXItZXZlbnRzOiBhbGw7IGZvbnQtd2VpZ2h0OiBib2xkOyB3aGl0ZS1zcGFjZTogbm9ybWFsOyB3b3JkLXdyYXA6IG5vcm1hbDsgIj5GaWNoaWVyczwvZGl2PjwvZGl2PjwvZGl2PjwvZm9yZWlnbk9iamVjdD48dGV4dCB4PSIzMzAiIHk9IjE5OSIgZmlsbD0ibGlnaHQtZGFyaygjMDAwMDAwLCAjZmZmZmZmKSIgZm9udC1mYW1pbHk9IkhlbHZldGljYSIgZm9udC1zaXplPSIxMnB4IiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXdlaWdodD0iYm9sZCI+RmljaGllcnM8L3RleHQ+PC9zd2l0Y2g+PC9nPjwvZz48L2c+PC9nPjwvZz48L2c+PHN3aXRjaD48ZyByZXF1aXJlZEZlYXR1cmVzPSJodHRwOi8vd3d3LnczLm9yZy9UUi9TVkcxMS9mZWF0dXJlI0V4dGVuc2liaWxpdHkiLz48YSB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLC01KSIgeGxpbms6aHJlZj0iaHR0cHM6Ly93d3cuZHJhd2lvLmNvbS9kb2MvZmFxL3N2Zy1leHBvcnQtdGV4dC1wcm9ibGVtcyIgdGFyZ2V0PSJfYmxhbmsiPjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtc2l6ZT0iMTBweCIgeD0iNTAlIiB5PSIxMDAlIj5UZXh0IGlzIG5vdCBTVkcgLSBjYW5ub3QgZGlzcGxheTwvdGV4dD48L2E+PC9zd2l0Y2g+PC9zdmc+ ``` ### Prérequis - La partie IHM est concue autour d'une page Web, il faut en conséquence que le port 80 soit disponible sur la machine. ### Points d'Accès - 📊 **Ecran Principal** : http://localhost - ⚙️ **Barre des tâches** : 🧲 click droit ## 📁 Structure des Fichiers ### Format de Fichier Les fichiers CSV de magnétomètre ont la structure suivante : - **Valeurs séparées par point-virgule** (`;`) - **6 capteurs maximum** (Capteur 1-6) - **Colonnes de données par capteur** : - `Horodatage` - Horodatage Unix - `Bx (nT)` - Champ magnétique axe X (nanotesla) - `By (nT)` - Champ magnétique axe Y (nanotesla) - `Bz (nT)` - Champ magnétique axe Z (nanotesla) - `P (Bar)` - Pression (bar) - `Temperature` - Température (°C) - `Angle X/Y/Z` - Angles d'orientation ## ⚙️ Configuration ### Configuration des Capteurs L'édition des capteurs peut être réalisée directement dans l'interface web : ```yaml sensors: sensor_1: id: 1 name: "Accéléromètre Avant" description: "Capteur accéléromètre panneau avant" serial: "HEXAH-024545-001" enabled: true color: x: "#FF6384" # Couleur axe X y: "#36A2EB" # Couleur axe Y z: "#4BC0C0" # Couleur axe Z default_scale: x: 1.0 y: 1.0 z: 1.0 default_offset: x: 0.0 y: 0.0 z: 0.0 units: "g" location: "Panneau Avant" ``` ### Paramètres d'Affichage ```yaml display: max_sensors_displayed: 12 # Capteurs maximum à afficher (1-12) default_time_window: 30 # secondes default_update_rate: 100 # millisecondes (10 Hz) chart_height: 300 # pixels show_legend: true show_grid: true ``` # 📊 Guide d'Utilisation ### Tableau de Bord Principal #### Sources de Données 1. **Simulation de Capteurs** : Générateur de données intégré avec modes multiples - Réaliste : Simule des données réelles d'accéléromètre - Onde Sinusoïdale : Motifs d'ondes sinusoïdales mathématiques - Aléatoire : Données aléatoires dans des plages spécifiées - Zéro : Données plates pour tests ## 🎛️ Interface Utilisateur ### Tableau de Bord Principal - **Graphiques Temps Réel** : Visualisation de données de capteurs en direct avec contrôle de streaming automatique - **Panneau de Contrôle** : Démarrer/arrêter l'acquisition de données avec réponse instantanée - **Affichage d'État** : État du simulateur en temps réel, nombre d'échantillons et état d'acquisition - **Contrôles Modaux** : Interface propre avec dialogues modaux pour fonctionnalités avancées ### Composants Interface Modale #### 📡 Modale de Sélection de Capteurs - **Liste Dynamique de Capteurs** : Choisir quels capteurs afficher - **Configuration Temps Réel** : Les changements s'appliquent immédiatement aux graphiques - **Gestion des Capteurs** : Activer/désactiver les capteurs sans rechargement de page #### 📂 Modale d'Intégration de Fichiers - **Lancement d'Application Externe** : Démarrer des applications externes avec paramètres projet/campagne - **Navigateur de Fichiers Historiques** : Parcourir et charger les sessions de données précédentes - **Téléchargement de Fichier** : Importation manuelle de fichiers CSV pour analyse - **Contrôles de Lecture** : Lecture temps réel avec contrôle de vitesse (0.5x à 5x) #### ⚙️ Modale de Paramètres de Capteurs - **Contrôles Échelle/Décalage** : Ajustement de données temps réel par axe - **Configuration de Graphique** : Options d'affichage et fenêtres temporelles - **Exportation de Données** : Exportation CSV avec gestion de session ### Contrôle d'Acquisition - **Streaming de Graphiques Intelligent** : Les graphiques se mettent automatiquement en pause quand aucune acquisition - **Réponse Instantanée** : Démarrer/arrêter l'acquisition sans délais de redémarrage de processus - **Indicateurs d'État** : Retour visuel pour l'état d'acquisition et l'état du simulateur - **Suivi de Progression** : Nombres d'échantillons temps réel et informations de fichier de données ## 🔧 Gestion de Configuration ### Système de Configuration YAML Éditer la configuration à `/config.html` ou directement dans `config/config.yaml` : ```yaml sensors: sensor_1: id: 1 name: "Magnétomètre X" description: "Magnétomètre primaire axe X" serial: "HEXAH-024545-001" enabled: true color: x: "#FF6384" y: "#36A2EB" z: "#4BC0C0" units: "nT" location: "Position Avant" ``` ### Traitement des Données - **Conversion d'Horodatage** : Horodatages Unix convertis en objets Date JavaScript - **Données de Champ Magnétique** : Valeurs Bx, By, Bz en nanotesla (nT) → Visualisation graphique - **Données Environnementales** : Température en °C, Pression en Bar - **Données d'Angle** : Angles format IEEE 754 automatiquement convertis en degrés - **Taux Temps Réel** : Lecture de données à 10Hz (configurable) - **Mises à Jour Statiques** : Température et angles se rafraîchissent toutes les 5 secondes ### Fonctionnalités d'Intégration - **Mappage Automatique de Capteurs** : Capteurs de fichier (Capteur 1-6) → Capteurs d'application (sensor_1-6) - **Respect de Configuration** : Affiche seulement les capteurs activés - **Suivi de Progression** : Barre de progression visuelle avec capacité de navigation - **Contrôle de Vitesse** : Ajuster la lecture de 0.5x à 5x vitesse - **Gestion d'Erreurs** : Rapports d'erreurs complets et récupération ## � Système de Gestion d'État L'application utilise `config/status.yaml` pour la communication en temps réel entre les composants : ```yaml app: mode: development # Mode application : development|production test_trigger: false # Indicateur de déclenchement de test acquisition: type: stop # Opération courante : start|stop current_file: null # Nom du fichier de données actif mode: realistic # Mode simulation : realistic|sine|random|step|vibration project: test_project # Nom du projet de collecte de données campaign: demo_run # Nom de la campagne de collecte de données running: false # État d'acquisition sample_count: 0 # Nombre d'échantillons collectés simulator: commands: [] # File d'attente des commandes en attente ``` ### Modes d'Application - **`production`** : Mode d'opération standard - Contrôles de test cachés dans l'interface - Optimisé pour la collecte de données - Mode par défaut pour le déploiement - **`development`** : Mode de développement amélioré - Contrôles de test visibles dans le tableau de bord - Bouton "Exécuter Tests" activé - Lien "Résultats des Tests" accessible - Fonctionnalités de débogage améliorées ### Points de Terminaison API d'État **Obtenir l'État Actuel :** ```bash GET /api.php?action=get_status ``` **Définir le Mode d'Application :** ```bash POST /api.php Content-Type: application/json { "action": "send_simulator_command", "command": { "type": "set_mode", "mode": "development" } } ``` **Déclencher les Tests (Mode Développement) :** ```bash POST /api.php Content-Type: application/json { "action": "send_simulator_command", "command": { "type": "trigger_tests", "test_trigger": true } } ``` ## �🔧 Développement ### Développement Local (sans Docker) Pour le développement avec un serveur PHP local : ```bash # Démarrer serveur de développement PHP (recommandé) php -S localhost:8080 ``` **Note :** Pour la fonctionnalité complète incluant la sauvegarde de configuration, utilisez le setup Docker au lieu du serveur PHP local. ### Développement Docker Pour le développement avec changements de code en direct : ```bash # Utiliser montages de volumes pour développement cd setup/ docker-compose down docker-compose up -d # Surveiller les logs docker-compose logs -f ``` ### Permissions de Fichiers S'assurer que le répertoire config est accessible en écriture : ```bash chmod -R 755 config/ chown -R www-data:www-data config/ # Pour Apache ``` ### Vue d'Ensemble de l'Architecture #### Composants Frontend - **index.html** : Tableau de bord principal avec graphiques temps réel - **config.html** : Interface éditeur de configuration - **Modules CSS** : Style responsive avec design moderne - **Modules JavaScript** : Architecture modulaire ES6+ #### Modules JavaScript - **sensor-chart.js** : Intégration Chart.js avec données streaming - **data-logger.js** : Exportation CSV et gestion de données - **config-manager.js** : Chargement et gestion de configuration - **php-config-manager.js** : Persistance de configuration côté serveur - **magneto-file-reader.js** : Analyse de fichiers CSV et extraction de données - **magneto-file-integration.js** : Intégration UI pour lecteur de fichiers #### Composants Backend - **api.php** : API RESTful pour gestion de configuration - **Alpine Linux** : Image de base Docker légère - **Apache + PHP 8.2** : Serveur web avec support PHP moderne - **Persistance de Volumes** : Volumes Docker pour persistance de données ## 🚀 Déploiement de Production ### Déploiement Docker (Recommandé) 1. **Configurer Environnement** : ```bash git clone cd Mkii ``` 2. **Configurer Application** : ```bash # Éditer configuration si nécessaire nano config/config.yaml ``` 3. **Déployer** : ```bash cd setup/ ./setup.sh ``` 4. **Vérifier Déploiement** : ```bash ./status.sh curl http://localhost:8080 ``` ### Déploiement Manuel Pour déploiement manuel sur stack LAMP existante : 1. **Copier Fichiers** : ```bash cp -r * /var/www/html/ ``` 2. **Définir Permissions** : ```bash chown -R www-data:www-data /var/www/html/config/ chmod -R 755 /var/www/html/config/ ``` 3. **Configurer Apache** : ```apache AllowOverride All Require all granted ``` ## 🛠️ Dépannage / Problèmes Courants #### Configuration Non Sauvegardée ```bash # Vérifier permissions fichiers ls -la config/ # Devrait montrer : drwxr-xr-x www-data www-data # Corriger permissions sudo chown -R www-data:www-data config/ sudo chmod -R 755 config/ ``` #### Graphiques Non Affichés 1. Vérifier console navigateur pour erreurs JavaScript 2. Vérifier que les bibliothèques Chart.js se chargent 3. S'assurer que la configuration des capteurs est valide 4. Vérifier que la source de données est active #### Lecteur de Fichiers Non Fonctionnel 1. Vérifier que le format de fichier CSV correspond à la structure attendue 2. Vérifier console navigateur pour erreurs d'analyse 3. S'assurer que le fichier contient les en-têtes requis : "Horodatage", "Bx (nT)", etc. 4. Essayer avec fichier de données exemple du répertoire `/data/` #### Problèmes Docker ```bash # Vérifier état conteneur cd setup/ ./status.sh # Voir logs ./logs.sh # Redémarrer conteneurs ./restart.sh # Reconstruire si nécessaire ./rebuild.sh ``` ## Optimisation des Performances #### Données Haute Fréquence - Ajuster `max_buffer_size` dans la configuration - Réduire le taux de mise à jour graphique si nécessaire - Utiliser la décimation de données pour longs enregistrements #### Performance Navigateur - Vider cache navigateur si les graphiques deviennent lents - Fermer onglets navigateur inutilisés - Utiliser navigateur moderne avec accélération matérielle #### Performance Docker ```bash # Surveiller utilisation ressources docker stats # Ajuster limites mémoire dans docker-compose.yml si nécessaire services: sensor-viz-app: mem_limit: 512m ``` ## 📝 Référence API ### API de Configuration #### GET /api.php?action=read Obtenir configuration actuelle ```json { "success": true, "config": { /* Config YAML en JSON */ } } ``` #### POST /api.php Sauvegarder configuration ```json { "action": "write", "config": { /* Nouvelle configuration */ } } ``` #### GET /api.php?action=backup Créer sauvegarde configuration ```json { "success": true, "backup_file": "config_backup_2025-07-28_14-30-15.yaml" } ``` ### Format d'Exportation de Données L'exportation CSV inclut : ```csv timestamp,sensor_id,x_raw,y_raw,z_raw,x_processed,y_processed,z_processed 2025-07-28T14:30:15.123Z,1,0.123,0.456,0.789,0.123,0.456,0.789 ``` ## 🔍 Surveillance ### Logs d'Application ```bash # Logs Docker cd setup/ ./logs.sh # Logs Apache (si déploiement manuel) tail -f /var/log/apache2/error.log tail -f /var/log/apache2/access.log ``` ### Métriques de Performance - **Taux de Données** : Affiché dans barre d'état tableau de bord - **Utilisation Mémoire** : Surveiller via outils dev navigateur - **Trafic Réseau** : Vérifier onglet réseau navigateur - **Ressources Serveur** : Utiliser `htop` ou stats Docker ## 🤝 Contribution ### Style de Code - Utiliser fonctionnalités JavaScript ES6+ - Suivre indentation cohérente (4 espaces) - Ajouter commentaires JSDoc pour fonctions - Utiliser HTML et CSS sémantiques ### Tests - Tester avec fichiers de données magnétomètre exemple - Vérifier persistance configuration - Vérifier design responsive sur appareils mobiles - Valider fonctionnalité exportation CSV ### Pull Requests 1. Fork le dépôt 2. Créer branche fonctionnalité 3. Ajouter tests pour nouvelle fonctionnalité 4. Mettre à jour documentation 5. Soumettre pull request avec description claire ## 🐳 Commandes Docker Toutes les commandes Docker doivent être exécutées depuis le répertoire `setup/` : ```bash # Naviguer vers répertoire setup cd setup/ # Démarrer application docker-compose up -d # Voir logs docker-compose logs -f # Arrêter application docker-compose down # Redémarrer services docker-compose restart # Reconstruire conteneurs docker-compose build --no-cache # Accéder shell conteneur docker-compose exec sensor-viz bash ``` ### Scripts de Gestion Le répertoire setup inclut des scripts de gestion pratiques : ```bash cd setup/ # Configuration initiale ./setup.sh # Vérifier état ./status.sh # Voir logs ./logs.sh # Redémarrer application ./restart.sh # Arrêter application ./stop.sh # Reconstruire application ./rebuild.sh ``` ## 🔒 Considérations de Sécurité ### Protection des Données - Fichiers de configuration protégés de l'accès web direct via règles Apache - En-têtes CORS correctement configurés pour points de terminaison API - Système de sauvegarde automatique empêche perte de configuration - Validation d'entrée sur tous changements de configuration - Aucune donnée sensible stockée dans localStorage navigateur ### Sécurité Téléchargement de Fichiers - Validation fichiers CSV avant traitement - Limites de taille de fichier appliquées - Pas de stockage côté serveur pour données téléchargées - Analyse côté client empêche vulnérabilités serveur ## 📈 Caractéristiques de Performance ### Performance Temps Réel - Optimisé pour mises à jour de données soutenues à 10Hz - Streaming Chart.js efficace avec mise en mémoire tampon circulaire - Décimation automatique de données pour sessions longue durée - Structures de données efficaces en mémoire ### Compatibilité Navigateur - Navigateurs modernes avec support ES6+ requis - Rendu Canvas accéléré matériellement - Support WebWorker pour traitement arrière-plan - Design responsive pour appareils mobiles ### Utilisation Ressources - Utilisation mémoire typique : 50-100MB - Utilisation CPU : <10% sur matériel moderne - Bande passante réseau : Minimale (mises à jour config seulement) - Stockage : Rétention données configurable ## 🏗️ Spécifications Techniques ### Technologies Frontend - **HTML5** : Balisage sémantique avec fonctionnalités accessibilité - **CSS3** : Mise en page Grid/Flexbox avec variables CSS - **JavaScript ES6+** : Motifs async/await modernes - **Chart.js 4.x** : Graphiques accélérés matériellement - **Plugin Streaming** : Visualisation données temps réel ### Technologies Backend - **PHP 8.2** : PHP moderne avec typage fort - **Apache 2.4** : Serveur web prêt production - **Alpine Linux** : Empreinte conteneur minimale - **Docker Compose** : Orchestration multi-conteneurs ### Formats de Données - **YAML** : Configuration lisible humainement - **CSV** : Exportation données standard industrie - **JSON** : Communication API - **IEEE 754** : Représentation angles virgule flottante ## 📋 Exigences ### Exigences Système Minimales - **CPU** : Processeur dual-core 1 GHz - **RAM** : 2GB mémoire disponible - **Stockage** : 1GB espace disque libre - **Réseau** : 100 Mbps pour mises à jour temps réel ### Exigences Navigateur - **Chrome/Chromium** : 80+ - **Firefox** : 75+ - **Safari** : 13+ - **Edge** : 80+ ### Exigences Docker - **Docker** : 20.10+ - **Docker Compose** : 2.0+ - **Ports Disponibles** : 8080 - **Volumes** : Accès système fichiers hôte ## 🎯 Cas d'Usage ### Applications de Recherche - **Études Magnétomètre** : Visualisation champ magnétique temps réel - **Analyse Accéléromètre** : Surveillance mouvement et vibration - **Surveillance Environnementale** : Suivi température et orientation - **Validation Données** : Comparaison en direct de capteurs multiples ### Applications Industrielles - **Contrôle Qualité** : Validation capteurs temps réel - **Surveillance Équipement** : Analyse vibration continue - **Calibration** : Vérification décalage et échelle capteurs - **Journalisation Données** : Enregistrement mesures automatisé ### Usage Éducatif - **Démonstrations Physique** : Visualisation données capteurs en direct - **Formation Ingénierie** : Analyse données monde réel - **Exemples Programmation** : Motifs développement web modernes - **Science des Données** : Workflows importation et analyse CSV ## 📄 Licence Ce projet est open source et disponible pour usage éducatif et commercial. ## 🙏 Remerciements ### Bibliothèques Tierces - **Chart.js** : Bibliothèque graphiques puissante avec support streaming - **js-yaml** : Analyseur YAML JavaScript pour fichiers configuration - **Alpine Linux** : Image de base Docker légère - **Serveur HTTP Apache** : Plateforme serveur web fiable ### Support Format de Données - **CSV Magnétomètre** : Support pour fichiers données magnétomètre externes - **IEEE 754** : Gestion appropriée données angles virgule flottante - **CSV Point-virgule** : Compatibilité format CSV européen ## 🤝 Contribution Les contributions sont bienvenues ! Veuillez vous concentrer sur : - Améliorations performance pour données haute fréquence - Nouveaux modes simulation et motifs de données - Support mobile amélioré et design responsive - Formats exportation données additionnels et outils analyse - Exemples intégration matériel capteurs réels - Support étendu format données magnétomètre ### Mises à Jour Majeures Récentes #### V2.0 - Architecture Simulateur Continu - **Simulateur Toujours Actif** : Processus arrière-plan élimine délais démarrage - **Contrôle Acquisition Instantané** : Démarrer/arrêter acquisition données sans surcharge processus - **Streaming Graphiques Intelligent** : Pause/reprise automatique basée sur état acquisition - **Contrôle Basé Commandes** : Contrôle professionnel via communication fichier état #### V1.5 - Interface Utilisateur/UX Professionnelle - **Interface Modale** : Interface propre et organisée avec dialogues modaux - **État Temps Réel** : Surveillance simulateur en direct et affichage nombre échantillons - **Graphiques Conscients Acquisition** : Graphiques se mettent intelligemment en pause quand pas d'acquisition - **Gestion Fichiers Améliorée** : Navigateur fichiers données complet et contrôles #### V1.0 - Fonctionnalités Core - **Lecteur Fichiers Magnétomètre** : Système importation CSV complet pour données externes - **Configuration Capteurs Dynamique** : Jusqu'à 12 capteurs avec configuration en direct - **Déploiement Docker** : Conteneurs basés Alpine avec persistance volumes - **Configuration Web** : Éditeur YAML avec système sauvegarde automatique --- ## 📞 Support & Documentation ### Liens Rapides - **Application Principale** : http://localhost:8080 - **Éditeur Configuration** : http://localhost:8080/config.html - **Documentation API** : API REST intégrée pour automatisation - **Logs Conteneur** : `cd setup && ./logs.sh` ### Problèmes Courants - **Port 8080 utilisé** : Changer port dans `setup/docker-compose.yml` - **Problèmes permissions** : S'assurer volumes Docker ont permissions correctes - **Simulateur ne répond pas** : Vérifier `config/status.yaml` pour communication - **Fichiers CSV ne se chargent pas** : Vérifier format fichier correspond structure attendue ### Conseils Performance - **Données haute fréquence** : Utiliser déploiement Docker pour meilleure performance - **Gros fichiers** : Considérer chunking fichiers pour très gros ensembles données - **Capteurs multiples** : Limiter capteurs actifs pour performance graphiques optimale - **Acquisition arrière-plan** : Simulateur continue même quand navigateur fermé --- **Construit avec** : Chart.js, JavaScript Vanilla, CSS3, HTML5, PHP 8.2, Apache, Alpine Linux, Docker **🛰️ Visualisation de Données de Capteurs en Temps Réel - Système d'Acquisition Continue Professionnel !**