-
Notifications
You must be signed in to change notification settings - Fork 0
/
course.es.html
611 lines (537 loc) · 30.5 KB
/
course.es.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="En este curso presencial de 2 dias, aprenderemos como hacer un microservicio en PHP, utilizando CQRS, ReactPHP y Docker">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="author" content="Marc Morera - PHP Coach">
<!-- The above 4 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<!-- Google Analytics -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-41917921-6', 'auto');
ga('send', 'pageview');
</script>
<!-- End Google Analytics -->
<!-- Main Style -->
<link rel="stylesheet" href="style.css">
<link rel="icon" href="favicon.ico" type="image/x-icon" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.10.2/css/all.min.css">
<!-- HTML Meta Tags -->
<title>PHP Coach Course - Event-Driven en PHP</title>
<meta name="description" content="En este curso aprenderás como hacer un servicio en PHP, utilizando Eventos de dominio, CQRS, ReactPHP y Docker">
<!-- Google / Search Engine Tags -->
<meta itemprop="name" content="Curso PHP Coach - Event-Driven en PHP">
<meta itemprop="description" content="En este curso aprenderás como hacer un servicio en PHP, utilizando Eventos de dominio, CQRS, ReactPHP y Docker">
<meta itemprop="image" content="http://php.coach/img/event-driven-in-php.png">
<!-- Facebook Meta Tags -->
<meta property="og:url" content="https://php.coach/course.es.html">
<meta property="og:type" content="website">
<meta property="og:title" content="Curso PHP Coach - Event-Driven en PHP">
<meta property="og:description" content="En este curso aprenderás como hacer un servicio en PHP, utilizando Eventos de dominio, CQRS, ReactPHP y Docker">
<meta property="og:image" content="http://php.coach/img/event-driven-in-php.png">
<!-- Twitter Meta Tags -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Curso PHP Coach - Event-Driven en PHP">
<meta name="twitter:description" content="En este curso aprenderás como hacer un servicio en PHP, utilizando Eventos de dominio, CQRS, ReactPHP y Docker">
<meta name="twitter:image" content="http://php.coach/img/event-driven-in-php.png">
<style>
.service-content-area:hover a {
color: #e1b12c;
font-weight: bold;
}
.point-zone ul li, .point-zone ul li:hover {
list-style: inherit;
line-height: 32px;
color: #717273;
font-size: 16px;
}
.point-zone ul {
margin-left: 30px;
}
</style>
</head>
<body>
<!-- Preloader -->
<div id="preloader">
<div class="loader"></div>
</div>
<div class="progress-container">
<div class="progress-bar" id="scrollIndicator"></div>
</div>
<!-- ***** Header Area Start ***** -->
<header class="header-area">
<!-- Logo -->
<a href="/" class="nav-brand"><img src="img/logo.png" alt="PHP Coach logo"></a>
<!-- Menu -->
<div class="dornee-menu pl-5">
<nav class="dorneenav">
<ul id="nav">
<li><a href="#requisites"><span class="fa fa-exclamation-triangle"></span> Requisitos</a></li>
<li><a href="#skeleton"><span class="fa fa-skull"></span> Estructura</a></li>
<li><a href="#docker-basics"><span class="fab fa-docker"></span> Básicos en Docker</a></li>
<li><a href="#reactphp-fundamentals"><span class="fa fa-server"></span> Fundamentos de ReactPHP</a></li>
<li><a href="#domain-definition"><span class="fa fa-project-diagram"></span> Definición del Dominio</a></li>
<li><a href="#io-dependencies"><span class="fa fa-layer-group"></span> Dependencias de I/O</a></li>
<li><a href="#turning-event-driven"><span class="fa fa-cogs"></span> Eventos de Dominio</a></li>
<li><a href="/"><span class="fa fa-step-backward"></span> Principal</a></li>
</ul>
</nav>
</div>
<!-- Menu HideShow -->
<div class="menu-hideshow">
<div class="hamburger" id="ham">
<span class="a"></span>
<span class="b"></span>
</div>
</div>
<!-- Contact Me -->
<a href="/#contact" class="contact-me-btn btn dornee-btn" id="contactMebtn">Reserva ya!</a>
</header>
<!-- ***** Header Area End ***** -->
<div class="page-content">
<section class="point-zone bg-gray clearfix pb-5 pt-5" id="requisites">
<div class="container">
<div class="row">
<div class="col-12">
<!-- Section Title -->
<div class="section-title text-center wow fadeInUp" data-wow-delay="300ms">
<h2>Requisitos</h2>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<p>
Para que puedas realizar este curso, sería importante que
tuvieras en cuenta algunos puntos. Todos ellos son
imprescindibles, dado que compartirás el curso con
más personas, y desde el primer segundo nos podremos
manos a la obra.
</p>
<p>
No importa el sistema operativo que lleves en tu ordenador,
pero asegúrate que sabes como instalar, utilizar y gestionar
las herramientas que aquí se detallan.
</p>
<p class="info-block">
Visita nuestras <a href="9-razones.html">9 razones para hacer el curso.</a>
</p>
<p class="info-block">
We have available some translations for this content - <a href="course.html">English version</a>
</p>
<ul>
<li><a href="https://git-scm.com/book/en/v2/Getting-Started-Installing-Git" target="_blank">Git instalado</a></li>
<li><a href="https://docs.docker.com/install/" target="_blank">Docker</a> instalado</li>
<li><a href="https://www.tutorialspoint.com/apache_bench/apache_bench_environment_setup.htm" target="_blank">Apache Benchmark</a> instalado - apache-tools</li>
<li>PHP 7.3 instalado (requerimiento mínimo). Si desarrollas con Docker, entonces no te preocupes por esto.</li>
</ul>
</div>
</div>
</div>
</section>
<!-- ***** Service Area End ***** -->
<!-- ***** Service Area Start ***** -->
<section class="my-service-area bg-gray section-padding-100-70 clearfix" id="course-agenda">
<div class="container">
<div class="row">
<div class="col-12">
<!-- Section Title -->
<div class="section-title text-center wow fadeInUp" data-wow-delay="300ms">
<h2>Agenda</h2>
</div>
</div>
</div>
<div class="row">
<!-- Service Content Area -->
<div class="col-12 col-sm-6 col-lg-4">
<a href="#skeleton">
<div class="service-content-area text-center mb-30 wow fadeInUp" data-wow-delay="300ms">
<!-- Icon -->
<div class="service-icon">
<i class="fa fa-skull"></i>
</div>
<!-- Content text -->
<div class="service-content-text">
<h4>Estructura del proyecto</h4>
<p>Principios básicos de DriftPHP, el framework PHP para trabajar con los componentes de ReactPHP y de Symfony.</p>
</div>
</div>
</a>
</div>
<!-- Service Content Area -->
<div class="col-12 col-sm-6 col-lg-4">
<a href="#docker-basics">
<div class="service-content-area text-center mb-30 wow fadeInUp" data-wow-delay="300ms">
<!-- Icon -->
<div class="service-icon">
<i class="fab fa-docker"></i>
</div>
<!-- Content text -->
<div class="service-content-text">
<h4>Basicos de Docker</h4>
<p>Aprenderemos todo lo que necesitamos saber de docker para deployar nuestras aplicationes. Este curso asume que ya sabes lo que es docker y para qué sirve</p>
</div>
</div>
</a>
</div>
<!-- Service Content Area -->
<div class="col-12 col-sm-6 col-lg-4">
<a href="#reactphp-fundamentals">
<div class="service-content-area text-center mb-30 wow fadeInUp" data-wow-delay="300ms">
<!-- Icon -->
<div class="service-icon">
<i class="fa fa-server"></i>
</div>
<!-- Content text -->
<div class="service-content-text">
<h4>Fundamentos de ReactPHP</h4>
<p>Para entender correctamente cómo funciona la programación asíncrona en PHP, antes necesitamos aprender cómo funciona ReactPHP internamente.</p>
</div>
</div>
</a>
</div>
<!-- Service Content Area -->
<div class="col-12 col-sm-6 col-lg-4">
<a href="#domain-definition">
<div class="service-content-area text-center mb-30 wow fadeInUp" data-wow-delay="300ms">
<!-- Icon -->
<div class="service-icon">
<i class="fa fa-project-diagram"></i>
</div>
<!-- Content text -->
<div class="service-content-text">
<h4>Definición del dominio</h4>
<p>Con un proyecto simple pero completo delante nuestro, empezaremos a pensar en nuestro modelo. En esta parte no vamos a cargar ninguna dependencia externa como Mysql o Redis. Solo nuestras clases. Después de este módulo, tu proyecto funcionará síncronamente sin ningúna capa de persistencia</p>
</div>
</div>
</a>
</div>
<!-- Service Content Area -->
<div class="col-12 col-sm-6 col-lg-4">
<a href="#io-dependencies">
<div class="service-content-area text-center mb-30 wow fadeInUp" data-wow-delay="300ms">
<!-- Icon -->
<div class="service-icon">
<i class="fa fa-layer-group"></i>
</div>
<!-- Content text -->
<div class="service-content-text">
<h4>Dependencias I/O</h4>
<p>Una vez nuestro proyecto ya está funcionando correctamente, vamos a trabajar la capa de persistencia, como Redis o Mysql. Veremos que testear esta capa es trivial y extremadamente rápido. Veremos cuan rápido es cambiar entre adaptadores.</p>
</div>
</div>
</a>
</div>
<!-- Service Content Area -->
<div class="col-12 col-sm-6 col-lg-4">
<a href="#turning-event-driven">
<div class="service-content-area text-center mb-30 wow fadeInUp" data-wow-delay="300ms">
<!-- Icon -->
<div class="service-icon">
<i class="fa fa-cogs"></i>
</div>
<!-- Content text -->
<div class="service-content-text">
<h4>Eventos de dominio</h4>
<p>Y si transformamos nuestra aplicación entera para que trabaje con eventos de dominio? Cuánto creéis que podrá mejorar? Este capítulo, literalmente, te fascinará.</p>
</div>
</div>
</a>
</div>
</div>
</div>
</section>
<!-- ***** Service Area End ***** -->
<!-- ***** Service Area Start ***** -->
<section class="point-zone clearfix mt-50 mb-50" id="skeleton">
<div class="container">
<div class="row">
<div class="col-12">
<!-- Section Title -->
<div class="section-title text-center wow fadeInUp" data-wow-delay="300ms">
<h2><span class="fa fa-skull"></span> Estructura</h2>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<p>
Parece simple y trivial, pero la mayoría de las veces,
es uno de los puntos más complejos a la hora de empezar
un proyecto. En este primer bloque del curso, empezaremos
por construir lo que será el esqueleto de nuestra aplicación.
¿Qué necesitamos para empezar desde cero un proyecto donde,
nuestra lógica de negocio, será implementada alrededor
de una arquitectura CQRS y Event-Driven?
¿Cuales son las librerías que <strong>realmente</strong>
vamos a necesitar para empezar con un repositorio lo más
ligero posible?
</p>
<p>
En este capítulo exploraremos los principios de DriftPHP,
un nuevo framework construido con los componentes de Symfony
y ReactPHP. Conoceremos los componentes del framework así
como sus posibles usos.
</p>
<ul>
<li>Duración del bloque - <strong>3h</strong></li>
<li>Definición de capas</li>
<li>Instalamos DriftPHP. Arquitectura y fundamentos.</li>
<li>Command Bus como el elemento core del proyecto</li>
<li>Commands, command handlers y middlewares</li>
<li>Nuestro primer <i>Hello world</i> utilizando CQRS</li>
<li>Soporte en servidor por parte de DriftPHP. Server + Watcher</li>
<li>Un poco de benchmarking con AB</li>
</ul>
</div>
</div>
</div>
</section>
<!-- ***** Service Area End ***** -->
<section class="point-zone bg-gray clearfix pb-5 pt-5" id="docker-basics">
<div class="container">
<div class="row">
<div class="col-12">
<!-- Section Title -->
<div class="section-title text-center wow fadeInUp" data-wow-delay="300ms">
<h2><span class="fab fa-docker"></span> Básicos de Docker</h2>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<p>
Hoy en dia, una de las mejores formas de hacer que cualquier
aplicación pueda funciona en cualquier entorno moderno es
añadiendo soporte para Docker. Docker es una tecnología bastante
asequible si entiendes su función, y este será nuestro
objetivo. Una vez tengamos nuestra propia estructura para
nuestra aplicación de <i>hello world</i>, vamos a configurar
docker y docker-composer para poder hacer deployments, testing
y desarrollo en local.
</p>
<p>
El objetivo de este bloque es añadir soporte de docker
en nuestra aplicación. Añadiremos también integración
con CircleCI para añadir un hook en nuestras pull requests
</p>
<ul>
<li>Duración del bloque - <strong>2h</strong></li>
<li>Elementos necesarios de Docker</li>
<li>Docker composer para testing</li>
<li>Crear un Dockerfile base</li>
</ul>
</div>
</div>
</div>
</section>
<!-- ***** Service Area End ***** -->
<!-- ***** Service Area Start ***** -->
<section class="point-zone clearfix mt-50 mb-50" id="reactphp-fundamentals">
<div class="container">
<div class="row">
<div class="col-12">
<!-- Section Title -->
<div class="section-title text-center wow fadeInUp" data-wow-delay="300ms">
<h2><span class="fa fa-server"></span> Fundamentos de ReactPHP</h2>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<p>
Trabajar con ReactPHP es una experiencia completamente nueva
si nunca has trabajado con un Event-Loop o una Promesa. Las
cosas suceden eventualmente, y precisamente esto te fuerza
a cambiar tu mentalidad sobre como programar tus servicios.
</p>
<p>
DriftPHP, por primera vez en un framework PHP, te permite
trabajar con Responses de ReactPHP. Esto te permitirá
aplicar todos los conceptos de asincronía en ty dominio de una forma
que nunca antes habrías visto.
</p>
<p>
Tras este bloque, entenderás todos los fundamentos de ReactPHP, una parte
esencial del curso.
</p>
<ul>
<li>Duración del bloque - <strong>3h</strong></li>
<li>¿Qué es un event-loop?</li>
<li>¿Qué es una promesa?</li>
<li>¿Qué es un stream?</li>
</ul>
</div>
</div>
</div>
</section>
<!-- ***** Service Area End ***** -->
<section class="point-zone bg-gray clearfix pb-5 pt-5" id="domain-definition">
<div class="container">
<div class="row">
<div class="col-12">
<!-- Section Title -->
<div class="section-title text-center wow fadeInUp" data-wow-delay="300ms">
<h2><span class="fa fa-project-diagram"></span> Definición del Dominio</h2>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<p>
Ahora ya tenemos un servicio que sirve peticiones tan
rápido como realmente puede hacerlo, pero solo podemos
servir un solo endpoint. Y será complicado ganar un poco
de dinero tan solo con esta funcionalidad, por lo que
vamos a empezar a diseñar nuestro dominio.
</p>
<p>
Y nuestro proyecto será simple. Crearemos un pequeño
servicio para gestionar usuarios. No será un sistema
de login ni un sistema de gestión demasiado complejo,
solo una pequeña API donde podremos:
</p>
<ul>
<li>Añadir un usuario</li>
<li>Eliminar un usuario existente</li>
<li>Editar un usuario existente</li>
<li>Listar todos nuestros usuarios</li>
</ul>
<p>
Estos puntos serán suficientes como para entender
ciertos puntos sobre la arquitectura, como donde añadir
nuestras clases de dominio, qué deberían contener estas clases
y que deberían evitar, y cuan grande puede ser dicho dominio
antes de poder aplicar una separación lógica.
</p>
<p>
Después de este capítulo, todo debería estar funcionando
perfectamente de una forma completamente síncrona, y
guardando absolutamente todo en memoria. Aún no siendo
útil de ninguna de las formas, oye, es un primer paso.
</p>
<ul>
<li>Duración del bloque - <strong>3h</strong></li>
<li>Análisis de requerimientos</li>
<li>Implementación de las clases del modelo</li>
<li>Interfaces de repositorios y implementación en memoria</li>
<li>Tests completos de nuestras necesidades, tanto unitarios como funcionales</li>
</ul>
</div>
</div>
</div>
</section>
<!-- ***** Service Area End ***** -->
<!-- ***** Service Area Start ***** -->
<section class="point-zone clearfix mt-50 mb-50" id="io-dependencies">
<div class="container">
<div class="row">
<div class="col-12">
<!-- Section Title -->
<div class="section-title text-center wow fadeInUp" data-wow-delay="300ms">
<h2><span class="fa fa-layer-group"></span> Dependencias de I/O</h2>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<p>
Vamos a hacer que todo funcione correctamente añadiendo una
capa extra en nuestro proyecto, relativa a nuestras implementaciones
de I/O. En nuestro lenguaje, añadir adaptadores para nuestros
repositorios, como el de Repositorio de User.
</p>
<p>
Todos estos adaptadores tienen que estar cubiertos por tests
unitarios al 100%, Veremos cómo, a pesar de todo, si seguimos
la arquitectura que vamos a seguir, este ejercicio será trivial
y rápido.
</p>
<p>
Después de este bloque, nuestra aplicación pasará a ser usable.
</p>
<ul>
<li>Duración del bloque - <strong>2h</strong></li>
<li>Adaptador Mysql para la capa de persistencia</li>
<li>Tests unitarios para los nuevos adaptadores</li>
</ul>
</div>
</div>
</div>
</section>
<!-- ***** Service Area End ***** -->
<section class="point-zone bg-gray clearfix pb-5 pt-5" id="turning-event-driven">
<div class="container">
<div class="row">
<div class="col-12">
<!-- Section Title -->
<div class="section-title text-center wow fadeInUp" data-wow-delay="300ms">
<h2><span class="fa fa-sync"></span> Eventos de dominio</h2>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<p>
Tras estos últimos 5 capítulos, tendremos un servicio funcionando
perfectamente en ReactPHP, con algunas implementaciones de repositorio
testeadas y con algunos benchmarks ejecutados que nos demostrarán que,
sin lugar a duda, hemos experimentado una mejora de performance sustancial
con respecto a servicios a los que estamos acostumbrados.
</p>
<p>
Aún así, lo podemos hacer mejor. Mucho mejor. <strong>Increiblemente mejor</strong>
</p>
<p>
Este capítulo final hará que te estalle la cabeza, pues empezaremos a trabajar
con eventos de dominio, y precisamente gracias a las features que ReactPHP nos
brinda en términos de asincronía y non-blocking, podremos convertir nuestro servicio
en algo mucho más escalable, desacoplándolo muchísimo más de la infrastructura y
decrementando nuestros tiempos de respuesta y uso de recursos por enésima vez.
</p>
<ul>
<li>Duración del bloque - <strong>3h</strong></li>
<li>Definición de eventos de dominio</li>
<li>Introduciendo repositorios en memoria long-term</li>
<li>Introducción a AMQP (RabbitMQ)</li>
<li>Deployando la combinación server + consumer</li>
<li>Introducción a los websockets</li>
</ul>
</div>
</div>
</div>
</section>
<!-- ***** Service Area End ***** -->
<!-- ***** Footer Area Start ***** -->
<footer class="footer-bottom-area section-padding-50">
<div class="container">
<div class="row">
<div class="col-12">
<div class="footer--content-text text-center">
<div class="footer-social-icon d-flex align-items-center justify-content-center">
<a href="https://twitter.com/mmoreram" data-toggle="tooltip" data-placement="top" title="Twitter"><i class="social_twitter"></i></a>
<a href="https://www.linkedin.com/in/mmoreram/" data-toggle="tooltip" data-placement="top" title="Linkedin"><i class="social_linkedin"></i></a>
<a href="https://www.youtube.com/channel/UC4GrdGq5JfI4tDmOuXViyxQ" data-toggle="tooltip" data-placement="top" title="Youtube"><i class="social_youtube"></i></a>
</div>
<p>Copyright ©2019 All rights reserved by <a href="#" target="_blank">Classy Theme</a></p>
</div>
</div>
</div>
</div>
</footer>
<!-- ***** Footer Area End ***** -->
</div>
<!-- All JavaScript Files -->
<script src="js/jquery.min.js"></script>
<script src="js/popper.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/bundle.js"></script>
<script src="js/active.js"></script>
<script id="mcjs">!function(c,h,i,m,p){m=c.createElement(h),p=c.getElementsByTagName(h)[0],m.async=1,m.src=i,p.parentNode.insertBefore(m,p)}(document,"script","https://chimpstatic.com/mcjs-connected/js/users/c11fd3061a6f0d72f6464d2f4/84ab7df037d8fdd3aad087ac6.js");</script>
</body>
</html>