From f36dd96e2d8eb2a40b7d52ce7551c4d23d8f8bf1 Mon Sep 17 00:00:00 2001
From: Hugo SUBTIL <ext.sopra.husubtil@grandlyon.com>
Date: Fri, 2 Oct 2020 15:44:07 +0200
Subject: [PATCH 01/10] feat(map): add map with Leaflet

---
 .gitignore                                |   3 ++
 angular.json                              |  12 ++++-
 package-lock.json                         |  25 ++++++++++
 package.json                              |   3 ++
 src/app/app.module.ts                     |   3 +-
 src/app/home/home.component.html          |   2 +-
 src/app/home/home.component.ts            |   9 ++--
 src/app/map/components/index.ts           |   6 +++
 src/app/map/components/map.component.html |   1 +
 src/app/map/components/map.component.scss |   3 ++
 src/app/map/components/map.component.ts   |  56 ++++++++++++++++++++++
 src/app/map/map.module.ts                 |  12 +++++
 src/app/map/models/map-options.ts         |   0
 src/app/map/services/map.service.spec.ts  |  16 +++++++
 src/app/map/services/map.service.ts       |   8 ++++
 src/assets/img/ic_marker.png              | Bin 0 -> 652 bytes
 src/index.html                            |  24 +++++-----
 src/main.ts                               |   5 +-
 18 files changed, 165 insertions(+), 23 deletions(-)
 create mode 100644 src/app/map/components/index.ts
 create mode 100644 src/app/map/components/map.component.html
 create mode 100644 src/app/map/components/map.component.scss
 create mode 100644 src/app/map/components/map.component.ts
 create mode 100644 src/app/map/map.module.ts
 create mode 100644 src/app/map/models/map-options.ts
 create mode 100644 src/app/map/services/map.service.spec.ts
 create mode 100644 src/app/map/services/map.service.ts
 create mode 100644 src/assets/img/ic_marker.png

diff --git a/.gitignore b/.gitignore
index 86d943a9b..dd7eaed51 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,3 +44,6 @@ testem.log
 # System Files
 .DS_Store
 Thumbs.db
+
+#config
+.env
diff --git a/angular.json b/angular.json
index 79beada28..ed8667999 100644
--- a/angular.json
+++ b/angular.json
@@ -30,8 +30,16 @@
             "tsConfig": "tsconfig.app.json",
             "localize": true,
             "aot": true,
-            "assets": ["src/favicon.ico", "src/assets"],
-            "styles": ["src/styles.scss"],
+            "assets": [
+              "src/favicon.ico",
+              "src/assets",
+              {
+                "glob": "**/*",
+                "input": "./node_modules/leaflet/dist/images",
+                "output": "assets/"
+              }
+            ],
+            "styles": ["src/styles.scss", "./node_modules/leaflet/dist/leaflet.css"],
             "scripts": []
           },
           "configurations": {
diff --git a/package-lock.json b/package-lock.json
index 3cc3d6852..50b7ced9f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -773,6 +773,11 @@
         "tslib": "^2.0.0"
       }
     },
+    "@asymmetrik/ngx-leaflet": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/@asymmetrik/ngx-leaflet/-/ngx-leaflet-8.1.0.tgz",
+      "integrity": "sha512-lq7LduBP/vXcaSEmKnx7mzCR8WsoYqh9pB6BNnq53yeCwsqRbG3GdKye1/i8VvoRzjDsmQBPQsIFZ9uclXrtgg=="
+    },
     "@babel/code-frame": {
       "version": "7.10.4",
       "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
@@ -1973,6 +1978,12 @@
       "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
       "dev": true
     },
+    "@types/geojson": {
+      "version": "7946.0.7",
+      "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.7.tgz",
+      "integrity": "sha512-wE2v81i4C4Ol09RtsWFAqg3BUitWbHSpSlIo+bNdsCJijO9sjme+zm+73ZMCa/qMC8UEERxzGbvmr1cffo2SiQ==",
+      "dev": true
+    },
     "@types/glob": {
       "version": "7.1.3",
       "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz",
@@ -2004,6 +2015,15 @@
       "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==",
       "dev": true
     },
+    "@types/leaflet": {
+      "version": "1.5.17",
+      "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.5.17.tgz",
+      "integrity": "sha512-2XYq9k6kNjhNI7PaTz8Rdxcc8Vzwu97OaS9CtcrTxnTSxFUGwjlGjTDvhTLJU+JRSfZ4lBwGcl0SjZHALdVr6g==",
+      "dev": true,
+      "requires": {
+        "@types/geojson": "*"
+      }
+    },
     "@types/minimatch": {
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
@@ -8058,6 +8078,11 @@
       "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==",
       "dev": true
     },
+    "leaflet": {
+      "version": "1.7.1",
+      "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.7.1.tgz",
+      "integrity": "sha512-/xwPEBidtg69Q3HlqPdU3DnrXQOvQU/CCHA1tcDQVzOwm91YMYaILjNp7L4Eaw5Z4sOYdbBz6koWyibppd8Zqw=="
+    },
     "less": {
       "version": "3.12.2",
       "resolved": "https://registry.npmjs.org/less/-/less-3.12.2.tgz",
diff --git a/package.json b/package.json
index 5a8956c0f..90b8efc60 100644
--- a/package.json
+++ b/package.json
@@ -24,6 +24,8 @@
     "@angular/platform-browser": "~10.1.3",
     "@angular/platform-browser-dynamic": "~10.1.3",
     "@angular/router": "~10.1.3",
+    "@asymmetrik/ngx-leaflet": "^8.1.0",
+    "leaflet": "^1.7.1",
     "rxjs": "~6.6.0",
     "tslib": "^2.0.0",
     "zone.js": "~0.10.2"
@@ -35,6 +37,7 @@
     "@angular/localize": "^10.1.3",
     "@types/jasmine": "~3.5.0",
     "@types/jasminewd2": "~2.0.3",
+    "@types/leaflet": "^1.5.17",
     "@types/node": "^12.12.62",
     "codelyzer": "^6.0.0",
     "jasmine-core": "~3.6.0",
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 4ad3e8861..00278763f 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -11,10 +11,11 @@ import { StructureListComponent } from './structure-list/structure-list.componen
 import { FooterComponent } from './footer/footer.component';
 import { HeaderComponent } from './header/header.component';
 import { SharedModule } from './shared/shared.module';
+import { MapModule } from './map/map.module';
 
 @NgModule({
   declarations: [AppComponent, HeaderComponent, FooterComponent, HomeComponent, StructureListComponent],
-  imports: [BrowserModule, AppRoutingModule, FlexLayoutModule, SharedModule],
+  imports: [BrowserModule, AppRoutingModule, FlexLayoutModule, SharedModule, MapModule],
   providers: [{ provide: LOCALE_ID, useValue: 'fr' }, CustomBreakPointsProvider],
   bootstrap: [AppComponent],
 })
diff --git a/src/app/home/home.component.html b/src/app/home/home.component.html
index 4f2ba48bc..56147e48a 100644
--- a/src/app/home/home.component.html
+++ b/src/app/home/home.component.html
@@ -1,5 +1,5 @@
 <div class="content-container">
   <div class="section-container">
-    <p>Home works!</p>
+    <app-map></app-map>
   </div>
 </div>
diff --git a/src/app/home/home.component.ts b/src/app/home/home.component.ts
index 73acf06f0..98af51905 100644
--- a/src/app/home/home.component.ts
+++ b/src/app/home/home.component.ts
@@ -3,13 +3,10 @@ import { Component, OnInit } from '@angular/core';
 @Component({
   selector: 'app-home',
   templateUrl: './home.component.html',
-  styleUrls: ['./home.component.scss']
+  styleUrls: ['./home.component.scss'],
 })
 export class HomeComponent implements OnInit {
+  constructor() {}
 
-  constructor() { }
-
-  ngOnInit(): void {
-  }
-
+  ngOnInit(): void {}
 }
diff --git a/src/app/map/components/index.ts b/src/app/map/components/index.ts
new file mode 100644
index 000000000..45941a73c
--- /dev/null
+++ b/src/app/map/components/index.ts
@@ -0,0 +1,6 @@
+import { MapComponent } from './map.component';
+
+export { MapComponent };
+
+// tslint:disable-next-line:variable-name
+export const MapComponents = [MapComponent];
diff --git a/src/app/map/components/map.component.html b/src/app/map/components/map.component.html
new file mode 100644
index 000000000..de076413c
--- /dev/null
+++ b/src/app/map/components/map.component.html
@@ -0,0 +1 @@
+<div id="map" leaflet [leafletOptions]="mapOptions" (leafletMapReady)="onMapReady($event)"></div>
diff --git a/src/app/map/components/map.component.scss b/src/app/map/components/map.component.scss
new file mode 100644
index 000000000..4bbcec030
--- /dev/null
+++ b/src/app/map/components/map.component.scss
@@ -0,0 +1,3 @@
+#map {
+  height: 600px;
+}
diff --git a/src/app/map/components/map.component.ts b/src/app/map/components/map.component.ts
new file mode 100644
index 000000000..704918cd7
--- /dev/null
+++ b/src/app/map/components/map.component.ts
@@ -0,0 +1,56 @@
+import { Component, OnInit } from '@angular/core';
+import { latLng, MapOptions, tileLayer, Map, Marker, icon } from 'leaflet';
+
+declare var ol: any;
+@Component({
+  selector: 'app-map',
+  templateUrl: './map.component.html',
+  styleUrls: ['./map.component.scss'],
+})
+export class MapComponent implements OnInit {
+  public map: Map;
+  public mapOptions: MapOptions;
+
+  constructor() {}
+
+  ngOnInit(): void {
+    this.initializeMapOptions();
+  }
+
+  public onMapReady(map: Map): void {
+    this.map = map;
+    this.addSampleMarker();
+  }
+
+  private initializeMapOptions(): void {
+    this.mapOptions = {
+      center: latLng(45.764043, 4.835659),
+      zoom: 12,
+      layers: [
+        tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
+          maxZoom: 18,
+          attribution: 'Map data © OpenStreetMap contributors',
+        }),
+      ],
+    };
+  }
+
+  private addSampleMarker(): void {
+    const marker = new Marker([45.764043, 4.835659]).setIcon(
+      icon({
+        iconSize: [25, 41],
+        iconAnchor: [13, 41],
+        iconUrl: '../../../assets/img/ic_marker.png',
+      })
+    );
+    marker.addTo(this.map);
+    const marker2 = new Marker([45.764043, 4.935659]).setIcon(
+      icon({
+        iconSize: [25, 41],
+        iconAnchor: [13, 41],
+        iconUrl: '../../../assets/img/ic_marker.png',
+      })
+    );
+    marker2.addTo(this.map);
+  }
+}
diff --git a/src/app/map/map.module.ts b/src/app/map/map.module.ts
new file mode 100644
index 000000000..d52d49db8
--- /dev/null
+++ b/src/app/map/map.module.ts
@@ -0,0 +1,12 @@
+import { NgModule } from '@angular/core';
+import { CommonModule, DatePipe } from '@angular/common';
+import { SharedModule } from '../shared/shared.module';
+import { MapComponents } from './components';
+import { LeafletModule } from '@asymmetrik/ngx-leaflet';
+@NgModule({
+  imports: [CommonModule, SharedModule, LeafletModule],
+  declarations: [MapComponents],
+  providers: [DatePipe],
+  exports: [MapComponents],
+})
+export class MapModule {}
diff --git a/src/app/map/models/map-options.ts b/src/app/map/models/map-options.ts
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/app/map/services/map.service.spec.ts b/src/app/map/services/map.service.spec.ts
new file mode 100644
index 000000000..9a1a1ec53
--- /dev/null
+++ b/src/app/map/services/map.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { MapService } from './map.service';
+
+describe('MapService', () => {
+  let service: MapService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(MapService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
diff --git a/src/app/map/services/map.service.ts b/src/app/map/services/map.service.ts
new file mode 100644
index 000000000..81ce8c87d
--- /dev/null
+++ b/src/app/map/services/map.service.ts
@@ -0,0 +1,8 @@
+import { Injectable } from '@angular/core';
+
+@Injectable({
+  providedIn: 'root',
+})
+export class MapService {
+  constructor() {}
+}
diff --git a/src/assets/img/ic_marker.png b/src/assets/img/ic_marker.png
new file mode 100644
index 0000000000000000000000000000000000000000..0cee292f0cfac7648bf62b1d257936ffb4986ffc
GIT binary patch
literal 652
zcmV;70(1R|P)<h;3K|Lk000e1NJLTq000*N000{Z1^@s6m*^DR00009a7bBm000XU
z000XU0RWnu7ytkO0drDELIAGL9O(c600d`2O+f$vv5yP<VFdsH0wGC6K~#7FtybM}
z+CUKg_D-7di}|S_qyy4HsK8DIHWgSH{2X|W9E%FT6(k)HS74Vw2Lkfo43ciMCl7>R
zoeYL=26VT}etX>QekVc+e)qi30G%1aIWgB{T(fp2Jdu$P@%?F-{&K~Wi<F5*U^MU+
z2vcMjRK6$U*REH@{v87W_Jj~cr(x3BvTYFG_>atJ;+?SDRsEKHTFup(*sk~hVhfUZ
z%d?)_uf?^0DQQMH5;AbBE(iUxa*eMzBD5_Afy&FRq$-$s#^6Dg>W`H$A^Ws*iJ3Xs
zg)bIfT6F!9Y|f>N*kshIN6FK+FAn^s)|g0atuU4_RMH6ULnJjUBDS!0CLTINfiuM*
zC%H-07$q>N=k_ydsw}u3{h1!%FDHNQo_r|t$3dw)%v7!o4lK#EOM>Bf-i6C25;9e6
z@ZkCZfv@5lzwk_C)y+~3B0P|-M-7_5jTwQWG+o};BTS!zlSb;93x)|+5?ln^4|)5~
zd;X&g4$_tXz!+C<lXiZf2He4sAmTU8GCi>4oZN~`-qJ^aY++|rqU%zuhG}2geTV}f
z4LPXXE`R<@w1s)si-_n7?;x&*%l@XV@D82#yuSRson=@`vQrI{XxmP%fSnT<w2Ln1
zQt~{(wI7heU6C)BW5SpEzONRWh`ah+Lyb0d+m@TjgxDd+JCo-L<YG`7KZwwHA=a(8
m6mu`c()Np<H?hxMWBvl_|L2g$_n@Ev0000<MNUMnLSTY4ZYd)G

literal 0
HcmV?d00001

diff --git a/src/index.html b/src/index.html
index 761c288f2..3469415cc 100644
--- a/src/index.html
+++ b/src/index.html
@@ -1,13 +1,15 @@
-<!doctype html>
+<!DOCTYPE html>
 <html lang="en">
-<head>
-  <meta charset="utf-8">
-  <title>Pamn</title>
-  <base href="/">
-  <meta name="viewport" content="width=device-width, initial-scale=1">
-  <link rel="icon" type="image/x-icon" href="favicon.ico">
-</head>
-<body>
-  <app-root></app-root>
-</body>
+  <head>
+    <meta charset="utf-8" />
+    <title>Pamn</title>
+    <base href="/" />
+    <meta name="viewport" content="width=device-width, initial-scale=1" />
+    <link rel="icon" type="image/x-icon" href="favicon.ico" />
+    <link rel="stylesheet" href="https://openlayers.org/en/v4.6.5/css/ol.css" type="text/css" />
+    <script src="https://openlayers.org/en/v4.6.5/build/ol.js" type="text/javascript"></script>
+  </head>
+  <body>
+    <app-root></app-root>
+  </body>
 </html>
diff --git a/src/main.ts b/src/main.ts
index c7b673cf4..d9a2e7e4a 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -8,5 +8,6 @@ if (environment.production) {
   enableProdMode();
 }
 
-platformBrowserDynamic().bootstrapModule(AppModule)
-  .catch(err => console.error(err));
+platformBrowserDynamic()
+  .bootstrapModule(AppModule)
+  .catch((err) => console.error(err));
-- 
GitLab


From 0daaf7c37063231735ac9896244c146f9aeebad6 Mon Sep 17 00:00:00 2001
From: Hugo SUBTIL <ext.sopra.husubtil@grandlyon.com>
Date: Fri, 9 Oct 2020 15:23:04 +0200
Subject: [PATCH 02/10] feat(carto): first working verison of leafleat carto
 with wms from data.grandlyon

---
 angular.json                              |   6 +-
 package-lock.json                         |  77 ++++++++++++++++++--
 package.json                              |   5 +-
 src/app/map/components/map.component.html |  13 +++-
 src/app/map/components/map.component.scss |  28 ++++++++
 src/app/map/components/map.component.ts   |  82 +++++++++++++++++++---
 src/app/map/map.module.ts                 |   3 +-
 src/assets/img/ic_marker.png              | Bin 652 -> 1274 bytes
 src/index.html                            |   4 ++
 src/styles.scss                           |   1 +
 tsconfig.app.json                         |   2 +
 tsconfig.spec.json                        |  14 +---
 12 files changed, 204 insertions(+), 31 deletions(-)

diff --git a/angular.json b/angular.json
index ed8667999..9bc732dd2 100644
--- a/angular.json
+++ b/angular.json
@@ -39,7 +39,11 @@
                 "output": "assets/"
               }
             ],
-            "styles": ["src/styles.scss", "./node_modules/leaflet/dist/leaflet.css"],
+            "styles": [
+              "src/styles.scss",
+              "./node_modules/leaflet/dist/leaflet.css",
+              "./node_modules/leaflet.locatecontrol/dist/L.Control.Locate.css"
+            ],
             "scripts": []
           },
           "configurations": {
diff --git a/package-lock.json b/package-lock.json
index 50b7ced9f..5441d3080 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1945,6 +1945,28 @@
         }
       }
     },
+    "@runette/ngx-leaflet-locate": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/@runette/ngx-leaflet-locate/-/ngx-leaflet-locate-1.0.3.tgz",
+      "integrity": "sha512-U792/VO5PvQKok7H4CHJ+u3L7Vy3Pca3Iki32CXVqloVzUOO0VcNMcF07NoLcXkUHEXX7hJ5I7OGivTyMFcYpQ==",
+      "requires": {
+        "@types/leaflet.locatecontrol": "^0.60.7",
+        "leaflet.locatecontrol": "^0.68.0",
+        "tslib": "^1.9.0"
+      },
+      "dependencies": {
+        "leaflet.locatecontrol": {
+          "version": "0.68.0",
+          "resolved": "https://registry.npmjs.org/leaflet.locatecontrol/-/leaflet.locatecontrol-0.68.0.tgz",
+          "integrity": "sha512-jXJCpBvkyH6shjPEOK/DWu/tKX/WdkNeO96jyPrnGelYp9u6wSDj4V1V4aX9+CMTIrEyVB4/4XuU+T7VTRpb6w=="
+        },
+        "tslib": {
+          "version": "1.14.0",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.0.tgz",
+          "integrity": "sha512-+Zw5lu0D9tvBMjGP8LpvMb0u2WW2QV3y+D8mO6J+cNzCYIN4sVy43Bf9vl92nqFahutN0I8zHa7cc4vihIshnw=="
+        }
+      }
+    },
     "@schematics/angular": {
       "version": "10.1.3",
       "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-10.1.3.tgz",
@@ -1981,8 +2003,7 @@
     "@types/geojson": {
       "version": "7946.0.7",
       "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.7.tgz",
-      "integrity": "sha512-wE2v81i4C4Ol09RtsWFAqg3BUitWbHSpSlIo+bNdsCJijO9sjme+zm+73ZMCa/qMC8UEERxzGbvmr1cffo2SiQ==",
-      "dev": true
+      "integrity": "sha512-wE2v81i4C4Ol09RtsWFAqg3BUitWbHSpSlIo+bNdsCJijO9sjme+zm+73ZMCa/qMC8UEERxzGbvmr1cffo2SiQ=="
     },
     "@types/glob": {
       "version": "7.1.3",
@@ -2019,11 +2040,18 @@
       "version": "1.5.17",
       "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.5.17.tgz",
       "integrity": "sha512-2XYq9k6kNjhNI7PaTz8Rdxcc8Vzwu97OaS9CtcrTxnTSxFUGwjlGjTDvhTLJU+JRSfZ4lBwGcl0SjZHALdVr6g==",
-      "dev": true,
       "requires": {
         "@types/geojson": "*"
       }
     },
+    "@types/leaflet.locatecontrol": {
+      "version": "0.60.7",
+      "resolved": "https://registry.npmjs.org/@types/leaflet.locatecontrol/-/leaflet.locatecontrol-0.60.7.tgz",
+      "integrity": "sha512-sac/MeK4gB+3XTJ3JzCe3HqLwKNHblIpZrxUJ6FapWK8uISZ0wcy8motVO7+v/yO47tQgsnYaobwFZ//beWHBQ==",
+      "requires": {
+        "@types/leaflet": "*"
+      }
+    },
     "@types/minimatch": {
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
@@ -2037,9 +2065,9 @@
       "dev": true
     },
     "@types/node": {
-      "version": "12.12.62",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.62.tgz",
-      "integrity": "sha512-qAfo81CsD7yQIM9mVyh6B/U47li5g7cfpVQEDMfQeF8pSZVwzbhwU3crc0qG4DmpsebpJPR49AKOExQyJ05Cpg==",
+      "version": "12.12.67",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.67.tgz",
+      "integrity": "sha512-R48tgL2izApf+9rYNH+3RBMbRpPeW3N8f0I9HMhggeq4UXwBDqumJ14SDs4ctTMhG11pIOduZ4z3QWGOiMc9Vg==",
       "dev": true
     },
     "@types/normalize-package-data": {
@@ -6568,6 +6596,12 @@
         "minimalistic-assert": "^1.0.1"
       }
     },
+    "hat": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/hat/-/hat-0.0.3.tgz",
+      "integrity": "sha1-uwFKnmSzeIrtgAWRdBPU/z1QLYo=",
+      "dev": true
+    },
     "hex-color-regex": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
@@ -7687,6 +7721,12 @@
         }
       }
     },
+    "js-string-escape": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz",
+      "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=",
+      "dev": true
+    },
     "js-tokens": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -8014,6 +8054,20 @@
         }
       }
     },
+    "karma-browserify": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/karma-browserify/-/karma-browserify-7.0.0.tgz",
+      "integrity": "sha512-SLgh1dmF2eZEj3glrmTD2CMJRGZwEiKA6k2hBr2+2JDC4JMU1dlsvBKpV66Lvi/tbj3H9qA+Vl/FdIcfPRrJpA==",
+      "dev": true,
+      "requires": {
+        "convert-source-map": "^1.1.3",
+        "hat": "^0.0.3",
+        "js-string-escape": "^1.0.0",
+        "lodash": "^4.17.14",
+        "minimatch": "^3.0.0",
+        "os-shim": "^0.1.3"
+      }
+    },
     "karma-chrome-launcher": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz",
@@ -8083,6 +8137,11 @@
       "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.7.1.tgz",
       "integrity": "sha512-/xwPEBidtg69Q3HlqPdU3DnrXQOvQU/CCHA1tcDQVzOwm91YMYaILjNp7L4Eaw5Z4sOYdbBz6koWyibppd8Zqw=="
     },
+    "leaflet.locatecontrol": {
+      "version": "0.72.0",
+      "resolved": "https://registry.npmjs.org/leaflet.locatecontrol/-/leaflet.locatecontrol-0.72.0.tgz",
+      "integrity": "sha512-enAf10UG9Z1bV0siTP/+vG/ZVncDqSA3V8c6iZ3s6KWL5Ngkk4A4mk9Ssefj46ey98I9HSYWqoS+k2Y7EaKjwQ=="
+    },
     "less": {
       "version": "3.12.2",
       "resolved": "https://registry.npmjs.org/less/-/less-3.12.2.tgz",
@@ -9728,6 +9787,12 @@
       "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
       "dev": true
     },
+    "os-shim": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz",
+      "integrity": "sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc=",
+      "dev": true
+    },
     "os-tmpdir": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
diff --git a/package.json b/package.json
index 90b8efc60..b463714e8 100644
--- a/package.json
+++ b/package.json
@@ -25,7 +25,9 @@
     "@angular/platform-browser-dynamic": "~10.1.3",
     "@angular/router": "~10.1.3",
     "@asymmetrik/ngx-leaflet": "^8.1.0",
+    "@runette/ngx-leaflet-locate": "^1.0.3",
     "leaflet": "^1.7.1",
+    "leaflet.locatecontrol": "^0.72.0",
     "rxjs": "~6.6.0",
     "tslib": "^2.0.0",
     "zone.js": "~0.10.2"
@@ -38,11 +40,12 @@
     "@types/jasmine": "~3.5.0",
     "@types/jasminewd2": "~2.0.3",
     "@types/leaflet": "^1.5.17",
-    "@types/node": "^12.12.62",
+    "@types/node": "^12.12.67",
     "codelyzer": "^6.0.0",
     "jasmine-core": "~3.6.0",
     "jasmine-spec-reporter": "~5.0.0",
     "karma": "~5.0.0",
+    "karma-browserify": "^7.0.0",
     "karma-chrome-launcher": "~3.1.0",
     "karma-coverage-istanbul-reporter": "~3.0.2",
     "karma-jasmine": "~4.0.0",
diff --git a/src/app/map/components/map.component.html b/src/app/map/components/map.component.html
index de076413c..7fa9fe594 100644
--- a/src/app/map/components/map.component.html
+++ b/src/app/map/components/map.component.html
@@ -1 +1,12 @@
-<div id="map" leaflet [leafletOptions]="mapOptions" (leafletMapReady)="onMapReady($event)"></div>
+<div
+  id="map"
+  leaflet
+  [leafletOptions]="mapOptions"
+  [leafletLayersControl]="layersControl"
+  (leafletMapReady)="onMapReady($event)"
+></div>
+<leaflet-locate-control
+  [map]="map"
+  [options]="locateOptions"
+  (location$)="onNewLocation($event)"
+></leaflet-locate-control>
diff --git a/src/app/map/components/map.component.scss b/src/app/map/components/map.component.scss
index 4bbcec030..67c8eb237 100644
--- a/src/app/map/components/map.component.scss
+++ b/src/app/map/components/map.component.scss
@@ -1,3 +1,31 @@
+@import '../../../assets/scss/color';
+
 #map {
   height: 600px;
 }
+
+::ng-deep .fa-map-marker {
+  display: inline-block;
+  height: 0;
+  width: 0;
+  border-right: 5px solid transparent;
+  border-bottom: 12px solid red;
+  border-left: 7px solid transparent;
+}
+
+::ng-deep .leaflet-control-locate-circle {
+  &.leaflet-interactive {
+    stroke: $white !important;
+    fill: $black !important;
+    stroke-width: 2px !important;
+  }
+}
+
+::ng-deep .leaflet-marker-icon {
+  &.leaflet-interactive {
+    circle {
+      fill: $primary-color !important;
+      stroke-width: unset !important;
+    }
+  }
+}
diff --git a/src/app/map/components/map.component.ts b/src/app/map/components/map.component.ts
index 704918cd7..473f9d8fb 100644
--- a/src/app/map/components/map.component.ts
+++ b/src/app/map/components/map.component.ts
@@ -1,7 +1,7 @@
 import { Component, OnInit } from '@angular/core';
-import { latLng, MapOptions, tileLayer, Map, Marker, icon } from 'leaflet';
+import { latLng, MapOptions, tileLayer, Map, Marker, icon, CRS, TileLayer, LatLngBounds } from 'leaflet';
 
-declare var ol: any;
+declare const L: any; // Leaflet
 @Component({
   selector: 'app-map',
   templateUrl: './map.component.html',
@@ -10,6 +10,16 @@ declare var ol: any;
 export class MapComponent implements OnInit {
   public map: Map;
   public mapOptions: MapOptions;
+  public layersControl = {};
+  public locateOptions = {
+    flyTo: false,
+    keepCurrentZoomLevel: true,
+    locateOptions: {
+      enableHighAccuracy: true,
+    },
+    icon: 'fa-map-marker',
+    clickBehavior: { inView: 'stop', outOfView: 'setView', inViewNotFollowing: 'setView' },
+  };
 
   constructor() {}
 
@@ -22,23 +32,74 @@ export class MapComponent implements OnInit {
     this.addSampleMarker();
   }
 
+  public onNewLocation(e: Location): void {
+    console.log(e);
+  }
+
   private initializeMapOptions(): void {
+    const metroMaps = new TileLayer.WMS('https://download.data.grandlyon.com/wms/grandlyon', {
+      crs: CRS.EPSG4326,
+      transparent: true,
+      format: 'image/png',
+      attribution: 'Map data © OpenStreetMap contributors',
+      version: '1.3.0',
+      bounds: new LatLngBounds([45.437, 4.568], [46.03, 5.18]),
+    });
+    metroMaps.wmsParams = {
+      format: 'image/png',
+      transparent: true,
+      version: '1.3.0',
+      layers: 'adr_voie_lieu.adrmetropole',
+      service: 'WMS',
+      request: 'GetMap',
+      width: 256,
+      height: 256,
+    };
+
+    const ignMaps = new TileLayer.WMS('https://data.grandlyon.com/api/query/map/ign', {
+      crs: CRS.EPSG4326,
+      transparent: true,
+      format: 'image/png',
+      attribution: 'Map data © OpenStreetMap contributors',
+      version: '1.1.1',
+    });
+    ignMaps.wmsParams = {
+      format: 'image/png',
+      styles: 'normal',
+      transparent: true,
+      version: '1.1.1',
+      layers: 'ORTHOIMAGERY.ORTHOPHOTOS.BDORTHO',
+      service: 'WMS',
+      request: 'GetMap',
+      width: 512,
+      height: 512,
+    };
+
+    const carteLayer = tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
+      maxZoom: 18,
+      attribution: 'Map data © OpenStreetMap contributors',
+    });
+
+    this.layersControl = {
+      baseLayers: {
+        Carte: carteLayer,
+        Satellite: ignMaps,
+      },
+      overlays: {
+        'Contours métropole': metroMaps,
+      },
+    };
     this.mapOptions = {
       center: latLng(45.764043, 4.835659),
       zoom: 12,
-      layers: [
-        tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
-          maxZoom: 18,
-          attribution: 'Map data © OpenStreetMap contributors',
-        }),
-      ],
+      layers: [carteLayer, metroMaps],
     };
   }
 
   private addSampleMarker(): void {
     const marker = new Marker([45.764043, 4.835659]).setIcon(
       icon({
-        iconSize: [25, 41],
+        iconSize: [35, 41],
         iconAnchor: [13, 41],
         iconUrl: '../../../assets/img/ic_marker.png',
       })
@@ -46,11 +107,12 @@ export class MapComponent implements OnInit {
     marker.addTo(this.map);
     const marker2 = new Marker([45.764043, 4.935659]).setIcon(
       icon({
-        iconSize: [25, 41],
+        iconSize: [35, 41],
         iconAnchor: [13, 41],
         iconUrl: '../../../assets/img/ic_marker.png',
       })
     );
     marker2.addTo(this.map);
+    marker.bindTooltip('<p>Hello <br/>World !</p>');
   }
 }
diff --git a/src/app/map/map.module.ts b/src/app/map/map.module.ts
index d52d49db8..3487eb49d 100644
--- a/src/app/map/map.module.ts
+++ b/src/app/map/map.module.ts
@@ -3,8 +3,9 @@ import { CommonModule, DatePipe } from '@angular/common';
 import { SharedModule } from '../shared/shared.module';
 import { MapComponents } from './components';
 import { LeafletModule } from '@asymmetrik/ngx-leaflet';
+import { NgxLeafletLocateModule } from '@runette/ngx-leaflet-locate';
 @NgModule({
-  imports: [CommonModule, SharedModule, LeafletModule],
+  imports: [CommonModule, SharedModule, NgxLeafletLocateModule, LeafletModule],
   declarations: [MapComponents],
   providers: [DatePipe],
   exports: [MapComponents],
diff --git a/src/assets/img/ic_marker.png b/src/assets/img/ic_marker.png
index 0cee292f0cfac7648bf62b1d257936ffb4986ffc..f378d60ad21bd0bae4e7570e9b6cb9800fc8f0e9 100644
GIT binary patch
delta 1240
zcmV;}1Sk891^NjgiBL{Q4GJ0x0000DNk~Le0000d0000k2nGNE0IRG3{gELwe*}+7
zL_t(|0nM2|OcX&B#@`Yvu(*QLlEn_9@r)X+<cy6L8VEL6s6-O1IHg305Ctm{Itvrg
z#>z-+v@sl38cBd)ppqL({v^^sd%kaYvl*5<c6PY~zvSJ_-p=j*cr)|n&EQc26^q3b
z7p-h(*|Kc7_N^vLY>sUjrRRByf2t{l%Cb!rlj##%Yn=CaE{y=i#Z%hxlGf7iCHnQ_
z7p)XlXnl2^Hr6(R_Vp*~DSa|c4UG+S@$yA#I^ASHPO-JIC+DKx>qS7N1nLp4x3{+G
z%jYlJP<K`OL|Oy3-)Yx%(HPqhLvB)BI0o~%m}2vjLX}c`N4qwWV!K*ye>{3oVC!q^
z^t|smp{$hPz5bDY<3&{t(Ay6T<Lc$`%L99>lxpj0skg6}n$I+s1@uB-7-O>r>{;J4
zs<!%v`)$B;_86=QwZ-7qT?vmJhDJw5&5-fs{ec3{Neudgdaf&1(J>Y!jJ+4*FLYPa
zPWR?fu|4++A0Iz_JXA0UfA2#i5Cz`TaN;%Hoq#(ESz#(GK|k<Z4j)Ou&>a^pU!az2
zEqZWUf!0|jmWs6Zj!Edq;$mrGiQ)(l-H*Dd`E>K1d*8o(k3B>HcjML#{IT#}swM#A
z&=KcBST`|<1q{<a&o&_?UAcBe-$y%F!Fy_1naftdWl)>>G2{FYe|T(QWWda>Nw!9w
zVVGr|C~?j94)@V6PB+i|3^+1?LrzAjpj>~i*G2)GV3@Y>;*Chpb|2tq*PZKjeKf5s
zub65J;C$3JRyUk}jF+LyL_-nHJMn=@B7aPztkf$Nz`2e$|CDd4`KatxJet>lB_>TN
zSsZ>1#Z-N|-c*(2e@}Ej)gE{AoUPb!TiaWvnsNMzo~}t&9l$A6TxS$wp+xeG#K^L;
zW2iOI_f^BGAoM7}>6zv_U;$=@owpIq^?Hqf?3xqS)z$5Sn@3G@DkoWy-|WVG`#!Gm
zJy%=fuGi-;oj28az~w_<MhY(+9S-uaEL(wLW(5?<Y60Jef7&?-YqV(6lkE2|+}_jG
z6MI*MfNaG*Ej(lT+qCvroadqUkQuWO#2a<8DP54o!;)quO=p?{FzjQK>^rdOk$Cu+
z;l>PHmW!z*-m8@0{fD`Ss49}pj*fGZ7UwZzZ+G0L!<HEyq9L>L*g+WU;O6yP*Y}K}
zY71ay56fT^f9CrDPH6Q)ez)sxtUT<XVB!qLcGbSOYx%+;<YHWJc%SqpO1I+(y<~Og
z<8UIeXKm#MIJC)!jtnX;cnduw!Z@1@w<)*qx3SGt3(%UG25hiYyZug?5S$VJGL<~c
zL05)6HdwB$%lVuJMC`-a2@VUBDs=p{FIXg;1v$aRe?8P+kH6MgMzz75;RJAyWV0K0
znZx+9VrQov%PInw1P~z!V3KJdZ)`J%G!=&vK!h5dM1KAJmEOO3PvyV{h6hY$tH|+?
z`ap03n5CWLvee?jqCR7@lLgmf)v8IdT_l-B^+y$Z9`qDDZg%K$ZFSB3@1YR2&o~r7
z0CA|XF2QDx46GEOrCEuQM=yW~(EkNyB!FX;1p5albj*?`Xz`Q)0000<MNUMnLSTX#
COJ6kr

delta 613
zcmV-r0-F8$35*3HiBL{Q4GJ0x0000DNk~Le0000N0000R2nGNE0GH?#+mRtOe*z&%
zL_t(|0j*ZuaoRu-{`O9q@r(JXAfyA*L8!n^1vV8}82lV~jvR{$z!fAN5LaNAKnDWy
z;0%&(vnLOPV4VzxZw7R?%YJ*@?S3ah34Zsy&j6hn!Z|V5WL&d$COnam5ApqJnErCb
zlZ%vzMqo7X76?;h7*xI|<JYcNf5iSB0|EAg5Jjh9(%G_Y5a0NZ%xL1Bu-jGrmV8>x
z)tcC@_yA%Hl6cFrp4+d*wSOsTMmQ2OaH}o{{jze6uQ(#KEe3(g%dMm;n0dzFL6+)|
zl`tXuv~!7>IoX9T7G7F({gG_WrHj~P)T&3x)3z@T{HE5JNNlYzmM~P(e+ceFBsDA|
zwy<_49y&vTGsPe$xk=R+B`~Sy_A_d#EVv&1nI7OTCx7mqd?@qBL8&~<RIUvUEXlM>
zg5i1Ih07-rGF5Ew;Q9f9ui_iO@JwXY%~A~_JdmwN4Vu7>8G)iSUEbFtOrL|3M(UXh
zh6z>@Tm;(>dHc_M{-X>If6|rzz!+C<lXiZf2He4sAmTU8GCi>4oZN~`-qJ^aY++|r
zqU%zuhG}2geTV}f4LPXXE`R<@w1s)si-_n7?;x&*%l@XV@D82#yuSRson=@`vQrI{
zXxmP%fSnT<w2Ln1Qt~{(wI7heU6C)BW5SpEzONRWh`ah+Lyb0dJKL6<$%NP;$2*hf
z3FKl>8b658cp=uUw-j?P#M1VQo;R`2U1R<N>i_4E$M>M100000NkvXXu0mjf+fySZ

diff --git a/src/index.html b/src/index.html
index 3469415cc..e3de07cb0 100644
--- a/src/index.html
+++ b/src/index.html
@@ -7,6 +7,10 @@
     <meta name="viewport" content="width=device-width, initial-scale=1" />
     <link rel="icon" type="image/x-icon" href="favicon.ico" />
     <link rel="stylesheet" href="https://openlayers.org/en/v4.6.5/css/ol.css" type="text/css" />
+    <link
+      rel="stylesheet"
+      href="https://cdn.jsdelivr.net/npm/leaflet.locatecontrol@0.72.0/dist/L.Control.Locate.min.css"
+    />
     <script src="https://openlayers.org/en/v4.6.5/build/ol.js" type="text/javascript"></script>
   </head>
   <body>
diff --git a/src/styles.scss b/src/styles.scss
index 96329efae..d62180f39 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -3,6 +3,7 @@
 @import 'assets/scss/typography';
 @import 'assets/scss/color';
 @import 'assets/scss/breakpoint';
+@import '../node_modules/leaflet.locatecontrol/dist/L.Control.Locate.css';
 
 html,
 body {
diff --git a/tsconfig.app.json b/tsconfig.app.json
index 6bb6c9dac..789f1f58b 100644
--- a/tsconfig.app.json
+++ b/tsconfig.app.json
@@ -3,6 +3,8 @@
   "extends": "./tsconfig.json",
   "compilerOptions": {
     "outDir": "./out-tsc/app",
+    "fullTemplateTypeCheck": true,
+    "strictInjectionParameters": true,
     "types": ["node"]
   },
   "files": ["src/main.ts", "src/polyfills.ts"],
diff --git a/tsconfig.spec.json b/tsconfig.spec.json
index 092345b02..1fde99220 100644
--- a/tsconfig.spec.json
+++ b/tsconfig.spec.json
@@ -3,16 +3,8 @@
   "extends": "./tsconfig.json",
   "compilerOptions": {
     "outDir": "./out-tsc/spec",
-    "types": [
-      "jasmine"
-    ]
+    "types": ["node", "jasmine"]
   },
-  "files": [
-    "src/test.ts",
-    "src/polyfills.ts"
-  ],
-  "include": [
-    "src/**/*.spec.ts",
-    "src/**/*.d.ts"
-  ]
+  "files": ["src/test.ts", "src/polyfills.ts"],
+  "include": ["src/**/*.spec.ts", "src/**/*.d.ts"]
 }
-- 
GitLab


From 5aa1038800f5b2eaa021040e0b5e3e33e124b4ae Mon Sep 17 00:00:00 2001
From: Hugo SUBTIL <ext.sopra.husubtil@grandlyon.com>
Date: Tue, 13 Oct 2020 17:21:37 +0200
Subject: [PATCH 03/10] feat(map): clean code and remove ign map because of
 heavy loading

---
 src/app/home/home.component.html          |  7 +-
 src/app/map/components/map.component.html | 14 +---
 src/app/map/components/map.component.scss |  4 +-
 src/app/map/components/map.component.ts   | 94 +++++++++--------------
 src/app/map/services/map.service.ts       | 29 +++++++
 tsconfig.app.json                         |  2 -
 6 files changed, 72 insertions(+), 78 deletions(-)

diff --git a/src/app/home/home.component.html b/src/app/home/home.component.html
index 56147e48a..ca9398f41 100644
--- a/src/app/home/home.component.html
+++ b/src/app/home/home.component.html
@@ -1,5 +1,4 @@
-<div class="content-container">
-  <div class="section-container">
-    <app-map></app-map>
-  </div>
+<div fxLayout="row">
+  <p fxFlex="30%">temp</p>
+  <app-map fxFlex="70%" [toogleToolTipIds]="[1, 2]"></app-map>
 </div>
diff --git a/src/app/map/components/map.component.html b/src/app/map/components/map.component.html
index 7fa9fe594..4ed0d90d5 100644
--- a/src/app/map/components/map.component.html
+++ b/src/app/map/components/map.component.html
@@ -1,12 +1,2 @@
-<div
-  id="map"
-  leaflet
-  [leafletOptions]="mapOptions"
-  [leafletLayersControl]="layersControl"
-  (leafletMapReady)="onMapReady($event)"
-></div>
-<leaflet-locate-control
-  [map]="map"
-  [options]="locateOptions"
-  (location$)="onNewLocation($event)"
-></leaflet-locate-control>
+<div id="map" leaflet [leafletOptions]="mapOptions" (leafletMapReady)="onMapReady($event)"></div>
+<leaflet-locate-control [map]="map" [options]="locateOptions"></leaflet-locate-control>
diff --git a/src/app/map/components/map.component.scss b/src/app/map/components/map.component.scss
index 67c8eb237..e11a4d0aa 100644
--- a/src/app/map/components/map.component.scss
+++ b/src/app/map/components/map.component.scss
@@ -1,7 +1,9 @@
 @import '../../../assets/scss/color';
+@import '../../../assets/scss/layout';
 
 #map {
-  height: 600px;
+  height: calc(100vh - #{$header-height} - #{$footer-height});
+  width: 100%;
 }
 
 ::ng-deep .fa-map-marker {
diff --git a/src/app/map/components/map.component.ts b/src/app/map/components/map.component.ts
index 473f9d8fb..6121644a2 100644
--- a/src/app/map/components/map.component.ts
+++ b/src/app/map/components/map.component.ts
@@ -1,16 +1,17 @@
-import { Component, OnInit } from '@angular/core';
-import { latLng, MapOptions, tileLayer, Map, Marker, icon, CRS, TileLayer, LatLngBounds } from 'leaflet';
+import { Component, Input, OnInit } from '@angular/core';
+import { latLng, MapOptions, tileLayer, Map, CRS, TileLayer, LatLngBounds } from 'leaflet';
+import { MapService } from '../services/map.service';
 
-declare const L: any; // Leaflet
 @Component({
   selector: 'app-map',
   templateUrl: './map.component.html',
   styleUrls: ['./map.component.scss'],
 })
 export class MapComponent implements OnInit {
+  @Input() public toogleToolTipIds: Array<number> = [];
   public map: Map;
   public mapOptions: MapOptions;
-  public layersControl = {};
+  // Init locate options
   public locateOptions = {
     flyTo: false,
     keepCurrentZoomLevel: true,
@@ -21,22 +22,29 @@ export class MapComponent implements OnInit {
     clickBehavior: { inView: 'stop', outOfView: 'setView', inViewNotFollowing: 'setView' },
   };
 
-  constructor() {}
+  constructor(private mapService: MapService) {}
 
   ngOnInit(): void {
     this.initializeMapOptions();
   }
 
+  /**
+   * Add marker when map is ready to be showned
+   * @param map
+   */
   public onMapReady(map: Map): void {
     this.map = map;
-    this.addSampleMarker();
-  }
-
-  public onNewLocation(e: Location): void {
-    console.log(e);
+    this.addMarker();
+    this.toggleToolTip(this.toogleToolTipIds);
   }
 
+  /**
+   * Init map options :
+   * - Metropole bounds based on a WMS service hosted by data.grandlyon.com
+   * - Map Layer based on open street maps
+   */
   private initializeMapOptions(): void {
+    // Init WMS service with param from data.grandlyon.com
     const metroMaps = new TileLayer.WMS('https://download.data.grandlyon.com/wms/grandlyon', {
       crs: CRS.EPSG4326,
       transparent: true,
@@ -55,64 +63,32 @@ export class MapComponent implements OnInit {
       width: 256,
       height: 256,
     };
-
-    const ignMaps = new TileLayer.WMS('https://data.grandlyon.com/api/query/map/ign', {
-      crs: CRS.EPSG4326,
-      transparent: true,
-      format: 'image/png',
-      attribution: 'Map data © OpenStreetMap contributors',
-      version: '1.1.1',
-    });
-    ignMaps.wmsParams = {
-      format: 'image/png',
-      styles: 'normal',
-      transparent: true,
-      version: '1.1.1',
-      layers: 'ORTHOIMAGERY.ORTHOPHOTOS.BDORTHO',
-      service: 'WMS',
-      request: 'GetMap',
-      width: 512,
-      height: 512,
-    };
-
     const carteLayer = tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
       maxZoom: 18,
       attribution: 'Map data © OpenStreetMap contributors',
     });
-
-    this.layersControl = {
-      baseLayers: {
-        Carte: carteLayer,
-        Satellite: ignMaps,
-      },
-      overlays: {
-        'Contours métropole': metroMaps,
-      },
-    };
+    // Center is set on townhall
+    // Zoom is blocked on 11 to prevent people to zoom out from metropole
     this.mapOptions = {
       center: latLng(45.764043, 4.835659),
-      zoom: 12,
+      zoom: 11,
+      minZoom: 11,
       layers: [carteLayer, metroMaps],
     };
   }
 
-  private addSampleMarker(): void {
-    const marker = new Marker([45.764043, 4.835659]).setIcon(
-      icon({
-        iconSize: [35, 41],
-        iconAnchor: [13, 41],
-        iconUrl: '../../../assets/img/ic_marker.png',
-      })
-    );
-    marker.addTo(this.map);
-    const marker2 = new Marker([45.764043, 4.935659]).setIcon(
-      icon({
-        iconSize: [35, 41],
-        iconAnchor: [13, 41],
-        iconUrl: '../../../assets/img/ic_marker.png',
-      })
-    );
-    marker2.addTo(this.map);
-    marker.bindTooltip('<p>Hello <br/>World !</p>');
+  /**
+   * Toogle all tooltips given in parameters
+   */
+  public toggleToolTip(ids: Array<number>): void {
+    ids.forEach((id) => {
+      this.mapService.toogleToolTip(id);
+    });
+  }
+
+  private addMarker(): void {
+    //TODO: Replace with real data
+    this.map = this.mapService.addMarker(this.map, 45.764043, 4.835659, 1);
+    this.map = this.mapService.addMarker(this.map, 45.764043, 4.935659, 2);
   }
 }
diff --git a/src/app/map/services/map.service.ts b/src/app/map/services/map.service.ts
index 81ce8c87d..30aaad690 100644
--- a/src/app/map/services/map.service.ts
+++ b/src/app/map/services/map.service.ts
@@ -1,8 +1,37 @@
 import { Injectable } from '@angular/core';
+import { icon, Marker, Map } from 'leaflet';
 
 @Injectable({
   providedIn: 'root',
 })
 export class MapService {
+  private markersList = {};
   constructor() {}
+
+  public addMarker(map: Map, lat: number, lon: number, id: number): Map {
+    const marker = new Marker([lat, lon]).setIcon(
+      icon({
+        iconSize: [35, 41],
+        iconAnchor: [13, 41],
+        iconUrl: '../../../assets/img/ic_marker.png',
+      })
+    );
+
+    marker.bindTooltip('<p>Hello <br/>World !</p>'); //TODO: replace with real data
+    marker.addTo(map);
+    this.markersList[id] = marker;
+    return map;
+  }
+
+  public toogleToolTip(id: number): void {
+    this.getMarker(id).toggleTooltip();
+  }
+
+  public setToolTip(id: number): void {
+    this.getMarker(id).bindTooltip('<p>Hello <br/>World 2!</p>');
+  }
+
+  public getMarker(id: number): Marker {
+    return this.markersList[id];
+  }
 }
diff --git a/tsconfig.app.json b/tsconfig.app.json
index 789f1f58b..6bb6c9dac 100644
--- a/tsconfig.app.json
+++ b/tsconfig.app.json
@@ -3,8 +3,6 @@
   "extends": "./tsconfig.json",
   "compilerOptions": {
     "outDir": "./out-tsc/app",
-    "fullTemplateTypeCheck": true,
-    "strictInjectionParameters": true,
     "types": ["node"]
   },
   "files": ["src/main.ts", "src/polyfills.ts"],
-- 
GitLab


From 6295b528092663fbadde388a192f29f8c64e44c1 Mon Sep 17 00:00:00 2001
From: Hugo SUBTIL <ext.sopra.husubtil@grandlyon.com>
Date: Fri, 16 Oct 2020 17:15:28 +0200
Subject: [PATCH 04/10] feat(map): add TU and clean service

---
 package-lock.json                         | 26 +++++++++---------
 src/app/home/home.component.html          |  2 +-
 src/app/home/home.component.scss          |  3 +++
 src/app/map/components/map.component.scss | 29 +++++++++++++++-----
 src/app/map/components/map.component.ts   | 16 +++++------
 src/app/map/services/map.service.spec.ts  | 33 +++++++++++++++++++++++
 src/app/map/services/map.service.ts       | 27 ++++++++++++++-----
 7 files changed, 101 insertions(+), 35 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 57bbd8dbf..ce5d413bd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8047,17 +8047,17 @@
         }
       }
     },
+    "jju": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz",
+      "integrity": "sha1-o6vicYryQaKykE+EpiWXDzia4yo="
+    },
     "js-string-escape": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz",
       "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=",
       "dev": true
     },
-    "jju": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz",
-      "integrity": "sha1-o6vicYryQaKykE+EpiWXDzia4yo="
-    },
     "js-tokens": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -8671,6 +8671,14 @@
       "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==",
       "dev": true
     },
+    "latest-version": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz",
+      "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==",
+      "requires": {
+        "package-json": "^6.3.0"
+      }
+    },
     "leaflet": {
       "version": "1.7.1",
       "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.7.1.tgz",
@@ -8681,14 +8689,6 @@
       "resolved": "https://registry.npmjs.org/leaflet.locatecontrol/-/leaflet.locatecontrol-0.72.0.tgz",
       "integrity": "sha512-enAf10UG9Z1bV0siTP/+vG/ZVncDqSA3V8c6iZ3s6KWL5Ngkk4A4mk9Ssefj46ey98I9HSYWqoS+k2Y7EaKjwQ=="
     },
-    "latest-version": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz",
-      "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==",
-      "requires": {
-        "package-json": "^6.3.0"
-      }
-    },
     "less": {
       "version": "3.12.2",
       "resolved": "https://registry.npmjs.org/less/-/less-3.12.2.tgz",
diff --git a/src/app/home/home.component.html b/src/app/home/home.component.html
index cec915a85..030fee9dd 100644
--- a/src/app/home/home.component.html
+++ b/src/app/home/home.component.html
@@ -1,4 +1,4 @@
 <div fxLayout="row">
-  <app-structure-list fxFlex="30%"></app-structure-list>
+  <app-structure-list class="left-pane" fxFlex="30%"></app-structure-list>
   <app-map fxFlex="70%" [toogleToolTipIds]="[1, 2]"></app-map>
 </div>
diff --git a/src/app/home/home.component.scss b/src/app/home/home.component.scss
index e69de29bb..7d2eb86af 100644
--- a/src/app/home/home.component.scss
+++ b/src/app/home/home.component.scss
@@ -0,0 +1,3 @@
+.left-pane {
+  padding: 0 25px;
+}
diff --git a/src/app/map/components/map.component.scss b/src/app/map/components/map.component.scss
index e11a4d0aa..e40578ea2 100644
--- a/src/app/map/components/map.component.scss
+++ b/src/app/map/components/map.component.scss
@@ -7,12 +7,29 @@
 }
 
 ::ng-deep .fa-map-marker {
-  display: inline-block;
-  height: 0;
-  width: 0;
-  border-right: 5px solid transparent;
-  border-bottom: 12px solid red;
-  border-left: 7px solid transparent;
+  color: $black;
+  position: absolute;
+  margin-left: 4px;
+  margin-top: 2px;
+  width: 12px;
+  height: 12px;
+  border: solid 1px currentColor;
+  border-radius: 7px 7px 7px 0;
+  -webkit-transform: rotate(-45deg);
+  transform: rotate(-45deg);
+  margin-left: -6px;
+  margin-top: 6px;
+}
+
+::ng-deep .fa-map-marker:before {
+  content: '';
+  position: absolute;
+  left: 3px;
+  top: 3px;
+  width: 4px;
+  height: 4px;
+  border: solid 1px currentColor;
+  border-radius: 3px;
 }
 
 ::ng-deep .leaflet-control-locate-circle {
diff --git a/src/app/map/components/map.component.ts b/src/app/map/components/map.component.ts
index 6121644a2..f3e84b556 100644
--- a/src/app/map/components/map.component.ts
+++ b/src/app/map/components/map.component.ts
@@ -14,7 +14,7 @@ export class MapComponent implements OnInit {
   // Init locate options
   public locateOptions = {
     flyTo: false,
-    keepCurrentZoomLevel: true,
+    keepCurrentZoomLevel: false,
     locateOptions: {
       enableHighAccuracy: true,
     },
@@ -30,12 +30,11 @@ export class MapComponent implements OnInit {
 
   /**
    * Add marker when map is ready to be showned
-   * @param map
+   * @param map map
    */
   public onMapReady(map: Map): void {
     this.map = map;
     this.addMarker();
-    this.toggleToolTip(this.toogleToolTipIds);
   }
 
   /**
@@ -64,15 +63,15 @@ export class MapComponent implements OnInit {
       height: 256,
     };
     const carteLayer = tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
-      maxZoom: 18,
+      maxZoom: 20,
       attribution: 'Map data © OpenStreetMap contributors',
     });
     // Center is set on townhall
     // Zoom is blocked on 11 to prevent people to zoom out from metropole
     this.mapOptions = {
       center: latLng(45.764043, 4.835659),
-      zoom: 11,
-      minZoom: 11,
+      zoom: 10,
+      minZoom: 10,
       layers: [carteLayer, metroMaps],
     };
   }
@@ -88,7 +87,8 @@ export class MapComponent implements OnInit {
 
   private addMarker(): void {
     //TODO: Replace with real data
-    this.map = this.mapService.addMarker(this.map, 45.764043, 4.835659, 1);
-    this.map = this.mapService.addMarker(this.map, 45.764043, 4.935659, 2);
+    this.mapService.createMarker(45.764043, 4.835659, 1, '<p>Hello <br/>World !</p>').addTo(this.map);
+    this.mapService.createMarker(45.764043, 4.935659, 2, '<p>Hello <br/>World 2!</p>').addTo(this.map);
+    this.mapService.createMarker(45.664043, 4.835659, 3).addTo(this.map);
   }
 }
diff --git a/src/app/map/services/map.service.spec.ts b/src/app/map/services/map.service.spec.ts
index 9a1a1ec53..3470f88c5 100644
--- a/src/app/map/services/map.service.spec.ts
+++ b/src/app/map/services/map.service.spec.ts
@@ -1,4 +1,5 @@
 import { TestBed } from '@angular/core/testing';
+import { Map } from 'leaflet';
 
 import { MapService } from './map.service';
 
@@ -13,4 +14,36 @@ describe('MapService', () => {
   it('should be created', () => {
     expect(service).toBeTruthy();
   });
+
+  it('should create marke with coord {lat: 45.764043, lng: 4.835659}', () => {
+    const marker = service.createMarker(45.764043, 4.835659, 1);
+
+    expect(marker.getLatLng().lat).toEqual(45.764043);
+    expect(marker.getLatLng().lng).toEqual(4.835659);
+  });
+  it('should add marker to map with icon ic_marker.png', () => {
+    const marker = service.createMarker(45.764043, 4.835659, 1);
+
+    expect(marker.getIcon().options.iconUrl).toEqual('../../../assets/img/ic_marker.png');
+    expect(marker.getIcon().options.iconSize).toEqual([35, 41]);
+    expect(marker.getIcon().options.iconAnchor).toEqual([13, 41]);
+  });
+
+  it('should cerate marker with tooltip', () => {
+    const marker = service.createMarker(45.764043, 4.835659, 1, '<p>Hello <br/>World !</p>');
+
+    expect(marker.getTooltip().getContent()).toEqual('<p>Hello <br/>World !</p>');
+  });
+
+  it('should get marker', () => {
+    const marker = service.createMarker(45.764043, 4.835659, 1, '<p>Hello <br/>World !</p>');
+    expect(marker).toEqual(service.getMarker(1));
+  });
+  it('should not get marker, with missing id', () => {
+    service.createMarker(45.764043, 4.835659, 1, '<p>Hello <br/>World !</p>');
+    expect(service.getMarker(2)).toEqual(null);
+  });
+  it('should not get marker, empty', () => {
+    expect(service.getMarker(1)).toEqual(null);
+  });
 });
diff --git a/src/app/map/services/map.service.ts b/src/app/map/services/map.service.ts
index 30aaad690..eb5eb8d4f 100644
--- a/src/app/map/services/map.service.ts
+++ b/src/app/map/services/map.service.ts
@@ -8,7 +8,7 @@ export class MapService {
   private markersList = {};
   constructor() {}
 
-  public addMarker(map: Map, lat: number, lon: number, id: number): Map {
+  public createMarker(lat: number, lon: number, id: number, tooltip?: string): Marker {
     const marker = new Marker([lat, lon]).setIcon(
       icon({
         iconSize: [35, 41],
@@ -17,21 +17,34 @@ export class MapService {
       })
     );
 
-    marker.bindTooltip('<p>Hello <br/>World !</p>'); //TODO: replace with real data
-    marker.addTo(map);
+    if (tooltip) {
+      marker.bindTooltip(tooltip);
+    }
     this.markersList[id] = marker;
-    return map;
+    return marker;
   }
 
+  /**
+   * Toogle a tooltip
+   * @param id marker id
+   */
   public toogleToolTip(id: number): void {
     this.getMarker(id).toggleTooltip();
   }
 
-  public setToolTip(id: number): void {
-    this.getMarker(id).bindTooltip('<p>Hello <br/>World 2!</p>');
+  /**
+   * Set a tooltip
+   * @param id markerId
+   * @param html html to display
+   */
+  public setToolTip(id: number, html: string): void {
+    this.getMarker(id).bindTooltip(html);
   }
 
+  /**
+   * Get marker by id
+   */
   public getMarker(id: number): Marker {
-    return this.markersList[id];
+    return this.markersList[id] ? this.markersList[id] : null;
   }
 }
-- 
GitLab


From 397fb5f7c840a2fed513ef98cf5ebf8cc27fc2c7 Mon Sep 17 00:00:00 2001
From: Hugo SUBTIL <ext.sopra.husubtil@grandlyon.com>
Date: Tue, 20 Oct 2020 13:19:44 +0200
Subject: [PATCH 05/10] feat(map): merge structre and map. Remove useless
 components and structure refacto

---
 package-lock.json                             |  8 +++
 package.json                                  |  7 +-
 proxy.conf.json                               | 12 ++++
 src/app/app.module.ts                         | 21 ++++--
 src/app/home/home.component.html              |  4 +-
 src/app/home/home.component.ts                | 15 +++-
 src/app/map/components/map.component.scss     | 35 ++++++++++
 src/app/map/components/map.component.ts       | 70 +++++++++++++++----
 src/app/map/models/address.model.ts           | 16 +++++
 src/app/map/models/addressGeometry.model.ts   | 16 +++++
 src/app/map/models/geojson.model.ts           | 13 ++++
 src/app/map/models/map-options.ts             |  0
 src/app/map/services/geojson.service.spec.ts  | 31 ++++++++
 src/app/map/services/geojson.service.ts       | 33 +++++++++
 src/app/map/services/map.service.ts           |  3 +
 .../{structure-list => }/models/day.model.ts  |  0
 .../models/openingDay.model.ts                |  0
 .../models/structure.model.ts                 | 17 ++++-
 .../{structure-list => }/models/time.model.ts |  0
 .../{structure-list => }/models/week.model.ts |  0
 .../services/structure-list.service.spec.ts   |  0
 .../services/structure-list.service.ts        |  8 +--
 .../components/card/card.component.html       |  1 -
 .../components/card/card.component.scss       |  0
 .../components/card/card.component.spec.ts    | 25 -------
 .../shared/components/card/card.component.ts  | 15 ----
 src/app/shared/components/index.ts            |  6 +-
 .../components/card/card.component.html       | 17 ++---
 .../components/card/card.component.scss       |  8 +--
 .../components/card/card.component.ts         | 18 ++---
 .../structure-list.component.html             |  3 +-
 .../structure-list.component.ts               |  5 +-
 .../structure-list/structure-list.module.ts   | 14 ----
 src/app/structure-list/structure-list.scss    | 10 +++
 src/environments/environment.ts               |  2 +
 35 files changed, 308 insertions(+), 125 deletions(-)
 create mode 100644 src/app/map/models/address.model.ts
 create mode 100644 src/app/map/models/addressGeometry.model.ts
 create mode 100644 src/app/map/models/geojson.model.ts
 delete mode 100644 src/app/map/models/map-options.ts
 create mode 100644 src/app/map/services/geojson.service.spec.ts
 create mode 100644 src/app/map/services/geojson.service.ts
 rename src/app/{structure-list => }/models/day.model.ts (100%)
 rename src/app/{structure-list => }/models/openingDay.model.ts (100%)
 rename src/app/{structure-list => }/models/structure.model.ts (76%)
 rename src/app/{structure-list => }/models/time.model.ts (100%)
 rename src/app/{structure-list => }/models/week.model.ts (100%)
 rename src/app/{structure-list => }/services/structure-list.service.spec.ts (100%)
 rename src/app/{structure-list => }/services/structure-list.service.ts (97%)
 delete mode 100644 src/app/shared/components/card/card.component.html
 delete mode 100644 src/app/shared/components/card/card.component.scss
 delete mode 100644 src/app/shared/components/card/card.component.spec.ts
 delete mode 100644 src/app/shared/components/card/card.component.ts
 delete mode 100644 src/app/structure-list/structure-list.module.ts
 create mode 100644 src/app/structure-list/structure-list.scss

diff --git a/package-lock.json b/package-lock.json
index ce5d413bd..c141501b3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1902,6 +1902,14 @@
         "webpack-sources": "1.4.3"
       }
     },
+    "@ngx-translate/core": {
+      "version": "13.0.0",
+      "resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-13.0.0.tgz",
+      "integrity": "sha512-+tzEp8wlqEnw0Gc7jtVRAJ6RteUjXw6JJR4O65KlnxOmJrCGPI0xjV/lKRnQeU0w4i96PQs/jtpL921Wrb7PWg==",
+      "requires": {
+        "tslib": "^2.0.0"
+      }
+    },
     "@nodelib/fs.scandir": {
       "version": "2.1.3",
       "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
diff --git a/package.json b/package.json
index b582075f7..4b09a880a 100644
--- a/package.json
+++ b/package.json
@@ -3,14 +3,14 @@
   "version": "0.0.3",
   "scripts": {
     "ng": "ng",
-    "start": "ng serve --configuration=fr",
+    "start": "ng serve --configuration=fr --proxy-config proxy.conf.json",
     "build:prod": "ng build --configuration=production,fr --output-path=dist",
     "build:dev": "ng build --configuration=fr --output-path=dist",
     "test": "ng test",
     "lint": "ng lint",
     "e2e": "ng e2e",
     "release": "standard-version",
-    "translate": "ng xi18n --output-path src/locale --out-file messages.en.xlf",
+    "translate": "ng xi18n --ivy --output-path src/locale --out-file messages.en.xlf",
     "api": "json-server api/db.json --routes api/routes.json --no-cors=true"
   },
   "private": true,
@@ -26,10 +26,11 @@
     "@angular/platform-browser-dynamic": "~10.1.3",
     "@angular/router": "~10.1.3",
     "@asymmetrik/ngx-leaflet": "^8.1.0",
+    "@ngx-translate/core": "^13.0.0",
     "@runette/ngx-leaflet-locate": "^1.0.3",
+    "json-server": "^0.16.2",
     "leaflet": "^1.7.1",
     "leaflet.locatecontrol": "^0.72.0",
-    "json-server": "^0.16.2",
     "luxon": "^1.25.0",
     "rxjs": "~6.6.0",
     "tslib": "^2.0.0",
diff --git a/proxy.conf.json b/proxy.conf.json
index c394a84fb..4cafc6d48 100644
--- a/proxy.conf.json
+++ b/proxy.conf.json
@@ -1,5 +1,17 @@
 {
   "/api": {
     "target": "http://localhost:3000"
+  },
+  "/base-adresse/base-adresse-nationale/streets": {
+    "target": "https://passerelle.formulaireextranet.grandlyon.com",
+    "secure": false,
+    "changeOrigin": true,
+    "logLevel": "info"
+  },
+  "/geocoding/photon/api": {
+    "target": "https://download.data.grandlyon.com",
+    "secure": false,
+    "changeOrigin": true,
+    "logLevel": "info"
   }
 }
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 0a75ad24f..7cb7bc0d7 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -1,21 +1,32 @@
 import { LOCALE_ID, NgModule } from '@angular/core';
-
-import { AppRoutingModule } from './app-routing.module';
+import { HttpClientModule } from '@angular/common/http';
 import { BrowserModule } from '@angular/platform-browser';
 import { FlexLayoutModule } from '@angular/flex-layout';
 
+import { AppRoutingModule } from './app-routing.module';
+
 import { AppComponent } from './app.component';
 import { HomeComponent } from './home/home.component';
 import { CustomBreakPointsProvider } from './config/custom-breakpoint';
 import { FooterComponent } from './footer/footer.component';
 import { HeaderComponent } from './header/header.component';
 import { SharedModule } from './shared/shared.module';
-import { StructureListModule } from './structure-list/structure-list.module';
 import { MapModule } from './map/map.module';
+import { RechercheComponent } from './structure-list/components/recherche/recherche.component';
+import { StructureListComponent } from './structure-list/structure-list.component';
+import { CardComponent } from './structure-list/components/card/card.component';
 
 @NgModule({
-  declarations: [AppComponent, HeaderComponent, FooterComponent, HomeComponent],
-  imports: [BrowserModule, AppRoutingModule, FlexLayoutModule, SharedModule, StructureListModule, MapModule],
+  declarations: [
+    AppComponent,
+    HeaderComponent,
+    FooterComponent,
+    HomeComponent,
+    StructureListComponent,
+    CardComponent,
+    RechercheComponent,
+  ],
+  imports: [BrowserModule, HttpClientModule, AppRoutingModule, FlexLayoutModule, SharedModule, MapModule],
   providers: [{ provide: LOCALE_ID, useValue: 'fr' }, CustomBreakPointsProvider],
   bootstrap: [AppComponent],
 })
diff --git a/src/app/home/home.component.html b/src/app/home/home.component.html
index 030fee9dd..68c653d8b 100644
--- a/src/app/home/home.component.html
+++ b/src/app/home/home.component.html
@@ -1,4 +1,4 @@
 <div fxLayout="row">
-  <app-structure-list class="left-pane" fxFlex="30%"></app-structure-list>
-  <app-map fxFlex="70%" [toogleToolTipIds]="[1, 2]"></app-map>
+  <app-structure-list [structureList]="structures" class="left-pane" fxFlex="30%"></app-structure-list>
+  <app-map fxFlex="70%" [structures]="structures"></app-map>
 </div>
diff --git a/src/app/home/home.component.ts b/src/app/home/home.component.ts
index 98af51905..2264953e0 100644
--- a/src/app/home/home.component.ts
+++ b/src/app/home/home.component.ts
@@ -1,4 +1,8 @@
 import { Component, OnInit } from '@angular/core';
+import { mergeMap } from 'rxjs/operators';
+import { Structure } from '../models/structure.model';
+import { StructureService } from '../services/structure-list.service';
+const { DateTime } = require('luxon');
 
 @Component({
   selector: 'app-home',
@@ -6,7 +10,14 @@ import { Component, OnInit } from '@angular/core';
   styleUrls: ['./home.component.scss'],
 })
 export class HomeComponent implements OnInit {
-  constructor() {}
+  public structures: Structure[] = [];
+  constructor(private structureService: StructureService) {}
 
-  ngOnInit(): void {}
+  ngOnInit(): void {
+    this.structureService.getStructures().subscribe((structures) => {
+      this.structures = structures.map((structure) =>
+        this.structureService.updateOpeningStructure(structure, DateTime.local())
+      );
+    });
+  }
 }
diff --git a/src/app/map/components/map.component.scss b/src/app/map/components/map.component.scss
index e40578ea2..7c09074d9 100644
--- a/src/app/map/components/map.component.scss
+++ b/src/app/map/components/map.component.scss
@@ -1,5 +1,7 @@
 @import '../../../assets/scss/color';
 @import '../../../assets/scss/layout';
+@import '../../../assets/scss/icons';
+@import '../../../assets/scss/typography';
 
 #map {
   height: calc(100vh - #{$header-height} - #{$footer-height});
@@ -48,3 +50,36 @@
     }
   }
 }
+
+::ng-deep .leaflet-tooltip {
+  padding: 8px 10px 8px 10px;
+  h1 {
+    color: $purple;
+    @include cn-bold-20;
+    margin: 0;
+  }
+  p {
+    color: $grey-3;
+    @include cn-regular-16;
+    margin: 0 0 13px 0;
+  }
+  div {
+    align-items: center;
+    display: flex;
+  }
+  // Find somthing better than redeclare class. Mixins ?
+  .ico-dot-available {
+    height: 12px;
+    width: 12px;
+    background-color: $green;
+    border-radius: 50%;
+    margin-right: 8px;
+  }
+  .ico-dot-unavailable {
+    height: 12px;
+    width: 12px;
+    background-color: $grey;
+    border-radius: 50%;
+    margin-right: 8px;
+  }
+}
diff --git a/src/app/map/components/map.component.ts b/src/app/map/components/map.component.ts
index f3e84b556..e30ec0504 100644
--- a/src/app/map/components/map.component.ts
+++ b/src/app/map/components/map.component.ts
@@ -1,5 +1,10 @@
-import { Component, Input, OnInit } from '@angular/core';
+import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
 import { latLng, MapOptions, tileLayer, Map, CRS, TileLayer, LatLngBounds } from 'leaflet';
+import { Observable } from 'rxjs';
+import { mergeMap } from 'rxjs/operators';
+import { Structure } from '../../models/structure.model';
+import { GeoJson } from '../models/geojson.model';
+import { GeojsonService } from '../services/geojson.service';
 import { MapService } from '../services/map.service';
 
 @Component({
@@ -7,7 +12,8 @@ import { MapService } from '../services/map.service';
   templateUrl: './map.component.html',
   styleUrls: ['./map.component.scss'],
 })
-export class MapComponent implements OnInit {
+export class MapComponent implements OnChanges {
+  @Input() public structures: Structure[] = [];
   @Input() public toogleToolTipIds: Array<number> = [];
   public map: Map;
   public mapOptions: MapOptions;
@@ -22,19 +28,64 @@ export class MapComponent implements OnInit {
     clickBehavior: { inView: 'stop', outOfView: 'setView', inViewNotFollowing: 'setView' },
   };
 
-  constructor(private mapService: MapService) {}
-
-  ngOnInit(): void {
+  constructor(private mapService: MapService, private geoJsonService: GeojsonService) {
     this.initializeMapOptions();
   }
 
+  ngOnChanges(changes: SimpleChanges): void {
+    if (changes.structures) {
+      this.getStructurePosition();
+    }
+  }
+
+  /**
+   * Get structures positions and add marker corresponding to those positons on the map
+   */
+  private getStructurePosition(): void {
+    this.structures.forEach((element: Structure) => {
+      this.getCoord(element.voie).subscribe((coord: GeoJson) => {
+        this.mapService
+          .createMarker(coord.geometry.getLon(), coord.geometry.getLat(), 1, this.buildToolTip(element))
+          .addTo(this.map);
+      });
+    });
+  }
+
+  /**
+   * Create tooltip for display
+   * @param structure Structure
+   */
+  private buildToolTip(structure: Structure): string {
+    const cssAvailabilityClass = structure.isOpen ? 'available' : 'unavailable';
+    return (
+      '<h1>' +
+      structure.nomDeVotreStructure +
+      '</h1>' +
+      '<p>' +
+      structure.typeDeStructure +
+      '</p><div>' +
+      '<span class="ico-dot-' +
+      cssAvailabilityClass +
+      '"></span><span>' +
+      structure.openDisplay() +
+      '</span></div>'
+    );
+  }
+
+  /**
+   * Get coord with a street reference
+   * @param idVoie Street reference
+   */
+  public getCoord(idVoie: number): Observable<GeoJson> {
+    return this.geoJsonService.getAddress(idVoie).pipe(mergeMap((res) => this.geoJsonService.getCoord(res)));
+  }
+
   /**
    * Add marker when map is ready to be showned
    * @param map map
    */
   public onMapReady(map: Map): void {
     this.map = map;
-    this.addMarker();
   }
 
   /**
@@ -84,11 +135,4 @@ export class MapComponent implements OnInit {
       this.mapService.toogleToolTip(id);
     });
   }
-
-  private addMarker(): void {
-    //TODO: Replace with real data
-    this.mapService.createMarker(45.764043, 4.835659, 1, '<p>Hello <br/>World !</p>').addTo(this.map);
-    this.mapService.createMarker(45.764043, 4.935659, 2, '<p>Hello <br/>World 2!</p>').addTo(this.map);
-    this.mapService.createMarker(45.664043, 4.835659, 3).addTo(this.map);
-  }
 }
diff --git a/src/app/map/models/address.model.ts b/src/app/map/models/address.model.ts
new file mode 100644
index 000000000..b91f488bb
--- /dev/null
+++ b/src/app/map/models/address.model.ts
@@ -0,0 +1,16 @@
+export class Address {
+  public id: number;
+  public text: string;
+  public type: string;
+  public city: string;
+  public citycode: string;
+  public zipcode: string;
+
+  constructor(obj?: any) {
+    Object.assign(this, obj);
+  }
+
+  public queryString(): string {
+    return this.text + ' ' + this.citycode;
+  }
+}
diff --git a/src/app/map/models/addressGeometry.model.ts b/src/app/map/models/addressGeometry.model.ts
new file mode 100644
index 000000000..71e1ce346
--- /dev/null
+++ b/src/app/map/models/addressGeometry.model.ts
@@ -0,0 +1,16 @@
+export class AddressGeometry {
+  public coordinates: Array<number>;
+  public type: string;
+
+  constructor(obj?: any) {
+    Object.assign(this, obj);
+  }
+
+  public getLat(): number {
+    return this.coordinates[0];
+  }
+
+  public getLon(): number {
+    return this.coordinates[1];
+  }
+}
diff --git a/src/app/map/models/geojson.model.ts b/src/app/map/models/geojson.model.ts
new file mode 100644
index 000000000..3407c70da
--- /dev/null
+++ b/src/app/map/models/geojson.model.ts
@@ -0,0 +1,13 @@
+import { AddressGeometry } from './addressGeometry.model';
+
+export class GeoJson {
+  public geometry: AddressGeometry;
+  public type: string;
+  public properties: object;
+
+  constructor(obj?: any) {
+    Object.assign(this, obj, {
+      geometry: obj && obj.geometry ? new AddressGeometry(obj.geometry) : null,
+    });
+  }
+}
diff --git a/src/app/map/models/map-options.ts b/src/app/map/models/map-options.ts
deleted file mode 100644
index e69de29bb..000000000
diff --git a/src/app/map/services/geojson.service.spec.ts b/src/app/map/services/geojson.service.spec.ts
new file mode 100644
index 000000000..0d9d5d0c6
--- /dev/null
+++ b/src/app/map/services/geojson.service.spec.ts
@@ -0,0 +1,31 @@
+import { TestBed } from '@angular/core/testing';
+import { Address } from '../models/address.model';
+
+import { GeojsonService } from './geojson.service';
+
+describe('GeojsonService', () => {
+  let service: GeojsonService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(GeojsonService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+
+  it('should get address for id 26061 ', () => {
+    service.getAddress(26061).subscribe((val) => {
+      expect(val.zipcode).toEqual('69800');
+      expect(val.text).toEqual('13ème Rue Cité Berliet');
+    });
+  });
+
+  it('should get coord with query string avenue foch 69006 ', () => {
+    service.getCoord(new Address({ text: 'avenue foch', citycode: '69006' })).subscribe((val) => {
+      expect(val.geometry.getLat()).toEqual(4.8429024);
+      expect(val.geometry.getLon()).toEqual(45.7733884);
+    });
+  });
+});
diff --git a/src/app/map/services/geojson.service.ts b/src/app/map/services/geojson.service.ts
new file mode 100644
index 000000000..7af9e3481
--- /dev/null
+++ b/src/app/map/services/geojson.service.ts
@@ -0,0 +1,33 @@
+import { HttpClient, HttpHeaders } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+import { Observable } from 'rxjs';
+import { map } from 'rxjs/operators';
+import { Address } from '../models/address.model';
+import { GeoJson } from '../models/geojson.model';
+
+@Injectable({
+  providedIn: 'root',
+})
+export class GeojsonService {
+  constructor(private http: HttpClient) {}
+
+  /**
+   * Retrive an address with a street national reference
+   * @param idVoie Number
+   */
+  public getAddress(idVoie: number): Observable<Address> {
+    return this.http
+      .get('/base-adresse/base-adresse-nationale/streets' + '?id=' + idVoie)
+      .pipe(map((data: { data: any[]; err: number }) => new Address(data.data[0])));
+  }
+
+  /**
+   * Get GeoLocation with an address
+   * @param address Address
+   */
+  public getCoord(address: Address): Observable<GeoJson> {
+    return this.http
+      .get('/geocoding/photon/api' + '?q=' + address.queryString())
+      .pipe(map((data: { features: any[]; type: string }) => new GeoJson(data.features[0])));
+  }
+}
diff --git a/src/app/map/services/map.service.ts b/src/app/map/services/map.service.ts
index eb5eb8d4f..77296375a 100644
--- a/src/app/map/services/map.service.ts
+++ b/src/app/map/services/map.service.ts
@@ -21,6 +21,9 @@ export class MapService {
       marker.bindTooltip(tooltip);
     }
     this.markersList[id] = marker;
+    console.log('marker lat', lat);
+    console.log('marker lon', lon);
+    console.log('marker', marker);
     return marker;
   }
 
diff --git a/src/app/structure-list/models/day.model.ts b/src/app/models/day.model.ts
similarity index 100%
rename from src/app/structure-list/models/day.model.ts
rename to src/app/models/day.model.ts
diff --git a/src/app/structure-list/models/openingDay.model.ts b/src/app/models/openingDay.model.ts
similarity index 100%
rename from src/app/structure-list/models/openingDay.model.ts
rename to src/app/models/openingDay.model.ts
diff --git a/src/app/structure-list/models/structure.model.ts b/src/app/models/structure.model.ts
similarity index 76%
rename from src/app/structure-list/models/structure.model.ts
rename to src/app/models/structure.model.ts
index 92ceb326d..cd65a8ead 100644
--- a/src/app/structure-list/models/structure.model.ts
+++ b/src/app/models/structure.model.ts
@@ -1,6 +1,7 @@
+import { TranslateService } from '@ngx-translate/core';
+import { Weekday } from '../structure-list/enum/weekday.enum';
 import { Day } from './day.model';
 import { OpeningDay } from './openingDay.model';
-import { Weekday } from '../enum/weekday.enum';
 import { Week } from './week.model';
 
 export class Structure {
@@ -13,7 +14,7 @@ export class Structure {
   public typeDeStructure: string;
   public description: string;
   public n: string;
-  public voie: string;
+  public voie: number;
   public telephone: string;
   public courriel: string;
   public siteWeb: string;
@@ -32,7 +33,7 @@ export class Structure {
   public isOpen: boolean;
   public openedOn: OpeningDay;
 
-  constructor(obj?: any) {
+  constructor(obj?: any, private translateService: TranslateService) {
     Object.assign(this, obj, {
       hours: obj && obj.hours ? new Week(obj.hours) : null,
     });
@@ -58,4 +59,14 @@ export class Structure {
         return null;
     }
   }
+
+  public openDisplay(): string {
+    if (this.isOpen) {
+      return 'Ouvert actuellement ';
+    } else if (this.openedOn.day) {
+      return 'Fermé - Ouvre ' + this.openedOn.day + ' à ' + this.openedOn.schedule;
+    } else {
+      return 'Fermé - Aucun horaire disponible ';
+    }
+  }
 }
diff --git a/src/app/structure-list/models/time.model.ts b/src/app/models/time.model.ts
similarity index 100%
rename from src/app/structure-list/models/time.model.ts
rename to src/app/models/time.model.ts
diff --git a/src/app/structure-list/models/week.model.ts b/src/app/models/week.model.ts
similarity index 100%
rename from src/app/structure-list/models/week.model.ts
rename to src/app/models/week.model.ts
diff --git a/src/app/structure-list/services/structure-list.service.spec.ts b/src/app/services/structure-list.service.spec.ts
similarity index 100%
rename from src/app/structure-list/services/structure-list.service.spec.ts
rename to src/app/services/structure-list.service.spec.ts
diff --git a/src/app/structure-list/services/structure-list.service.ts b/src/app/services/structure-list.service.ts
similarity index 97%
rename from src/app/structure-list/services/structure-list.service.ts
rename to src/app/services/structure-list.service.ts
index 9394b38c1..82d06039c 100644
--- a/src/app/structure-list/services/structure-list.service.ts
+++ b/src/app/services/structure-list.service.ts
@@ -1,16 +1,14 @@
 import { HttpClient } from '@angular/common/http';
 import { Injectable } from '@angular/core';
+import { WeekDay } from '@angular/common';
 import { Observable } from 'rxjs';
 import { map } from 'rxjs/operators';
-const { DateTime } = require('luxon');
 
+import { Structure } from '../models/structure.model';
 import { Day } from '../models/day.model';
 import { OpeningDay } from '../models/openingDay.model';
-import { Structure } from '../models/structure.model';
+import { Weekday } from '../structure-list/enum/weekday.enum';
 import { Time } from '../models/time.model';
-import { Weekday } from '../enum/weekday.enum';
-import { Week } from '../models/week.model';
-import { WeekDay } from '@angular/common';
 
 @Injectable({
   providedIn: 'root',
diff --git a/src/app/shared/components/card/card.component.html b/src/app/shared/components/card/card.component.html
deleted file mode 100644
index f2fda252a..000000000
--- a/src/app/shared/components/card/card.component.html
+++ /dev/null
@@ -1 +0,0 @@
-<p>card works!</p>
diff --git a/src/app/shared/components/card/card.component.scss b/src/app/shared/components/card/card.component.scss
deleted file mode 100644
index e69de29bb..000000000
diff --git a/src/app/shared/components/card/card.component.spec.ts b/src/app/shared/components/card/card.component.spec.ts
deleted file mode 100644
index 3093fd5a3..000000000
--- a/src/app/shared/components/card/card.component.spec.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { CardComponent } from './card.component';
-
-describe('CardComponent', () => {
-  let component: CardComponent;
-  let fixture: ComponentFixture<CardComponent>;
-
-  beforeEach(async () => {
-    await TestBed.configureTestingModule({
-      declarations: [ CardComponent ]
-    })
-    .compileComponents();
-  });
-
-  beforeEach(() => {
-    fixture = TestBed.createComponent(CardComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});
diff --git a/src/app/shared/components/card/card.component.ts b/src/app/shared/components/card/card.component.ts
deleted file mode 100644
index 07a9ab07e..000000000
--- a/src/app/shared/components/card/card.component.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { Component, OnInit } from '@angular/core';
-
-@Component({
-  selector: 'app-card',
-  templateUrl: './card.component.html',
-  styleUrls: ['./card.component.scss']
-})
-export class CardComponent implements OnInit {
-
-  constructor() { }
-
-  ngOnInit(): void {
-  }
-
-}
diff --git a/src/app/shared/components/index.ts b/src/app/shared/components/index.ts
index d8ec6de94..b86c35354 100644
--- a/src/app/shared/components/index.ts
+++ b/src/app/shared/components/index.ts
@@ -1,7 +1,7 @@
-import { CardComponent } from './card/card.component';
+// import { CardComponent } from './card/card.component';
 
 // tslint:disable-next-line: max-line-length
-export { CardComponent };
+// export { CardComponent };
 
 // tslint:disable-next-line:variable-name
-export const SharedComponents = [CardComponent];
+export const SharedComponents = [];
diff --git a/src/app/structure-list/components/card/card.component.html b/src/app/structure-list/components/card/card.component.html
index 490d59af8..b8d0c1dc5 100644
--- a/src/app/structure-list/components/card/card.component.html
+++ b/src/app/structure-list/components/card/card.component.html
@@ -1,6 +1,5 @@
-<span class="nbStructuresLabel">{{ structures.length }} structures</span>
-<div class="structure" fxLayout="column" *ngFor="let structure of structures">
-  <span class="nomStructure">{{ structure.nom }}</span>
+<div class="structure" fxLayout="column">
+  <span class="nomStructure">{{ structure.nomDeVotreStructure }}</span>
 
   <div class="headerStructure" fxLayout="row" fxLayoutAlign="space-between center">
     <span class="typeStructure">{{ structure.typeDeStructure }}</span>
@@ -8,18 +7,12 @@
   </div>
   <br />
   <div class="statusStructure" fxLayout="row" fxLayoutAlign="start center">
-    <div *ngIf="structure.isOpen; else closed">
-      <span class="ico-dot-available"></span>
-      <span>Ouvert actuellement</span>
+    <div>
+      <span *ngIf="structure.isOpen; else closed" class="ico-dot-available"></span>
+      <span>{{ structure.openDisplay() }}</span>
     </div>
     <ng-template #closed>
       <span class="ico-dot-unavailable"></span>
-      <span *ngIf="structure.openedOn.day; else noTime">
-        Fermé - Ouvre {{ structure.openedOn.day }} à {{ structure.openedOn.schedule }}</span
-      >
-    </ng-template>
-    <ng-template #noTime>
-      <span> Fermé - Aucun horaire disponible</span>
     </ng-template>
   </div>
 </div>
diff --git a/src/app/structure-list/components/card/card.component.scss b/src/app/structure-list/components/card/card.component.scss
index 732c84c03..3fe9e2edd 100644
--- a/src/app/structure-list/components/card/card.component.scss
+++ b/src/app/structure-list/components/card/card.component.scss
@@ -2,15 +2,9 @@
 @import '../../../../assets/scss/color';
 @import '../../../../assets/scss/typography';
 
-.nbStructuresLabel {
-  color: $grey;
-  @include cn-regular-16;
-  display: flex;
-  align-items: center;
-}
 .structure {
   padding: 12px 0 12px 0;
-  border-bottom: 1px dashed $grey;
+  border-bottom: 1px dashed $grey !important;
   .typeStructure {
     color: $grey;
     @include cn-regular-16;
diff --git a/src/app/structure-list/components/card/card.component.ts b/src/app/structure-list/components/card/card.component.ts
index 5594b507f..9049bcfa7 100644
--- a/src/app/structure-list/components/card/card.component.ts
+++ b/src/app/structure-list/components/card/card.component.ts
@@ -1,7 +1,5 @@
-import { Component, OnInit } from '@angular/core';
-import { Structure } from '../../models/structure.model';
-import { StructureService } from '../../services/structure-list.service';
-const { DateTime } = require('luxon');
+import { Component, Input, OnInit } from '@angular/core';
+import { Structure } from '../../../models/structure.model';
 
 @Component({
   selector: 'app-card',
@@ -9,14 +7,8 @@ const { DateTime } = require('luxon');
   styleUrls: ['./card.component.scss'],
 })
 export class CardComponent implements OnInit {
-  structures: Structure[] = [];
-  constructor(private structureService: StructureService) {}
+  @Input() public structure: Structure;
+  constructor() {}
 
-  ngOnInit(): void {
-    this.structureService.getStructures().subscribe((structures) => {
-      structures.forEach((s: Structure) => {
-        this.structures.push(this.structureService.updateOpeningStructure(s, DateTime.local()));
-      });
-    });
-  }
+  ngOnInit(): void {}
 }
diff --git a/src/app/structure-list/structure-list.component.html b/src/app/structure-list/structure-list.component.html
index a6dbe19b7..017b98518 100644
--- a/src/app/structure-list/structure-list.component.html
+++ b/src/app/structure-list/structure-list.component.html
@@ -1,2 +1,3 @@
 <app-recherche></app-recherche>
-<app-card></app-card>
+<span class="nbStructuresLabel">{{ structureList.length }} structures</span>
+<app-card *ngFor="let structure of structureList" [structure]="structure"></app-card>
diff --git a/src/app/structure-list/structure-list.component.ts b/src/app/structure-list/structure-list.component.ts
index 276b325e4..37296692d 100644
--- a/src/app/structure-list/structure-list.component.ts
+++ b/src/app/structure-list/structure-list.component.ts
@@ -1,10 +1,13 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, Input, OnInit } from '@angular/core';
+import { Structure } from '../models/structure.model';
 
 @Component({
   selector: 'app-structure-list',
   templateUrl: './structure-list.component.html',
+  styleUrls: ['./structure-list.scss'],
 })
 export class StructureListComponent implements OnInit {
+  @Input() public structureList: Structure[];
   constructor() {}
 
   ngOnInit(): void {}
diff --git a/src/app/structure-list/structure-list.module.ts b/src/app/structure-list/structure-list.module.ts
deleted file mode 100644
index 7067e0fef..000000000
--- a/src/app/structure-list/structure-list.module.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { NgModule } from '@angular/core';
-import { CommonModule } from '@angular/common';
-import { StructureListComponent } from './structure-list.component';
-import { CardComponent } from './components/card/card.component';
-import { RechercheComponent } from './components/recherche/recherche.component';
-import { HttpClientModule } from '@angular/common/http';
-import { FlexLayoutModule } from '@angular/flex-layout';
-
-@NgModule({
-  declarations: [StructureListComponent, CardComponent, RechercheComponent],
-  imports: [CommonModule, HttpClientModule, FlexLayoutModule],
-  exports: [StructureListComponent],
-})
-export class StructureListModule {}
diff --git a/src/app/structure-list/structure-list.scss b/src/app/structure-list/structure-list.scss
new file mode 100644
index 000000000..68c10dffe
--- /dev/null
+++ b/src/app/structure-list/structure-list.scss
@@ -0,0 +1,10 @@
+@import '../../assets/scss/icons';
+@import '../../assets/scss/color';
+@import '../../assets/scss/typography';
+
+.nbStructuresLabel {
+  color: $grey;
+  @include cn-regular-16;
+  display: flex;
+  align-items: center;
+}
diff --git a/src/environments/environment.ts b/src/environments/environment.ts
index 79b25c900..9ad8ed69b 100644
--- a/src/environments/environment.ts
+++ b/src/environments/environment.ts
@@ -5,6 +5,8 @@
 export const environment = {
   production: false,
   registrationForm: 'https://services.formulaireextranet.grandlyon.com/saisie-fiche-structure',
+  addressApi: 'https://passerelle.formulaireextranet.grandlyon.com/base-adresse/base-adresse-nationale/streets',
+  geojsonApi: 'https://download.data.grandlyon.com/geocoding/photon/api',
   VERSION: require('../../package.json').version,
 };
 
-- 
GitLab


From 7e53d3b9cc375036f47a0f3d7de137947fcaa65d Mon Sep 17 00:00:00 2001
From: Hugo SUBTIL <ext.sopra.husubtil@grandlyon.com>
Date: Wed, 21 Oct 2020 10:10:54 +0200
Subject: [PATCH 06/10] fix: unit testing and remove console.log

---
 src/app/home/home.component.spec.ts           |   8 +-
 src/app/map/services/geojson.service.spec.ts  |  43 ++++-
 src/app/map/services/map.service.ts           |   3 -
 src/app/models/structure.model.ts             |   3 +-
 .../components/card/card.component.spec.ts    | 151 ++++++++++++++++-
 .../structure-list.component.spec.ts          | 156 +++++++++++++++++-
 src/locale/messages.en.xlf                    |   4 +
 7 files changed, 347 insertions(+), 21 deletions(-)

diff --git a/src/app/home/home.component.spec.ts b/src/app/home/home.component.spec.ts
index 2c5a17268..8c0ce9e12 100644
--- a/src/app/home/home.component.spec.ts
+++ b/src/app/home/home.component.spec.ts
@@ -1,3 +1,5 @@
+import { HttpClientModule } from '@angular/common/http';
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 
 import { HomeComponent } from './home.component';
@@ -8,9 +10,9 @@ describe('HomeComponent', () => {
 
   beforeEach(async () => {
     await TestBed.configureTestingModule({
-      declarations: [ HomeComponent ]
-    })
-    .compileComponents();
+      declarations: [HomeComponent],
+      imports: [HttpClientTestingModule],
+    }).compileComponents();
   });
 
   beforeEach(() => {
diff --git a/src/app/map/services/geojson.service.spec.ts b/src/app/map/services/geojson.service.spec.ts
index 0d9d5d0c6..f25dadf4e 100644
--- a/src/app/map/services/geojson.service.spec.ts
+++ b/src/app/map/services/geojson.service.spec.ts
@@ -1,11 +1,19 @@
 import { TestBed } from '@angular/core/testing';
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
 import { Address } from '../models/address.model';
 
 import { GeojsonService } from './geojson.service';
+import { HttpClientModule } from '@angular/common/http';
 
 describe('GeojsonService', () => {
   let service: GeojsonService;
 
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [HttpClientModule],
+    }).compileComponents();
+  });
+
   beforeEach(() => {
     TestBed.configureTestingModule({});
     service = TestBed.inject(GeojsonService);
@@ -15,17 +23,36 @@ describe('GeojsonService', () => {
     expect(service).toBeTruthy();
   });
 
-  it('should get address for id 26061 ', () => {
-    service.getAddress(26061).subscribe((val) => {
-      expect(val.zipcode).toEqual('69800');
-      expect(val.text).toEqual('13ème Rue Cité Berliet');
+  it('should get address for id 26061 ', async () => {
+    await new Promise((resolve) => {
+      service.getAddress(26061).subscribe(
+        (val) => {
+          console.log(val);
+          expect(val.zipcode).toEqual('69800');
+          expect(val.text).toEqual('13ème Rue Cité Berliet');
+          resolve();
+        },
+        (err) => {
+          console.log(err);
+          resolve();
+        }
+      );
     });
   });
 
-  it('should get coord with query string avenue foch 69006 ', () => {
-    service.getCoord(new Address({ text: 'avenue foch', citycode: '69006' })).subscribe((val) => {
-      expect(val.geometry.getLat()).toEqual(4.8429024);
-      expect(val.geometry.getLon()).toEqual(45.7733884);
+  it('should get coord with query string avenue foch 69006 ', async () => {
+    await new Promise((resolve) => {
+      service.getCoord(new Address({ text: 'avenue foch', citycode: '69006' })).subscribe(
+        (val) => {
+          expect(val.geometry.getLat()).toEqual(4.8429024);
+          expect(val.geometry.getLon()).toEqual(45.7733884);
+          resolve();
+        },
+        (err) => {
+          console.log(err);
+          resolve();
+        }
+      );
     });
   });
 });
diff --git a/src/app/map/services/map.service.ts b/src/app/map/services/map.service.ts
index 77296375a..eb5eb8d4f 100644
--- a/src/app/map/services/map.service.ts
+++ b/src/app/map/services/map.service.ts
@@ -21,9 +21,6 @@ export class MapService {
       marker.bindTooltip(tooltip);
     }
     this.markersList[id] = marker;
-    console.log('marker lat', lat);
-    console.log('marker lon', lon);
-    console.log('marker', marker);
     return marker;
   }
 
diff --git a/src/app/models/structure.model.ts b/src/app/models/structure.model.ts
index cd65a8ead..191917321 100644
--- a/src/app/models/structure.model.ts
+++ b/src/app/models/structure.model.ts
@@ -1,4 +1,3 @@
-import { TranslateService } from '@ngx-translate/core';
 import { Weekday } from '../structure-list/enum/weekday.enum';
 import { Day } from './day.model';
 import { OpeningDay } from './openingDay.model';
@@ -33,7 +32,7 @@ export class Structure {
   public isOpen: boolean;
   public openedOn: OpeningDay;
 
-  constructor(obj?: any, private translateService: TranslateService) {
+  constructor(obj?: any) {
     Object.assign(this, obj, {
       hours: obj && obj.hours ? new Week(obj.hours) : null,
     });
diff --git a/src/app/structure-list/components/card/card.component.spec.ts b/src/app/structure-list/components/card/card.component.spec.ts
index c0787da7b..cf8f87ef3 100644
--- a/src/app/structure-list/components/card/card.component.spec.ts
+++ b/src/app/structure-list/components/card/card.component.spec.ts
@@ -2,6 +2,9 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 
 import { CardComponent } from './card.component';
 import { HttpClientModule } from '@angular/common/http';
+import { Structure } from '../../../models/structure.model';
+import { OpeningDay } from '../../../models/openingDay.model';
+
 describe('CardComponent', () => {
   let component: CardComponent;
   let fixture: ComponentFixture<CardComponent>;
@@ -15,8 +18,152 @@ describe('CardComponent', () => {
 
   beforeEach(() => {
     fixture = TestBed.createComponent(CardComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
+    component = fixture.debugElement.componentInstance;
+    const structure = new Structure({
+      id: 1,
+      numero: '26-63',
+      dateDeCreation: '2020-10-08T15:17:00.000Z',
+      derniereModification: '2020-10-08T15:17:00.000Z',
+      nomDeLusager: 'Erwan Le luron',
+      votreStructureEstElle: 'Un établissement principal (siège social)',
+      nomDeVotreStructure: 'Régie de Quartier Armstrong',
+      typeDeStructure: 'Tiers-lieu & coworking, FabLab',
+      description: "Association loi 1901 dont l'objet est l'insertion par l'économie social et solidaire",
+      n: 2,
+      voie: 21356,
+      telephone: '04 72 21 03 07',
+      courriel: 'sguillet@rqa.fr',
+      siteWeb: '',
+      facebook: '',
+      twitter: '@rqainfo69',
+      instagram: '',
+      civilite: 'Madame',
+      nom: 'GUILLET',
+      prenom: 'Séverine',
+      fonction: 'Autres',
+      accessibilitePersonnesAMobiliteReduitePmr: '',
+      choixMultiples: 'Tout public',
+      fermeturesExceptionnelles: '',
+      jaccompagneLesUsagersDansLeursDemarchesEnLigne: 'True',
+      accompagnementDesDemarches: 'Accompagnant CAF',
+      autresAccompagnements: '',
+      lesCompetencesDeBase: 260,
+      accesAuxDroits: 176,
+      insertionSocialeEtProfessionnelle: 254,
+      aideALaParentalite: '',
+      cultureEtSecuriteNumerique: 264,
+      wifiEnAccesLibre: 'True',
+      ordinateurs: '',
+      nombre: '',
+      tablettes: '',
+      bornesNumeriques: '',
+      imprimantes: '',
+      autresEspacesProposesParLaStructure: 'Espace libre service',
+      statutJuridique: '',
+      appartenezVousAUnReseauDeMediation: '',
+      precisezLequel: '',
+      idDeLitemStructureDansDirectus: 123,
+      statutDeLitemStructureDansDirectus: '',
+      idDeLitemOffreDansDirectus: '',
+      statut: 'Erreur lors du versement des données offre',
+      hours: {
+        monday: {
+          open: true,
+          time: [
+            {
+              openning: 1330,
+              closing: 1630,
+            },
+            {
+              openning: null,
+              closing: null,
+            },
+          ],
+        },
+        tuesday: {
+          open: true,
+          time: [
+            {
+              openning: 830,
+              closing: 1130,
+            },
+            {
+              openning: 1330,
+              closing: 1630,
+            },
+          ],
+        },
+        wednesday: {
+          open: true,
+          time: [
+            {
+              openning: 1330,
+              closing: 1630,
+            },
+            {
+              openning: null,
+              closing: null,
+            },
+          ],
+        },
+        thursday: {
+          open: true,
+          time: [
+            {
+              openning: 830,
+              closing: 1130,
+            },
+            {
+              openning: 1330,
+              closing: 1630,
+            },
+          ],
+        },
+        friday: {
+          open: true,
+          time: [
+            {
+              openning: 830,
+              closing: 1130,
+            },
+            {
+              openning: 1330,
+              closing: 1530,
+            },
+          ],
+        },
+        saturday: {
+          open: false,
+          time: [
+            {
+              openning: null,
+              closing: null,
+            },
+            {
+              openning: null,
+              closing: null,
+            },
+          ],
+        },
+        sunday: {
+          open: false,
+          time: [
+            {
+              openning: null,
+              closing: null,
+            },
+            {
+              openning: null,
+              closing: null,
+            },
+          ],
+        },
+        openedOn: new OpeningDay('monday', null),
+      },
+      openedOn: new OpeningDay('monday', null),
+    });
+    component.structure = structure;
+    fixture.detectChanges(); // calls NgOnit
   });
 
   it('should create', () => {
diff --git a/src/app/structure-list/structure-list.component.spec.ts b/src/app/structure-list/structure-list.component.spec.ts
index bbd876b55..b00f05ee5 100644
--- a/src/app/structure-list/structure-list.component.spec.ts
+++ b/src/app/structure-list/structure-list.component.spec.ts
@@ -1,8 +1,11 @@
 import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { StyleUtils } from '@angular/flex-layout';
+import { OpeningDay } from '../models/openingDay.model';
+import { Structure } from '../models/structure.model';
 
 import { StructureListComponent } from './structure-list.component';
 
-describe('StructureComponent', () => {
+describe('StructureListComponent', () => {
   let component: StructureListComponent;
   let fixture: ComponentFixture<StructureListComponent>;
 
@@ -14,8 +17,155 @@ describe('StructureComponent', () => {
 
   beforeEach(() => {
     fixture = TestBed.createComponent(StructureListComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
+    component = fixture.debugElement.componentInstance;
+    const structureList = new Array<Structure>(
+      new Structure({
+        id: 1,
+        numero: '26-63',
+        dateDeCreation: '2020-10-08T15:17:00.000Z',
+        derniereModification: '2020-10-08T15:17:00.000Z',
+        nomDeLusager: 'Erwan Le luron',
+        votreStructureEstElle: 'Un établissement principal (siège social)',
+        nomDeVotreStructure: 'Régie de Quartier Armstrong',
+        typeDeStructure: 'Tiers-lieu & coworking, FabLab',
+        description: "Association loi 1901 dont l'objet est l'insertion par l'économie social et solidaire",
+        n: 2,
+        voie: 21356,
+        telephone: '04 72 21 03 07',
+        courriel: 'sguillet@rqa.fr',
+        siteWeb: '',
+        facebook: '',
+        twitter: '@rqainfo69',
+        instagram: '',
+        civilite: 'Madame',
+        nom: 'GUILLET',
+        prenom: 'Séverine',
+        fonction: 'Autres',
+        accessibilitePersonnesAMobiliteReduitePmr: '',
+        choixMultiples: 'Tout public',
+        fermeturesExceptionnelles: '',
+        jaccompagneLesUsagersDansLeursDemarchesEnLigne: 'True',
+        accompagnementDesDemarches: 'Accompagnant CAF',
+        autresAccompagnements: '',
+        lesCompetencesDeBase: 260,
+        accesAuxDroits: 176,
+        insertionSocialeEtProfessionnelle: 254,
+        aideALaParentalite: '',
+        cultureEtSecuriteNumerique: 264,
+        wifiEnAccesLibre: 'True',
+        ordinateurs: '',
+        nombre: '',
+        tablettes: '',
+        bornesNumeriques: '',
+        imprimantes: '',
+        autresEspacesProposesParLaStructure: 'Espace libre service',
+        statutJuridique: '',
+        appartenezVousAUnReseauDeMediation: '',
+        precisezLequel: '',
+        idDeLitemStructureDansDirectus: 123,
+        statutDeLitemStructureDansDirectus: '',
+        idDeLitemOffreDansDirectus: '',
+        statut: 'Erreur lors du versement des données offre',
+        hours: {
+          monday: {
+            open: true,
+            time: [
+              {
+                openning: 1330,
+                closing: 1630,
+              },
+              {
+                openning: null,
+                closing: null,
+              },
+            ],
+          },
+          tuesday: {
+            open: true,
+            time: [
+              {
+                openning: 830,
+                closing: 1130,
+              },
+              {
+                openning: 1330,
+                closing: 1630,
+              },
+            ],
+          },
+          wednesday: {
+            open: true,
+            time: [
+              {
+                openning: 1330,
+                closing: 1630,
+              },
+              {
+                openning: null,
+                closing: null,
+              },
+            ],
+          },
+          thursday: {
+            open: true,
+            time: [
+              {
+                openning: 830,
+                closing: 1130,
+              },
+              {
+                openning: 1330,
+                closing: 1630,
+              },
+            ],
+          },
+          friday: {
+            open: true,
+            time: [
+              {
+                openning: 830,
+                closing: 1130,
+              },
+              {
+                openning: 1330,
+                closing: 1530,
+              },
+            ],
+          },
+          saturday: {
+            open: false,
+            time: [
+              {
+                openning: null,
+                closing: null,
+              },
+              {
+                openning: null,
+                closing: null,
+              },
+            ],
+          },
+          sunday: {
+            open: false,
+            time: [
+              {
+                openning: null,
+                closing: null,
+              },
+              {
+                openning: null,
+                closing: null,
+              },
+            ],
+          },
+        },
+        openedOn: new OpeningDay('monday', null),
+      })
+    );
+    structureList.length = 4;
+    console.log(structureList.length);
+    component.structureList = structureList;
+    fixture.detectChanges(); // calls NgOnit
   });
 
   it('should create', () => {
diff --git a/src/locale/messages.en.xlf b/src/locale/messages.en.xlf
index 0a4b401a0..c5c8d8d50 100644
--- a/src/locale/messages.en.xlf
+++ b/src/locale/messages.en.xlf
@@ -58,6 +58,10 @@
           <context context-type="linenumber">18</context>
         </context-group>
       </trans-unit>
+      <trans-unit id="monday" datatype="html">
+        <source>monday</source>
+        <target>lundi</target>
+      </trans-unit>
     </body>
   </file>
 </xliff>
-- 
GitLab


From 47665178a6dc089131c593d5fbd25e4b7bdd9d91 Mon Sep 17 00:00:00 2001
From: Hugo SUBTIL <ext.sopra.husubtil@grandlyon.com>
Date: Wed, 21 Oct 2020 12:42:29 +0200
Subject: [PATCH 07/10] fix: remove console log, better home css display

---
 src/app/home/home.component.html             | 4 ++--
 src/app/home/home.component.scss             | 2 ++
 src/app/map/services/geojson.service.spec.ts | 2 --
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/app/home/home.component.html b/src/app/home/home.component.html
index 68c653d8b..6016ec21f 100644
--- a/src/app/home/home.component.html
+++ b/src/app/home/home.component.html
@@ -1,4 +1,4 @@
 <div fxLayout="row">
-  <app-structure-list [structureList]="structures" class="left-pane" fxFlex="30%"></app-structure-list>
-  <app-map fxFlex="70%" [structures]="structures"></app-map>
+  <app-structure-list [structureList]="structures" class="left-pane"></app-structure-list>
+  <app-map [structures]="structures" fxFlex="100"></app-map>
 </div>
diff --git a/src/app/home/home.component.scss b/src/app/home/home.component.scss
index 7d2eb86af..1a2d33f8e 100644
--- a/src/app/home/home.component.scss
+++ b/src/app/home/home.component.scss
@@ -1,3 +1,5 @@
 .left-pane {
   padding: 0 25px;
+  width: 590px;
+  min-width: 590px;
 }
diff --git a/src/app/map/services/geojson.service.spec.ts b/src/app/map/services/geojson.service.spec.ts
index f25dadf4e..359674551 100644
--- a/src/app/map/services/geojson.service.spec.ts
+++ b/src/app/map/services/geojson.service.spec.ts
@@ -1,5 +1,4 @@
 import { TestBed } from '@angular/core/testing';
-import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
 import { Address } from '../models/address.model';
 
 import { GeojsonService } from './geojson.service';
@@ -27,7 +26,6 @@ describe('GeojsonService', () => {
     await new Promise((resolve) => {
       service.getAddress(26061).subscribe(
         (val) => {
-          console.log(val);
           expect(val.zipcode).toEqual('69800');
           expect(val.text).toEqual('13ème Rue Cité Berliet');
           resolve();
-- 
GitLab


From a457cbbaa2745a9de3b5ac32d9822eee7482ce77 Mon Sep 17 00:00:00 2001
From: Jeremie BRISON <ext.sopra.jbrison@grandlyon.com>
Date: Wed, 21 Oct 2020 14:30:24 +0200
Subject: [PATCH 08/10] fix(map) : replace img with pure css

---
 src/app/map/services/map.service.ts | 15 ++++++++-------
 src/assets/scss/_icons.scss         | 22 ++++++++++++++++++++++
 src/styles.scss                     |  1 +
 3 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/src/app/map/services/map.service.ts b/src/app/map/services/map.service.ts
index eb5eb8d4f..f13895072 100644
--- a/src/app/map/services/map.service.ts
+++ b/src/app/map/services/map.service.ts
@@ -1,4 +1,5 @@
 import { Injectable } from '@angular/core';
+import { divIcon } from 'leaflet';
 import { icon, Marker, Map } from 'leaflet';
 
 @Injectable({
@@ -9,13 +10,13 @@ export class MapService {
   constructor() {}
 
   public createMarker(lat: number, lon: number, id: number, tooltip?: string): Marker {
-    const marker = new Marker([lat, lon]).setIcon(
-      icon({
-        iconSize: [35, 41],
-        iconAnchor: [13, 41],
-        iconUrl: '../../../assets/img/ic_marker.png',
-      })
-    );
+    const icone = divIcon({
+      className: null,
+      html: "<div class='ico-marker-pin'></div>",
+      iconSize: [35, 41],
+      iconAnchor: [13, 41],
+    });
+    const marker = new Marker([lat, lon], { icon: icone });
 
     if (tooltip) {
       marker.bindTooltip(tooltip);
diff --git a/src/assets/scss/_icons.scss b/src/assets/scss/_icons.scss
index de969d5b3..f907cb4d0 100644
--- a/src/assets/scss/_icons.scss
+++ b/src/assets/scss/_icons.scss
@@ -78,3 +78,25 @@
   border-radius: 50%;
   display: inline-block;
 }
+
+.ico-marker-pin {
+  width: 30px;
+  height: 30px;
+  border-radius: 50% 50% 50% 0;
+  background: $purple;
+  position: absolute;
+  transform: rotate(-45deg);
+  left: 50%;
+  top: 50%;
+  margin: -15px 0 0 -15px;
+}
+
+.ico-marker-pin::after {
+  content: '';
+  width: 10px;
+  height: 10px;
+  margin: 10px 0 0 10px;
+  background: #fff;
+  position: absolute;
+  border-radius: 50%;
+}
diff --git a/src/styles.scss b/src/styles.scss
index d62180f39..0a1dafb13 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -3,6 +3,7 @@
 @import 'assets/scss/typography';
 @import 'assets/scss/color';
 @import 'assets/scss/breakpoint';
+@import 'assets/scss/icons';
 @import '../node_modules/leaflet.locatecontrol/dist/L.Control.Locate.css';
 
 html,
-- 
GitLab


From d90c9ce885b97e31dc3d59dc95322639541385f6 Mon Sep 17 00:00:00 2001
From: Jeremie BRISON <ext.sopra.jbrison@grandlyon.com>
Date: Wed, 21 Oct 2020 14:37:00 +0200
Subject: [PATCH 09/10] fix(map) : set maxZoom to prevent bug

---
 src/app/map/components/map.component.ts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/app/map/components/map.component.ts b/src/app/map/components/map.component.ts
index e30ec0504..f63314cb9 100644
--- a/src/app/map/components/map.component.ts
+++ b/src/app/map/components/map.component.ts
@@ -121,6 +121,7 @@ export class MapComponent implements OnChanges {
     // Zoom is blocked on 11 to prevent people to zoom out from metropole
     this.mapOptions = {
       center: latLng(45.764043, 4.835659),
+      maxZoom: 19,
       zoom: 10,
       minZoom: 10,
       layers: [carteLayer, metroMaps],
-- 
GitLab


From 2f63c2c30ddfa02475bd9d5369f2aa4db4f260bf Mon Sep 17 00:00:00 2001
From: Jeremie BRISON <ext.sopra.jbrison@grandlyon.com>
Date: Wed, 21 Oct 2020 14:41:46 +0200
Subject: [PATCH 10/10] fix(map) : Delete png icon

---
 src/app/map/services/map.service.spec.ts |   2 --
 src/assets/img/ic_marker.png             | Bin 1274 -> 0 bytes
 2 files changed, 2 deletions(-)
 delete mode 100644 src/assets/img/ic_marker.png

diff --git a/src/app/map/services/map.service.spec.ts b/src/app/map/services/map.service.spec.ts
index 3470f88c5..de3b0e0fa 100644
--- a/src/app/map/services/map.service.spec.ts
+++ b/src/app/map/services/map.service.spec.ts
@@ -23,8 +23,6 @@ describe('MapService', () => {
   });
   it('should add marker to map with icon ic_marker.png', () => {
     const marker = service.createMarker(45.764043, 4.835659, 1);
-
-    expect(marker.getIcon().options.iconUrl).toEqual('../../../assets/img/ic_marker.png');
     expect(marker.getIcon().options.iconSize).toEqual([35, 41]);
     expect(marker.getIcon().options.iconAnchor).toEqual([13, 41]);
   });
diff --git a/src/assets/img/ic_marker.png b/src/assets/img/ic_marker.png
deleted file mode 100644
index f378d60ad21bd0bae4e7570e9b6cb9800fc8f0e9..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1274
zcmV<W1O@wvP)<h;3K|Lk000e1NJLTq001Wd001rs1^@s6tE>S100009a7bBm000XU
z000XU0RWnu7ytkO0drDELIAGL9O(c600d`2O+f$vv5yP<VFdsH1dmBXK~#7F&6z(;
z6hRcm-x4dZxPsG?#SWtJj2f-vjExo=2sT)#L=vnxr9_Aj1uGFc3lq`C%1CUqF&tJJ
zNq}IWk{e3?B+@{8zHfN58J0VCcDVz;<lW5P&h7qqGxO%n;86k<i^UWdt!!u6vTV5a
zttLurj%^yH=Xr{%DTd0jO%;>r6I*MX_jxXj0L8^q+VPUs((fhu_2U<<6jo?`b)7cW
zHiGu`C+aDEGEEJQ4RrDHMQS?TWIs-^wXrAXqTcI8K&1rg5w5qlw&}~~FWOLdRr*9)
z1Ge93*LBet+Ym!;Qd~F&^SPK}^OHiAQhP_cHj!exT5ddgQDEz9>-4<uIiakS;JyBl
ze&a<|4$#{V4CCtM@XG^xtCVW%YN@xcmzvKsmj(1fU>IYw2JBhiGpe@whx={7bM_dl
z3AM%G*IfyZ9fn3nM$M4%<^6#I&q)mWgnF(kSJ5#RC5*in<1chq(@yv1QL#Pu3LhUo
zd^}Vz2=7BA5Cz`TaN;%Hoq#(ESz#(GK|k<Z4j)Ou&>a^pU!az2EqZWUf!0|jmWs6Z
zj!Edq;$mrGiQ)(l-H*Dd`E>K1d*8o(k3B>HcjML#{IT#}swM#A&=KcBST`|<1q{<a
z&o&_?UAcBe-$y%F!Fy_1naftdWl)>>G2{FYcx+%~z|5{mwnm;|m}Q+Pan1G)_t7p+
zH_!YGI5L1kPDZMrTz{|EMgf~(n6~iZjY!XSAK+-$o$GdeG_5SJm}(2)eAG5pH=KTq
zm!Zo<LlMn8@qtMqe@vvT)GHOhxsEsgly9o}sO(len%96OCQT_>9DWVORDHVMRF&gT
zbU)P|ck`UB*l=6hTc(<E{E42fNmd=eDO6l%6k?%7@{GjDva(~SHPH7}!>J(jD8T8N
z<~m>jW`&)%5zX~_jezW$6V}z$?Sh*}O>!zHS&`rD#(eueuJJurTjQ?R=P#W%)p@|>
zLtjP;FB}~X@~|vhfnjC^6v=7<--p^c32U@y(v$4>FWlbK)f0PHg@A0uJuN(A`rEYj
zSe)mf_mCO05X2jGvMF7V#lw<jCQWCW0x;}jlk7XN>5+K&nBm3@T$YQeB;Ko(;QfcW
zho~x&&5n+9k{0JNV{dodro)yQ9-<+$^4LKb>)__~Ti5rDp=t|YW)I6?6XyE>PH6Q)
zez)sxtUT<XVB!qLcGbSOYx%+;<YHWJc%SqpO1I+(y<~Og<8UIeXKm#MIJC)!jtnX;
zcnduw!Z@1@w<)*qx3SGt3(%UG25hiYyZug?5S$VJGL<~cL05)6HdwB$%lVuJMC`-a
z2@VUBDs=p{FIXg;1v$aRJ=9;1zt&kswZWX>1aOdKvm1Ar!}zjdXQv&@Dgu`T5FrU*
zl4&4sY%_;66^9c*gc_Yhe*OHF-oJTI<-i7p2TW$G$nlW+KyU(>rJdul)Z)UTK4Y_!
z1=nNMs!6h4B$-9^M-_V>^b|X8cIa|#b<O<mp%AstI21qtaj3DuW{(W46riP9iIGPy
kfC$k41!g3GW0eH^2PkyRk|${KlmGw#07*qoM6N<$f^8vU!~g&Q

-- 
GitLab