This repository was archived by the owner on Jul 1, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
537 lines (531 loc) · 83.7 KB
/
Copy pathindex.html
File metadata and controls
537 lines (531 loc) · 83.7 KB
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
<!DOCTYPE html><html lang="en-US"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,height=device-height,initial-scale=1.0"><meta name="apple-mobile-web-app-capable" content="yes"><meta http-equiv="X-UA-Compatible" content="ie=edge"><meta property="og:type" content="website"><meta name="twitter:card" content="summary"><style>@media screen{body,html{background:#000;height:100%;margin:0;overflow:hidden}[data-bespoke-marp-fragment=inactive]{visibility:hidden}.bespoke-marp-osc{display:none;opacity:0}.bespoke-marp-parent{bottom:0;left:0;position:absolute;right:0;top:0}.bespoke-marp-parent>.bespoke-marp-osc{background:rgba(0,0,0,.65);border-radius:7px;bottom:50px;color:#fff;display:block;font-family:Helvetica,Arial,sans-serif;font-size:16px;left:50%;line-height:0;opacity:1;padding:12px;position:absolute;touch-action:manipulation;-webkit-transform:translateX(-50%);transform:translateX(-50%);-webkit-transition:opacity .2s linear;transition:opacity .2s linear;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;white-space:nowrap;z-index:1;will-change:transform}.bespoke-marp-parent>.bespoke-marp-osc>*{margin-left:6px}.bespoke-marp-parent>.bespoke-marp-osc>:first-child{margin-left:0}.bespoke-marp-parent>.bespoke-marp-osc>span{opacity:.8}.bespoke-marp-parent>.bespoke-marp-osc>span[data-bespoke-marp-osc=page]{display:inline-block;min-width:140px;text-align:center}.bespoke-marp-parent>.bespoke-marp-osc>button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;border:0;color:inherit;cursor:pointer;font-size:inherit;opacity:.8;outline:none;padding:0;-webkit-transition:opacity .2s linear;transition:opacity .2s linear;-webkit-tap-highlight-color:transparent}.bespoke-marp-parent>.bespoke-marp-osc>button:disabled{cursor:not-allowed;opacity:.15!important}.bespoke-marp-parent>.bespoke-marp-osc>button:hover{opacity:1}.bespoke-marp-parent>.bespoke-marp-osc>button:hover:active{opacity:.6}.bespoke-marp-parent>.bespoke-marp-osc>button:hover:not(:disabled){-webkit-transition:none;transition:none}.bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=prev]{background:transparent url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IiNmZmYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSI1IiBkPSJNNjggOTBMMjggNTBsNDAtNDAiLz48L3N2Zz4=") no-repeat 50%;background-size:contain;height:32px;overflow:hidden;text-indent:100%;white-space:nowrap;width:32px}.bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=next]{background:transparent url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IiNmZmYiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSI1IiBkPSJNMzIgOTBsNDAtNDAtNDAtNDAiLz48L3N2Zz4=") no-repeat 50%;background-size:contain;height:32px;overflow:hidden;text-indent:100%;white-space:nowrap;width:32px}.bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=fullscreen]{background:transparent url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48ZGVmcz48c3R5bGU+LmF7ZmlsbDpub25lO3N0cm9rZTojZmZmO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2Utd2lkdGg6NXB4fTwvc3R5bGU+PC9kZWZzPjxyZWN0IGNsYXNzPSJhIiB4PSIxMCIgeT0iMjAiIHdpZHRoPSI4MCIgaGVpZ2h0PSI2MCIgcng9IjUuNjciLz48cGF0aCBjbGFzcz0iYSIgZD0iTTQwIDcwSDIwVjUwbTIwIDBMMjAgNzBtNDAtNDBoMjB2MjBtLTIwIDBsMjAtMjAiLz48L3N2Zz4=") no-repeat 50%;background-size:contain;height:32px;overflow:hidden;text-indent:100%;white-space:nowrap;width:32px}.bespoke-marp-parent>.bespoke-marp-osc>button[data-bespoke-marp-osc=fullscreen].exit{background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48ZGVmcz48c3R5bGU+LmF7ZmlsbDpub25lO3N0cm9rZTojZmZmO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2Utd2lkdGg6NXB4fTwvc3R5bGU+PC9kZWZzPjxyZWN0IGNsYXNzPSJhIiB4PSIxMCIgeT0iMjAiIHdpZHRoPSI4MCIgaGVpZ2h0PSI2MCIgcng9IjUuNjciLz48cGF0aCBjbGFzcz0iYSIgZD0iTTIwIDUwaDIwdjIwbS0yMCAwbDIwLTIwbTQwIDBINjBWMzBtMjAgMEw2MCA1MCIvPjwvc3ZnPg==")}.bespoke-marp-parent.bespoke-marp-inactive{cursor:none}.bespoke-marp-parent.bespoke-marp-inactive>.bespoke-marp-osc{opacity:0;pointer-events:none}svg.bespoke-marp-slide{height:100%;left:0;pointer-events:none;position:absolute;top:0;width:100%;z-index:-1}svg.bespoke-marp-slide.bespoke-marp-active{pointer-events:auto;z-index:0}svg.bespoke-marp-slide[data-bespoke-marp-load=hideable]{display:none}svg.bespoke-marp-slide[data-bespoke-marp-load=hideable].bespoke-marp-active{display:block}.bespoke-progress-parent{background:#222;display:-webkit-box;display:flex;height:5px;width:100%}.bespoke-progress-parent+.bespoke-marp-parent{top:5px}.bespoke-progress-parent .bespoke-progress-bar{-webkit-box-flex:0;flex:0 0 0;background:#0288d1;-webkit-transition:-webkit-flex-basis .2s cubic-bezier(0,1,1,1);transition:-webkit-flex-basis .2s cubic-bezier(0,1,1,1);transition:flex-basis .2s cubic-bezier(0,1,1,1);transition:flex-basis .2s cubic-bezier(0,1,1,1),-webkit-flex-basis .2s cubic-bezier(0,1,1,1)}}@media print{.bespoke-marp-osc,.bespoke-progress-parent{display:none!important;-webkit-transition:none!important;transition:none!important}.bespoke-marp-parent{top:0}}</style><style>div#p>svg>foreignObject>section{width:1280px;height:720px;box-sizing:border-box;overflow:hidden;position:relative;scroll-snap-align:center center}div#p>svg>foreignObject>section:after{bottom:0;content:attr(data-marpit-pagination);padding:inherit;pointer-events:none;position:absolute;right:0}div#p>svg>foreignObject>section:not([data-marpit-pagination]):after{display:none}/* Normalization */div#p>svg>foreignObject>section h1{font-size:2em;margin:0.67em 0}div#p>svg>foreignObject>section video::-webkit-media-controls{will-change:transform}@page{size:1280px 720px;margin:0}@media print{body,html{background-color:#fff;margin:0;page-break-inside:avoid;break-inside:avoid-page}div#p>svg>foreignObject>section{page-break-before:always;break-before:page}div#p>svg>foreignObject>section,div#p>svg>foreignObject>section *{-webkit-print-color-adjust:exact!important;color-adjust:exact!important}div#p>svg[data-marpit-svg]{display:block;height:100vh;width:100vw}}div#p>svg>foreignObject>section svg[data-marp-fitting=svg]{display:block;height:auto;width:100%}@supports (-ms-ime-align:auto){div#p>svg>foreignObject>section svg[data-marp-fitting=svg]{position:static}}div#p>svg>foreignObject>section svg[data-marp-fitting=svg].__reflow__{content:""}@supports (-ms-ime-align:auto){div#p>svg>foreignObject>section svg[data-marp-fitting=svg].__reflow__{position:relative}}div#p>svg>foreignObject>section [data-marp-fitting-svg-content]{display:table;white-space:nowrap}div#p>svg>foreignObject>section [data-marp-fitting-svg-content-wrap]{white-space:pre}div#p>svg>foreignObject>section img[data-marp-twemoji]{background:transparent;height:1em;margin:0 .05em 0 .1em;vertical-align:-.1em;width:1em}
/* @theme microblink */div#p>svg>foreignObject>section *{box-sizing:border-box}div#p>svg>foreignObject>section :after,div#p>svg>foreignObject>section :before{box-sizing:border-box}div#p>svg>foreignObject>section body,div#p>svg>foreignObject>section html{width:100%;height:100%}div#p>svg>foreignObject>section{color:#ffffff;background-color:#000000;font-family:"Avenir Next",Avenir,sans-serif;font-size:28px }@media (min-width:400px){div#p>svg>foreignObject>section{font-size:calc(0vw + 28px);line-height:1.45 }}@media (min-width:1100px){div#p>svg>foreignObject>section{font-size:28px }}div#p>svg>foreignObject>section ol,div#p>svg>foreignObject>section ul{margin-top:0;margin-bottom:1rem;font-size:28px }@media (min-width:400px){div#p>svg>foreignObject>section ol,div#p>svg>foreignObject>section ul{font-size:calc(0vw + 28px);line-height:1.45 }}@media (min-width:1100px){div#p>svg>foreignObject>section ol,div#p>svg>foreignObject>section ul{font-size:28px }}div#p>svg>foreignObject>section ol li,div#p>svg>foreignObject>section ul li{padding-bottom:7px}div#p>svg>foreignObject>section ol ol,div#p>svg>foreignObject>section ol ul,div#p>svg>foreignObject>section ul ol,div#p>svg>foreignObject>section ul ul{margin-bottom:0}div#p>svg>foreignObject>section p{margin-top:0;margin-bottom:1rem;font-size:28px }@media (min-width:400px){div#p>svg>foreignObject>section p{font-size:calc(0vw + 28px);line-height:1.45 }}@media (min-width:1100px){div#p>svg>foreignObject>section p{font-size:28px }}div#p>svg>foreignObject>section a{transition:all o 0.3s ease;color:#48B2E8;box-shadow:inset 0 -4px 0 rgba(72,178,232,0.5);text-decoration:none}div#p>svg>foreignObject>section a:hover{opacity:0.6}div#p>svg>foreignObject>section blockquote{display:inline-block;float:left;clear:both;position:relative;margin:42px 0;padding:0;width:100%;background-repeat:no-repeat;background-size:cover}div#p>svg>foreignObject>section blockquote:before{content:"\"";position:absolute;top:0;left:-28px;opacity:0.5;font-weight:700}div#p>svg>foreignObject>section blockquote p{position:relative;margin-top:0;font-weight:700;margin-bottom:1rem;font-size:32px ;font-weight:500}@media (min-width:400px){div#p>svg>foreignObject>section blockquote p{font-size:calc(0vw + 32px);line-height:1.54 }}@media (min-width:1100px){div#p>svg>foreignObject>section blockquote p{font-size:32px }}div#p>svg>foreignObject>section blockquote p:after{content:"\"";position:relative;margin-left:10.5px;opacity:0.5;font-weight:700}div#p>svg>foreignObject>section code{font-family:"Menlo","Consolas","Courier New",Courier,monospace;font-size:17px }@media (min-width:400px){div#p>svg>foreignObject>section code{font-size:calc(0vw + 17px);line-height:1 }}@media (min-width:1100px){div#p>svg>foreignObject>section code{font-size:17px }}div#p>svg>foreignObject>section pre{display:block;overflow-x:auto;padding:0.25em .5em;background:#23241f;margin-top:0;border-radius:6px}div#p>svg>foreignObject>section .hljs,div#p>svg>foreignObject>section .hljs-subst,div#p>svg>foreignObject>section .hljs-tag{color:#f8f8f2}div#p>svg>foreignObject>section .hljs-emphasis,div#p>svg>foreignObject>section .hljs-strong{color:#a8a8a2}div#p>svg>foreignObject>section .hljs-bullet,div#p>svg>foreignObject>section .hljs-link,div#p>svg>foreignObject>section .hljs-literal,div#p>svg>foreignObject>section .hljs-number,div#p>svg>foreignObject>section .hljs-quote,div#p>svg>foreignObject>section .hljs-regexp{color:#ae81ff}div#p>svg>foreignObject>section .hljs-code,div#p>svg>foreignObject>section .hljs-section,div#p>svg>foreignObject>section .hljs-selector-class,div#p>svg>foreignObject>section .hljs-title{color:#a6e22e}div#p>svg>foreignObject>section .hljs-strong{font-weight:bold}div#p>svg>foreignObject>section .hljs-emphasis{font-style:italic}div#p>svg>foreignObject>section .hljs-attr,div#p>svg>foreignObject>section .hljs-keyword,div#p>svg>foreignObject>section .hljs-name,div#p>svg>foreignObject>section .hljs-selector-tag{color:#f92672}div#p>svg>foreignObject>section .hljs-attribute,div#p>svg>foreignObject>section .hljs-symbol{color:#66d9ef}div#p>svg>foreignObject>section .hljs-class .hljs-title,div#p>svg>foreignObject>section .hljs-params{color:#f8f8f2}div#p>svg>foreignObject>section .hljs-addition,div#p>svg>foreignObject>section .hljs-built_in,div#p>svg>foreignObject>section .hljs-builtin-name,div#p>svg>foreignObject>section .hljs-selector-attr,div#p>svg>foreignObject>section .hljs-selector-id,div#p>svg>foreignObject>section .hljs-selector-pseudo,div#p>svg>foreignObject>section .hljs-string,div#p>svg>foreignObject>section .hljs-template-variable,div#p>svg>foreignObject>section .hljs-type,div#p>svg>foreignObject>section .hljs-variable{color:#e6db74}div#p>svg>foreignObject>section .hljs-comment,div#p>svg>foreignObject>section .hljs-deletion,div#p>svg>foreignObject>section .hljs-meta{color:#75715e}div#p>svg>foreignObject>section{padding:84px 84px;background-image:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTEiIHZpZXdCb3g9IjAgMCA1MCA1MSIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBvcGFjaXR5PSIwLjUiPjxwYXRoIGQ9Ik0zLjM2MjYxIDEuMjYyNjlMMC41OTg0OCAzLjk1NDU3TDYuODAyOTggMTAuMDAwM0w5LjU2NzExIDcuMzA4NDRMMy4zNjI2MSAxLjI2MjY5WiIgZmlsbD0id2hpdGUiLz48cGF0aCBkPSJNNDMuMjI3NCA0MC4wNDY5TDQwLjQ2MzMgNDIuNzM4OEw0Ni42Njc3IDQ4Ljc4NDVMNDkuNDMxOSA0Ni4wOTI3TDQzLjIyNzQgNDAuMDQ2OVoiIGZpbGw9IndoaXRlIi8+PHBhdGggZD0iTTQ2LjY0MSAxLjE5NjkzTDQwLjQzNTcgNy4yNDE4Mkw0My4xOTk0IDkuOTM0MDhMNDkuNDA0OCAzLjg4OTE5TDQ2LjY0MSAxLjE5NjkzWiIgZmlsbD0id2hpdGUiLz48cGF0aCBkPSJNNi43Nzg3NCA0MC4wNjYyTDAuNTczMzY0IDQ2LjExMTFMMy4zMzcxIDQ4LjgwMzNMOS41NDI0OCA0Mi43NTg0TDYuNzc4NzQgNDAuMDY2MloiIGZpbGw9IndoaXRlIi8+PHBhdGggZD0iTTUwLjAwMDEgMjMuMTMyMkg0MS4yMjQyVjI2LjkzOTZINTAuMDAwMVYyMy4xMzIyWiIgZmlsbD0id2hpdGUiLz48cGF0aCBkPSJNOC43NzU4MSAyMy4xMzIySDBWMjYuOTM5Nkg4Ljc3NTgxVjIzLjEzMjJaIiBmaWxsPSJ3aGl0ZSIvPjxwYXRoIGQ9Ik0yNi45MTc1IDQxLjUyM0gyMy4wMDg5VjUwLjA3MThIMjYuOTE3NVY0MS41MjNaIiBmaWxsPSJ3aGl0ZSIvPjxwYXRoIGQ9Ik0yNi45MTc1IDBIMjMuMDA4OVY4LjU0ODg1SDI2LjkxNzVWMFoiIGZpbGw9IndoaXRlIi8+PC9nPjwvc3ZnPg==);background-repeat:no-repeat;background-size:28px;background-position:right 84px bottom 56px}div#p>svg>foreignObject>section>h1:first-child,div#p>svg>foreignObject>section h2:first-child,div#p>svg>foreignObject>section h3:first-child,div#p>svg>foreignObject>section h4:first-child,div#p>svg>foreignObject>section h5:first-child,div#p>svg>foreignObject>section h6:first-child{color:#48B2E8;padding-bottom:28px;margin-top:0;margin-bottom:1rem;font-weight:600;font-size:35px }@media (min-width:400px){div#p>svg>foreignObject>section>h1:first-child,div#p>svg>foreignObject>section h2:first-child,div#p>svg>foreignObject>section h3:first-child,div#p>svg>foreignObject>section h4:first-child,div#p>svg>foreignObject>section h5:first-child,div#p>svg>foreignObject>section h6:first-child{font-size:calc(1vw + 31px);line-height:1.2 }}@media (min-width:1100px){div#p>svg>foreignObject>section>h1:first-child,div#p>svg>foreignObject>section h2:first-child,div#p>svg>foreignObject>section h3:first-child,div#p>svg>foreignObject>section h4:first-child,div#p>svg>foreignObject>section h5:first-child,div#p>svg>foreignObject>section h6:first-child{font-size:42px }}div#p>svg>foreignObject>section a code,div#p>svg>foreignObject>section li code,div#p>svg>foreignObject>section p code{border-radius:10px;background-color:rgba(255,255,255,0.1);padding:7px 14px;font-size:75%}div#p>svg>foreignObject>section.title{background-image:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjA3IiBoZWlnaHQ9IjkwIiB2aWV3Qm94PSIwIDAgMjA3IDkwIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiPjxwYXRoIGQ9Ik0wLjYzMDU1NCAzMy44MzM4SDQuNzcyOThMMTEuMjkzOSA0OS4zNTc5SDExLjQwNTdMMTcuODYyNyAzMy44MzM4SDIyLjAwNTJWNTQuMzM4NEgxOS4yMjc2VjM3LjQ4MTRIMTkuMTcxN0wxMi4yNTE3IDU0LjMzODRIMTAuNEwzLjQ3MTk5IDM3LjQ4MTRIMy40MDgxM1Y1NC4zMzg0SDAuNjMwNTU0VjMzLjgzMzhaIiBmaWxsPSJ3aGl0ZSIvPjxwYXRoIGQ9Ik0zMC41NTM0IDMzLjgzMzhIMzMuMzMxVjU0LjMzODRIMzAuNTUzNFYzMy44MzM4WiIgZmlsbD0id2hpdGUiLz48cGF0aCBkPSJNNTUuODU0OSAzOC4yNjM1QzU1LjI3MjMgMzcuNTEzMyA1NC41Mzc5IDM2LjkzMDYgNTMuNjUyIDM2LjUyMzZDNTIuNzY2IDM2LjExNjUgNTEuODQ4MiAzNS45MTcgNTAuODk4NCAzNS45MTdDNDkuNzQxIDM1LjkxNyA0OC42OTU1IDM2LjEzMjUgNDcuNzUzNiAzNi41NzE1QzQ2LjgxOTggMzcuMDAyNSA0Ni4wMTM2IDM3LjYwMTEgNDUuMzUxMiAzOC4zNTEzQzQ0LjY4ODcgMzkuMTAxNiA0NC4xNjk5IDM5Ljk4NzYgNDMuODAyOCA0MS4wMDEyQzQzLjQzNTYgNDIuMDE0OSA0My4yNTIgNDMuMTAwNCA0My4yNTIgNDQuMjU3N0M0My4yNTIgNDUuMzQzMiA0My40Mjc2IDQ2LjM2NDggNDMuNzcwOCA0Ny4zMzA2QzQ0LjEyMiA0OC4yOTY0IDQ0LjYxNjkgNDkuMTQyNCA0NS4yNzkzIDQ5Ljg3NjdDNDUuOTMzOCA1MC42MTEgNDYuNzQgNTEuMTkzNyA0Ny42ODE4IDUxLjYxNjdDNDguNjMxNiA1Mi4wMzk3IDQ5LjcwMTEgNTIuMjU1MiA1MC44OTg0IDUyLjI1NTJDNTIuMDc5NiA1Mi4yNTUyIDUzLjEwOTMgNTIuMDE1OCA1My45OTUyIDUxLjUyODlDNTQuODgxMiA1MS4wNSA1NS42Mzk0IDUwLjM3MTYgNTYuMjU0IDQ5LjUwMTZMNTguNjAwNiA1MS4yNjU1QzU4LjQ0ODkgNTEuNDgxIDU4LjE3NzUgNTEuNzg0MyA1Ny43ODY0IDUyLjE3NTRDNTcuNDAzMyA1Mi41NzQ1IDU2Ljg4NDUgNTIuOTY1NiA1Ni4yNTQgNTMuMzY0NkM1NS42MTU1IDUzLjc2MzcgNTQuODQ5MiA1NC4xMDY5IDUzLjk1NTMgNTQuNDEwMkM1My4wNjE0IDU0LjcxMzUgNTIuMDE1OCA1NC44NTcyIDUwLjg0MjUgNTQuODU3MkM0OS4yMjIyIDU0Ljg1NzIgNDcuNzYxNiA1NC41NDU5IDQ2LjQ1MjYgNTMuOTMxM0M0NS4xNTE2IDUzLjMxNjggNDQuMDQyMiA1Mi41MDI2IDQzLjEyNDMgNTEuNDk3QzQyLjIwNjQgNTAuNDkxMyA0MS41MDQxIDQ5LjM1NzkgNDEuMDI1MiA0OC4wOTY4QzQwLjU0NjMgNDYuODM1NyA0MC4yOTg5IDQ1LjU1MDcgNDAuMjk4OSA0NC4yNTc3QzQwLjI5ODkgNDIuNjc3MyA0MC41NjIyIDQxLjIwODcgNDEuMDgxMSAzOS44Njc4QzQxLjU5OTkgMzguNTI2OSA0Mi4zMzQyIDM3LjM2OTYgNDMuMjY4IDM2LjM5NTlDNDQuMjAxOCAzNS40MjIxIDQ1LjMyNzIgMzQuNjYzOSA0Ni42NDQyIDM0LjEyMTFDNDcuOTYxMSAzMy41Nzg0IDQ5LjQwNTggMzMuMzA3IDUwLjk4NjIgMzMuMzA3QzUyLjMzNSAzMy4zMDcgNTMuNjY4IDMzLjU3MDQgNTQuOTY5IDM0LjA4OTJDNTYuMjY5OSAzNC42MDggNTcuMzM5NSAzNS40MTQxIDU4LjE2OTYgMzYuNDkxNkw1NS44NTQ5IDM4LjI2MzVaIiBmaWxsPSJ3aGl0ZSIvPjxwYXRoIGQ9Ik02NS4xMDU1IDMzLjgzMzhINzIuMzIwOUM3My42Mjk4IDMzLjgzMzggNzQuNzE1MyAzNC4wMDk0IDc1LjU2MTQgMzQuMzY4NUM3Ni40MDc0IDM0LjcyNzcgNzcuMDg1OCAzNS4xODI3IDc3LjU3MjcgMzUuNzMzNEM3OC4wNjc2IDM2LjI4NDEgNzguNDEwOCAzNi44OTg3IDc4LjYwMjMgMzcuNTg1MUM3OC43OTM5IDM4LjI3MTUgNzguODg5NyAzOC45MzQgNzguODg5NyAzOS41NzI1Qzc4Ljg4OTcgNDAuMjI3IDc4Ljc3NzkgNDAuODY1NSA3OC41Mzg1IDQxLjQ3MjFDNzguMzA3IDQyLjA3ODcgNzcuOTcxOCA0Mi42Mjk1IDc3LjU0MDggNDMuMTI0M0M3Ny4xMDk4IDQzLjYxOTIgNzYuNTc1IDQ0LjAzNDIgNzUuOTQ0NSA0NC4zNjk0Qzc1LjMxMzkgNDQuNzA0NyA3NC42MTk1IDQ0LjkxMjIgNzMuODQ1MyA0NC45OTJMNzkuNjYzOSA1NC4zNDY0SDc2LjE5MTlMNzAuOTggNDUuMzExM0g2Ny44ODMxVjU0LjM0NjRINjUuMTA1NVYzMy44MzM4VjMzLjgzMzhaTTY3Ljg4MzEgNDIuODY4OUg3MS41MzA3QzcyLjA3MzQgNDIuODY4OSA3Mi42MDgyIDQyLjgyOSA3My4xMzUgNDIuNzQxMkM3My42Njk3IDQyLjY1MzQgNzQuMTQwNyA0Mi40OTM4IDc0LjU1NTcgNDIuMjYyM0M3NC45NzA3IDQyLjAzMDggNzUuMzA2IDQxLjY5NTYgNzUuNTUzNCA0MS4yNjQ2Qzc1LjgwMDggNDAuODMzNiA3NS45Mjg1IDQwLjI2NjkgNzUuOTI4NSAzOS41NzI1Qzc1LjkyODUgMzguODc4MSA3NS44MDA4IDM4LjMxMTQgNzUuNTUzNCAzNy44ODA0Qzc1LjMwNiAzNy40NDk0IDc0Ljk3MDcgMzcuMTE0MiA3NC41NTU3IDM2Ljg4MjdDNzQuMTQwNyAzNi42NTEzIDczLjY2OTcgMzYuNDkxNiA3My4xMzUgMzYuNDAzOEM3Mi42MDAyIDM2LjMxNiA3Mi4wNjU0IDM2LjI3NjEgNzEuNTMwNyAzNi4yNzYxSDY3Ljg4MzFWNDIuODY4OVY0Mi44Njg5WiIgZmlsbD0id2hpdGUiLz48cGF0aCBkPSJNOTUuMzU1NiA1NC44NTcyQzkzLjc5MTIgNTQuODU3MiA5Mi4zNTQ2IDU0LjU4NTggOTEuMDM3NiA1NC4wMzUxQzg5LjcyMDYgNTMuNDg0NCA4OC42MDMyIDUyLjcyNjEgODcuNjYxNCA1MS43NjA0Qzg2LjcyNzYgNTAuNzk0NiA4NS45OTMzIDQ5LjY1MzIgODUuNDU4NSA0OC4zNDQzQzg0LjkyMzcgNDcuMDI3MyA4NC42NjAzIDQ1LjYxNDYgODQuNjYwMyA0NC4wOTAxQzg0LjY2MDMgNDIuNTY1NiA4NC45MjM3IDQxLjE0NDkgODUuNDU4NSAzOS44MzU5Qzg1Ljk5MzMgMzguNTE5IDg2LjcxOTYgMzcuMzg1NiA4Ny42NjE0IDM2LjQxOThDODguNTk1MiAzNS40NTQgODkuNzIwNiAzNC42OTU4IDkxLjAzNzYgMzQuMTQ1MUM5Mi4zNDY2IDMzLjU5NDMgOTMuNzkxMiAzMy4zMjMgOTUuMzU1NiAzMy4zMjNDOTYuOTIgMzMuMzIzIDk4LjM1NjcgMzMuNTk0MyA5OS42NzM2IDM0LjE0NTFDMTAwLjk5MSAzNC42OTU4IDEwMi4xMDggMzUuNDU0IDEwMy4wNSAzNi40MTk4QzEwMy45ODQgMzcuMzg1NiAxMDQuNzE4IDM4LjUyNjkgMTA1LjI1MyAzOS44MzU5QzEwNS43ODggNDEuMTUyOSAxMDYuMDUxIDQyLjU2NTYgMTA2LjA1MSA0NC4wOTAxQzEwNi4wNTEgNDUuNjE0NiAxMDUuNzg4IDQ3LjAzNTMgMTA1LjI1MyA0OC4zNDQzQzEwNC43MTggNDkuNjYxMiAxMDMuOTg0IDUwLjc5NDYgMTAzLjA1IDUxLjc2MDRDMTAyLjExNiA1Mi43MjYxIDEwMC45OTEgNTMuNDg0NCA5OS42NzM2IDU0LjAzNTFDOTguMzU2NyA1NC41ODU4IDk2LjkyIDU0Ljg1NzIgOTUuMzU1NiA1NC44NTcyWk05NS4zNTU2IDUyLjI1NTJDOTYuNTM2OSA1Mi4yNTUyIDk3LjU5ODQgNTIuMDM5NyA5OC41NDAzIDUxLjYwMDdDOTkuNDkwMSA1MS4xNjk3IDEwMC4yOTYgNTAuNTc5MSAxMDAuOTc1IDQ5Ljg0NDhDMTAxLjY1MyA0OS4xMTA1IDEwMi4xNzIgNDguMjQ4NSAxMDIuNTM5IDQ3LjI1MDhDMTAyLjkwNiA0Ni4yNTMxIDEwMy4wOSA0NS4xOTk1IDEwMy4wOSA0NC4wODIxQzEwMy4wOSA0Mi45NjQ3IDEwMi45MDYgNDEuOTAzMSAxMDIuNTM5IDQwLjkxMzRDMTAyLjE3MiAzOS45MTU3IDEwMS42NTMgMzkuMDUzNyAxMDAuOTc1IDM4LjMxOTRDMTAwLjI5NiAzNy41ODUxIDk5LjQ5MDEgMzcuMDAyNSA5OC41NDAzIDM2LjU2MzVDOTcuNTkwNSAzNi4xMzI1IDk2LjUyODkgMzUuOTA5IDk1LjM1NTYgMzUuOTA5Qzk0LjE3NDQgMzUuOTA5IDkzLjExMjggMzYuMTI0NSA5Mi4xNzEgMzYuNTYzNUM5MS4yMjEyIDM2Ljk5NDUgOTAuNDE1IDM3LjU4NTEgODkuNzM2NiAzOC4zMTk0Qzg5LjA1ODIgMzkuMDUzNyA4OC41Mzk0IDM5LjkxNTcgODguMTcyMiA0MC45MTM0Qzg3LjgwNTEgNDEuOTExMSA4Ny42MjE1IDQyLjk2NDcgODcuNjIxNSA0NC4wODIxQzg3LjYyMTUgNDUuMTk5NSA4Ny44MDUxIDQ2LjI2MTEgODguMTcyMiA0Ny4yNTA4Qzg4LjUzOTQgNDguMjQ4NSA4OS4wNTgyIDQ5LjExMDUgODkuNzM2NiA0OS44NDQ4QzkwLjQxNSA1MC41NzkxIDkxLjIyMTIgNTEuMTYxNyA5Mi4xNzEgNTEuNjAwN0M5My4xMTI4IDUyLjAzOTcgOTQuMTc0NCA1Mi4yNTUyIDk1LjM1NTYgNTIuMjU1MloiIGZpbGw9IndoaXRlIi8+PHBhdGggZD0iTTExMi44NDMgMzMuODMzOEgxMTkuOTcxQzEyMC44NTcgMzMuODMzOCAxMjEuNjg3IDMzLjkzNzUgMTIyLjQ0NSAzNC4xNTNDMTIzLjIxMSAzNC4zNjg1IDEyMy44NjYgMzQuNjc5OCAxMjQuNDE2IDM1LjA5NDlDMTI0Ljk2NyAzNS41MDk5IDEyNS4zOTggMzYuMDQ0NyAxMjUuNzE3IDM2LjY5MTJDMTI2LjAzNyAzNy4zMzc3IDEyNi4xOTYgMzguMDk1OSAxMjYuMTk2IDM4Ljk2NTlDMTI2LjE5NiA0MC4xNDcyIDEyNS44NjkgNDEuMTA1IDEyNS4yMTUgNDEuODQ3M0MxMjQuNTYgNDIuNTg5NSAxMjMuNzA2IDQzLjEzMjMgMTIyLjY2OSA0My40ODM1VjQzLjUzOTRDMTIzLjI4MyA0My41NzkzIDEyMy44NjYgNDMuNzM4OSAxMjQuNDA4IDQ0LjAxODJDMTI0Ljk1MSA0NC4yOTc2IDEyNS40MTQgNDQuNjY0OCAxMjUuODEzIDQ1LjExOTdDMTI2LjIxMiA0NS41NzQ2IDEyNi41MjQgNDYuMTAxNCAxMjYuNzU1IDQ2LjdDMTI2Ljk4NyA0Ny4yOTg3IDEyNy4xMDYgNDcuOTQ1MiAxMjcuMTA2IDQ4LjYzOTZDMTI3LjEwNiA0OS41NjU0IDEyNi45MTUgNTAuMzc5NSAxMjYuNTQgNTEuMDg5OUMxMjYuMTY0IDUxLjc5MjMgMTI1LjY0NiA1Mi4zOTA5IDEyNC45OTEgNTIuODY5OEMxMjQuMzM3IDUzLjM1NjcgMTIzLjU3IDUzLjcxNTggMTIyLjcgNTMuOTcxMkMxMjEuODMgNTQuMjE4NyAxMjAuODk3IDU0LjM0NjQgMTE5Ljg5MSA1NC4zNDY0SDExMi44NTFWMzMuODMzOEgxMTIuODQzWk0xMTUuNjIxIDQyLjM1MDFIMTE5LjQxMkMxMTkuOTMxIDQyLjM1MDEgMTIwLjQyNiA0Mi4yOTQyIDEyMC44ODkgNDIuMTkwNUMxMjEuMzUyIDQyLjA4NjcgMTIxLjc1OSA0MS45MDMxIDEyMi4xMDIgNDEuNjU1N0MxMjIuNDUzIDQxLjQwODMgMTIyLjcyNCA0MS4wODkgMTIyLjkyNCA0MC42OTc5QzEyMy4xMjMgNDAuMzE0OCAxMjMuMjI3IDM5LjgzNTkgMTIzLjIyNyAzOS4yNzcyQzEyMy4yMjcgMzguNDYzMSAxMjIuOTY0IDM3Ljc2MDcgMTIyLjQ0NSAzNy4xNjIxQzEyMS45MjYgMzYuNTYzNSAxMjEuMTA0IDM2LjI2MDIgMTE5Ljk4NyAzNi4yNjAySDExNS42MTNWNDIuMzUwMUgxMTUuNjIxWk0xMTUuNjIxIDUxLjkwNEgxMTkuNzA3QzEyMC4xMyA1MS45MDQgMTIwLjYwMSA1MS44NjQxIDEyMS4xMTIgNTEuNzc2M0MxMjEuNjIzIDUxLjY4ODUgMTIyLjEwMiA1MS41MTI5IDEyMi41NDkgNTEuMjU3NUMxMjIuOTk2IDUwLjk5NDEgMTIzLjM3MSA1MC42NDI5IDEyMy42ODIgNTAuMjA0QzEyMy45OTMgNDkuNzU3IDEyNC4xNDUgNDkuMTc0MyAxMjQuMTQ1IDQ4LjQ0QzEyNC4xNDUgNDcuMjI2OCAxMjMuNzQ2IDQ2LjMwOSAxMjIuOTU2IDQ1LjcwMjRDMTIyLjE2NiA0NS4wOTU4IDEyMS4wOTYgNDQuNzkyNSAxMTkuNzM5IDQ0Ljc5MjVIMTE1LjYyOVY1MS45MDRIMTE1LjYyMVoiIGZpbGw9IndoaXRlIi8+PHBhdGggZD0iTTEzNC41NjkgMzMuODMzOEgxMzcuMzQ3VjUxLjczNjRIMTQ2Ljc1N1Y1NC4zNDY0SDEzNC41NjlWMzMuODMzOFoiIGZpbGw9IndoaXRlIi8+PHBhdGggZD0iTTE1My4wNzggMzMuODMzOEgxNTUuODU2VjU0LjMzODRIMTUzLjA3OFYzMy44MzM4WiIgZmlsbD0id2hpdGUiLz48cGF0aCBkPSJNMTY0LjYwNCAzMy44MzM4SDE2OC4yNTFMMTc5LjU0NSA1MC42OTA4SDE3OS42MDFWMzMuODMzOEgxODIuMzc4VjU0LjMzODRIMTc4Ljg0M0wxNjcuNDI5IDM3LjQ4MTRIMTY3LjM3M1Y1NC4zMzg0SDE2NC41OTZWMzMuODMzOEgxNjQuNjA0WiIgZmlsbD0id2hpdGUiLz48cGF0aCBkPSJNMTkwLjc5OSAzMy44MzM4SDE5My41NzdWNDIuNjkzM0gxOTMuODA4TDIwMi44NzUgMzMuODMzOEgyMDYuNzU0TDE5Ni44NDkgNDMuMzA3OUwyMDcuNDI1IDU0LjM0NjRIMjAzLjM3TDE5My44MDggNDQuMDkwMUgxOTMuNTc3VjU0LjM0NjRIMTkwLjc5OVYzMy44MzM4WiIgZmlsbD0id2hpdGUiLz48cGF0aCBkPSJNMS4xMDk0NCA3Ni4zODM0QzEuMzU2ODYgNzYuNzUwNiAxLjY2ODE0IDc3LjAxNCAyLjA0MzI4IDc3LjE4OTZDMi40MTg0MSA3Ny4zNjUyIDIuODA5NTEgNzcuNDUzIDMuMjE2NTcgNzcuNDUzQzMuNDQwMDUgNzcuNDUzIDMuNjcxNTEgNzcuNDIxIDMuOTAyOTggNzcuMzQ5MkM0LjEzNDQ0IDc3LjI3NzQgNC4zNDk5NSA3Ny4xNzM2IDQuNTQxNSA3Ny4wM0M0LjczMzA2IDc2Ljg4NjMgNC44OTI2OSA3Ni43MTg3IDUuMDEyNDIgNzYuNTExMkM1LjEzMjE0IDc2LjMwMzYgNS4xOTU5OSA3Ni4wNjQyIDUuMTk1OTkgNzUuNzkyOEM1LjE5NTk5IDc1LjQwOTcgNS4wNzYyNyA3NS4xMTQ0IDQuODI4ODQgNzQuOTE0OEM0LjU4MTQxIDc0LjcxNTMgNC4yODYwOSA3NC41NDc3IDMuOTI2OTIgNzQuNDEyQzMuNTY3NzUgNzQuMjc2MyAzLjE3NjY2IDc0LjE0ODYgMi43NDU2NSA3NC4wMjA5QzIuMzIyNjMgNzMuODkzMiAxLjkyMzU1IDczLjcxNzYgMS41NjQzOCA3My40OTQxQzEuMjA1MjEgNzMuMjcwNiAwLjkwMTkxNSA3Mi45NjczIDAuNjYyNDY5IDcyLjU5MjJDMC40MTUwNDEgNzIuMjE3MSAwLjI5NTMxNyA3MS42OTgzIDAuMjk1MzE3IDcxLjA1MThDMC4yOTUzMTcgNzAuNzY0NCAwLjM1OTE3IDcwLjQ1MzEgMC40ODY4NzUgNzAuMTI1OUMwLjYxNDU4IDY5Ljc5ODcgMC44MTQxMTggNjkuNDk1NCAxLjA4NTQ5IDY5LjIyNEMxLjM1Njg2IDY4Ljk1MjYgMS43MDgwNSA2OC43MjkxIDIuMTMxMDcgNjguNTQ1NkMyLjU1NDEgNjguMzYyIDMuMDcyOSA2OC4yNzQyIDMuNjcxNTEgNjguMjc0MkM0LjIxNDI2IDY4LjI3NDIgNC43MzMwNiA2OC4zNDYgNS4yMjc5MiA2OC40OTc3QzUuNzIyNzcgNjguNjQ5MyA2LjE2MTc2IDY4Ljk1MjYgNi41MzY4OSA2OS40MDc2TDUuNDQzNDIgNzAuNDA1M0M1LjI3NTgxIDcwLjE0MTkgNS4wMzYzNiA2OS45MzQzIDQuNzI1MDggNjkuNzc0N0M0LjQxMzggNjkuNjE1MSA0LjA2MjYxIDY5LjUzNTMgMy42NzE1MSA2OS41MzUzQzMuMjk2MzggNjkuNTM1MyAyLjk4NTEgNjkuNTgzMiAyLjczNzY3IDY5LjY3ODlDMi40OTAyNCA2OS43NzQ3IDIuMjkwNzEgNjkuOTAyNCAyLjEzOTA2IDcwLjA1NDFDMS45ODc0MSA3MC4yMDU3IDEuODgzNjUgNzAuMzczMyAxLjgxOTc5IDcwLjU0ODlDMS43NTU5NCA3MC43MjQ1IDEuNzMyIDcwLjg5MjEgMS43MzIgNzEuMDQzOEMxLjczMiA3MS40NjY4IDEuODUxNzIgNzEuNzg2MSAyLjA5OTE1IDcyLjAwOTZDMi4zMzg2IDcyLjIzMyAyLjY0MTg5IDcyLjQxNjYgMy4wMDEwNiA3Mi41NjAzQzMuMzYwMjMgNzIuNzA0IDMuNzUxMzMgNzIuODIzNyA0LjE4MjMzIDcyLjkzNTRDNC42MDUzNiA3My4wNDcyIDUuMDA0NDMgNzMuMjA2OCA1LjM2MzYgNzMuNDA2M0M1LjcyMjc3IDczLjYwNTkgNi4wMjYwNyA3My44NzcyIDYuMjY1NTIgNzQuMjIwNEM2LjUwNDk3IDc0LjU2MzYgNi42MzI2NyA3NS4wMzQ2IDYuNjMyNjcgNzUuNjMzMkM2LjYzMjY3IDc2LjExMjEgNi41NDQ4NyA3Ni41NDMxIDYuMzYxMyA3Ni45MjYyQzYuMTc3NzIgNzcuMzA5MyA1LjkzMDI5IDc3LjYzNjUgNS42MjcgNzcuODkyQzUuMzE1NzEgNzguMTU1MyA0Ljk1NjU0IDc4LjM1NDkgNC41MzM1MiA3OC40OTg2QzQuMTEwNSA3OC42NDIyIDMuNjYzNTMgNzguNzA2MSAzLjE4NDY0IDc4LjcwNjFDMi41NDYxMiA3OC43MDYxIDEuOTQ3NSA3OC41OTQzIDEuMzcyODMgNzguMzcwOUMwLjc5ODE1NSA3OC4xNDc0IDAuMzM1MjI1IDc3LjgxMjEgMCA3Ny4zNDEyTDEuMTA5NDQgNzYuMzgzNFoiIGZpbGw9IndoaXRlIi8+PHBhdGggZD0iTTkuMjUwNjMgNzUuNjAxMkM5LjI1MDYzIDc1Ljg4ODYgOS4zMTQ0OCA3Ni4xNiA5LjQ0MjE5IDc2LjM5MTRDOS41Njk4OSA3Ni42MzA5IDkuNzM3NSA3Ni44MzA0IDkuOTM3MDQgNzYuOTk4QzEwLjE0NDYgNzcuMTY1NiAxMC4zODQgNzcuMzAxMyAxMC42NTU0IDc3LjM4OTFDMTAuOTI2OCA3Ny40ODQ5IDExLjIwNjEgNzcuNTMyOCAxMS41MDE0IDc3LjUzMjhDMTEuODkyNSA3Ny41MzI4IDEyLjIzNTcgNzcuNDQ1IDEyLjUyMzEgNzcuMjYxNEMxMi44MTA0IDc3LjA3NzggMTMuMDgxOCA3Ni44Mzg0IDEzLjMyMTIgNzYuNTM1MUwxNC4yNzkgNzcuMjYxNEMxMy41NzY2IDc4LjE3MTMgMTIuNTk0OSA3OC42MjYzIDExLjMzMzggNzguNjI2M0MxMC44MDcgNzguNjI2MyAxMC4zMzYxIDc4LjUzODUgOS45MDUxMiA3OC4zNjI5QzkuNDgyMDkgNzguMTg3MyA5LjExNDk0IDc3LjkzOTggOC44Mjc2MSA3Ny42Mjg2QzguNTMyMjkgNzcuMzE3MyA4LjMwODgxIDc2Ljk0MjIgOC4xNDkxOCA3Ni41MTkxQzcuOTg5NTQgNzYuMDk2MSA3LjkwOTczIDc1LjYzMzIgNy45MDk3MyA3NS4xMzgzQzcuOTA5NzMgNzQuNjQzNSA3Ljk5NzUzIDc0LjE4MDUgOC4xNzMxMiA3My43NTc1QzguMzQ4NzEgNzMuMzM0NSA4LjU4ODE2IDcyLjk1OTQgOC44OTE0NiA3Mi42NDgxQzkuMTk0NzYgNzIuMzM2OCA5LjU2MTkxIDcyLjA4OTQgOS45NzY5NSA3MS45MTM4QzEwLjQgNzEuNzM4MiAxMC44NTQ5IDcxLjY1MDQgMTEuMzQ5OCA3MS42NTA0QzExLjk0MDQgNzEuNjUwNCAxMi40MzUzIDcxLjc1NDEgMTIuODQyMyA3MS45NjE3QzEzLjI0OTQgNzIuMTY5MiAxMy41ODQ2IDcyLjQ0MDYgMTMuODQ4IDcyLjc2NzhDMTQuMTExNCA3My4xMDMgMTQuMzAzIDczLjQ3ODIgMTQuNDE0NyA3My44OTMyQzE0LjUzNDQgNzQuMzA4MiAxNC41OTAzIDc0LjczMTMgMTQuNTkwMyA3NS4xNjIzVjc1LjYwOTJIOS4yNTA2M1Y3NS42MDEyWk0xMy4yNDE0IDc0LjU4NzZDMTMuMjMzNCA3NC4zMDgyIDEzLjE4NTUgNzQuMDUyOCAxMy4xMDU3IDczLjgxMzRDMTMuMDI1OSA3My41ODE5IDEyLjkwNjIgNzMuMzc0NCAxMi43NDY2IDczLjIwNjhDMTIuNTg2OSA3My4wMzEyIDEyLjM4NzQgNzIuODk1NSAxMi4xNDc5IDcyLjc5OTdDMTEuOTA4NSA3Mi43MDM5IDExLjYyOTEgNzIuNjU2MSAxMS4zMDk5IDcyLjY1NjFDMTAuOTk4NiA3Mi42NTYxIDEwLjcxOTIgNzIuNzExOSAxMC40NjM4IDcyLjgzMTZDMTAuMjA4NCA3Mi45NTE0IDkuOTg0OTMgNzMuMTAzIDkuODA5MzQgNzMuMjg2NkM5LjYzMzc0IDczLjQ3MDIgOS40OTAwOCA3My42Nzc3IDkuMzk0MyA3My45MDkyQzkuMjk4NTIgNzQuMTQwNiA5LjI1MDYzIDc0LjM2NDEgOS4yNTA2MyA3NC41ODc2SDEzLjI0MTRWNzQuNTg3NloiIGZpbGw9IndoaXRlIi8+PHBhdGggZD0iTTE3LjA1NjYgNzUuNjAxMkMxNy4wNTY2IDc1Ljg4ODYgMTcuMTIwNCA3Ni4xNiAxNy4yNDgxIDc2LjM5MTRDMTcuMzc1OCA3Ni42MjI5IDE3LjU0MzQgNzYuODMwNCAxNy43NDMgNzYuOTk4QzE3Ljk1MDUgNzcuMTY1NiAxOC4xODk5IDc3LjMwMTMgMTguNDYxMyA3Ny4zODkxQzE4LjczMjcgNzcuNDg0OSAxOS4wMTIgNzcuNTMyOCAxOS4zMDc0IDc3LjUzMjhDMTkuNjk4NSA3Ny41MzI4IDIwLjA0MTcgNzcuNDQ1IDIwLjMyOSA3Ny4yNjE0QzIwLjYxNjMgNzcuMDc3OCAyMC44ODc3IDc2LjgzODQgMjEuMTI3MiA3Ni41MzUxTDIyLjA4NDkgNzcuMjYxNEMyMS4zODI2IDc4LjE3MTMgMjAuNDAwOCA3OC42MjYzIDE5LjEzOTggNzguNjI2M0MxOC42MTMgNzguNjI2MyAxOC4xNDIxIDc4LjUzODUgMTcuNzExMSA3OC4zNjI5QzE3LjI4OCA3OC4xODczIDE2LjkyMDkgNzcuOTM5OCAxNi42MzM1IDc3LjYyODZDMTYuMzM4MiA3Ny4zMTczIDE2LjExNDcgNzYuOTQyMiAxNS45NTUxIDc2LjUxOTFDMTUuNzk1NSA3Ni4wOTYxIDE1LjcxNTcgNzUuNjMzMiAxNS43MTU3IDc1LjEzODNDMTUuNzE1NyA3NC42NDM1IDE1LjgwMzUgNzQuMTgwNSAxNS45NzkxIDczLjc1NzVDMTYuMTU0NyA3My4zMzQ1IDE2LjM5NDEgNzIuOTU5NCAxNi42OTc0IDcyLjY0ODFDMTcuMDAwNyA3Mi4zMzY4IDE3LjM2NzggNzIuMDg5NCAxNy43ODI5IDcxLjkxMzhDMTguMjA1OSA3MS43MzgyIDE4LjY2MDkgNzEuNjUwNCAxOS4xNTU3IDcxLjY1MDRDMTkuNzQ2NCA3MS42NTA0IDIwLjI0MTIgNzEuNzU0MSAyMC42NDgzIDcxLjk2MTdDMjEuMDU1MyA3Mi4xNjkyIDIxLjM5MDYgNzIuNDQwNiAyMS42NTM5IDcyLjc2NzhDMjEuOTE3MyA3My4xMDMgMjIuMTA4OSA3My40NzgyIDIyLjIyMDYgNzMuODkzMkMyMi4zNDA0IDc0LjMwODIgMjIuMzk2MiA3NC43MzEzIDIyLjM5NjIgNzUuMTYyM1Y3NS42MDkySDE3LjA1NjZWNzUuNjAxMlpNMjEuMDQ3MyA3NC41ODc2QzIxLjAzOTQgNzQuMzA4MiAyMC45OTE1IDc0LjA1MjggMjAuOTExNyA3My44MTM0QzIwLjgzMTggNzMuNTgxOSAyMC43MTIxIDczLjM3NDQgMjAuNTUyNSA3My4yMDY4QzIwLjM5MjkgNzMuMDMxMiAyMC4xOTMzIDcyLjg5NTUgMTkuOTUzOSA3Mi43OTk3QzE5LjcxNDQgNzIuNzAzOSAxOS40MzUxIDcyLjY1NjEgMTkuMTE1OCA3Mi42NTYxQzE4LjgwNDUgNzIuNjU2MSAxOC41MjUyIDcyLjcxMTkgMTguMjY5OCA3Mi44MzE2QzE4LjAxNDQgNzIuOTUxNCAxNy43OTA5IDczLjEwMyAxNy42MTUzIDczLjI4NjZDMTcuNDM5NyA3My40NzAyIDE3LjI5NiA3My42Nzc3IDE3LjIwMDIgNzMuOTA5MkMxNy4xMDQ1IDc0LjE0MDYgMTcuMDU2NiA3NC4zNjQxIDE3LjA1NjYgNzQuNTg3NkgyMS4wNDczVjc0LjU4NzZaIiBmaWxsPSJ3aGl0ZSIvPjxwYXRoIGQ9Ik0yNy44MTU3IDY3Ljg1MTJIMjkuMDc2OFY3Mi43Njc4SDI5LjEwMDdDMjkuMzI0MiA3Mi40MjQ2IDI5LjY1MTUgNzIuMTQ1MiAzMC4wNjY1IDcxLjk0NTdDMzAuNDg5NSA3MS43NDYyIDMwLjkzNjUgNzEuNjQyNCAzMS40MTU0IDcxLjY0MjRDMzEuOTI2MiA3MS42NDI0IDMyLjM5NzEgNzEuNzMwMiAzMi44MTIyIDcxLjkwNThDMzMuMjI3MiA3Mi4wODE0IDMzLjU4NjQgNzIuMzI4OCAzMy44ODE3IDcyLjY0MDFDMzQuMTc3IDcyLjk1MTQgMzQuNDAwNSA3My4zMjY1IDM0LjU2MDEgNzMuNzQ5NUMzNC43MTk3IDc0LjE3MjYgMzQuNzk5NiA3NC42MzU1IDM0Ljc5OTYgNzUuMTMwM0MzNC43OTk2IDc1LjYyNTIgMzQuNzE5NyA3Ni4wODgxIDM0LjU2MDEgNzYuNTAzMkMzNC40MDA1IDc2LjkyNjIgMzQuMTc3IDc3LjI5MzMgMzMuODgxNyA3Ny42MTI2QzMzLjU4NjQgNzcuOTMxOSAzMy4yMjcyIDc4LjE3OTMgMzIuODEyMiA3OC4zNTQ5QzMyLjM5NzEgNzguNTMwNSAzMS45MjYyIDc4LjYxODMgMzEuNDE1NCA3OC42MTgzQzMwLjk2ODQgNzguNjE4MyAzMC41Mjk0IDc4LjUyMjUgMzAuMTA2NCA3OC4zMjNDMjkuNjgzNCA3OC4xMjM0IDI5LjM0ODIgNzcuODUyIDI5LjEwMDcgNzcuNDkyOUgyOS4wNzY4Vjc4LjQ1MDdIMjcuODE1N1Y2Ny44NTEyWk0zMS4yNzE3IDc3LjQ1M0MzMS42MDY5IDc3LjQ1MyAzMS45MTAyIDc3LjM5NzEgMzIuMTgxNiA3Ny4yNzc0QzMyLjQ1MyA3Ny4xNTc3IDMyLjY4NDUgNzYuOTk4IDMyLjg2OCA3Ni43OTg1QzMzLjA1MTYgNzYuNTk4OSAzMy4yMDMzIDc2LjM1MTUgMzMuMzA3IDc2LjA3MjJDMzMuNDEwOCA3NS43ODQ4IDMzLjQ1ODcgNzUuNDczNSAzMy40NTg3IDc1LjEzODNDMzMuNDU4NyA3NC44MDMxIDMzLjQxMDggNzQuNDkxOCAzMy4zMDcgNzQuMjA0NUMzMy4yMDMzIDczLjkxNzEgMzMuMDU5NiA3My42Nzc3IDMyLjg2OCA3My40NzgyQzMyLjY4NDUgNzMuMjc4NiAzMi40NTMgNzMuMTE5IDMyLjE4MTYgNzIuOTk5M0MzMS45MTAyIDcyLjg3OTUgMzEuNjA2OSA3Mi44MjM3IDMxLjI3MTcgNzIuODIzN0MzMC45MzY1IDcyLjgyMzcgMzAuNjMzMiA3Mi44Nzk1IDMwLjM2MTggNzIuOTk5M0MzMC4wOTA0IDczLjExOSAyOS44NTkgNzMuMjc4NiAyOS42NzU0IDczLjQ3ODJDMjkuNDkxOCA3My42Nzc3IDI5LjM0MDIgNzMuOTI1MSAyOS4yMzY0IDc0LjIwNDVDMjkuMTMyNyA3NC40OTE4IDI5LjA4NDggNzQuODAzMSAyOS4wODQ4IDc1LjEzODNDMjkuMDg0OCA3NS40NzM1IDI5LjEzMjcgNzUuNzg0OCAyOS4yMzY0IDc2LjA3MjJDMjkuMzQwMiA3Ni4zNTk1IDI5LjQ4MzkgNzYuNTk4OSAyOS42NzU0IDc2Ljc5ODVDMjkuODU5IDc2Ljk5OCAzMC4wOTA0IDc3LjE1NzcgMzAuMzYxOCA3Ny4yNzc0QzMwLjYyNTIgNzcuMzk3MSAzMC45Mjg1IDc3LjQ1MyAzMS4yNzE3IDc3LjQ1M1oiIGZpbGw9IndoaXRlIi8+PHBhdGggZD0iTTM3LjM0NTcgNzUuNjAxMkMzNy4zNDU3IDc1Ljg4ODYgMzcuNDA5NSA3Ni4xNiAzNy41MzcyIDc2LjM5MTRDMzcuNjY1IDc2LjYzMDkgMzcuODMyNiA3Ni44MzA0IDM4LjAzMjEgNzYuOTk4QzM4LjIzOTYgNzcuMTY1NiAzOC40NzkxIDc3LjMwMTMgMzguNzUwNCA3Ny4zODkxQzM5LjAyMTggNzcuNDg0OSAzOS4zMDEyIDc3LjUzMjggMzkuNTk2NSA3Ny41MzI4QzM5Ljk4NzYgNzcuNTMyOCA0MC4zMzA4IDc3LjQ0NSA0MC42MTgxIDc3LjI2MTRDNDAuOTA1NSA3Ny4wNzc4IDQxLjE3NjggNzYuODM4NCA0MS40MTYzIDc2LjUzNTFMNDIuMzc0MSA3Ny4yNjE0QzQxLjY3MTcgNzguMTcxMyA0MC42OSA3OC42MjYzIDM5LjQyODkgNzguNjI2M0MzOC45MDIxIDc4LjYyNjMgMzguNDMxMiA3OC41Mzg1IDM4LjAwMDIgNzguMzYyOUMzNy41NzcyIDc4LjE4NzMgMzcuMjEgNzcuOTM5OCAzNi45MjI3IDc3LjYyODZDMzYuNjI3NCA3Ny4zMTczIDM2LjQwMzkgNzYuOTQyMiAzNi4yNDQyIDc2LjUxOTFDMzYuMDg0NiA3Ni4wOTYxIDM2LjAwNDggNzUuNjMzMiAzNi4wMDQ4IDc1LjEzODNDMzYuMDA0OCA3NC42NDM1IDM2LjA5MjYgNzQuMTgwNSAzNi4yNjgyIDczLjc1NzVDMzYuNDQzOCA3My4zMzQ1IDM2LjY4MzIgNzIuOTU5NCAzNi45ODY1IDcyLjY0ODFDMzcuMjg5OCA3Mi4zMzY4IDM3LjY1NyA3Mi4wODk0IDM4LjA3MiA3MS45MTM4QzM4LjQ5NSA3MS43MzgyIDM4Ljk1IDcxLjY1MDQgMzkuNDQ0OCA3MS42NTA0QzQwLjAzNTUgNzEuNjUwNCA0MC41MzAzIDcxLjc1NDEgNDAuOTM3NCA3MS45NjE3QzQxLjM0NDQgNzIuMTY5MiA0MS42Nzk3IDcyLjQ0MDYgNDEuOTQzMSA3Mi43Njc4QzQyLjIwNjUgNzMuMTAzIDQyLjM5OCA3My40NzgyIDQyLjUwOTggNzMuODkzMkM0Mi42Mjk1IDc0LjMwODIgNDIuNjg1MyA3NC43MzEzIDQyLjY4NTMgNzUuMTYyM1Y3NS42MDkySDM3LjM0NTdWNzUuNjAxMlpNNDEuMzM2NSA3NC41ODc2QzQxLjMyODUgNzQuMzA4MiA0MS4yODA2IDc0LjA1MjggNDEuMjAwOCA3My44MTM0QzQxLjEyMSA3My41ODE5IDQxLjAwMTIgNzMuMzc0NCA0MC44NDE2IDczLjIwNjhDNDAuNjgyIDczLjAzMTIgNDAuNDgyNCA3Mi44OTU1IDQwLjI0MyA3Mi43OTk3QzQwLjAwMzUgNzIuNzAzOSAzOS43MjQyIDcyLjY1NjEgMzkuNDA0OSA3Mi42NTYxQzM5LjA5MzcgNzIuNjU2MSAzOC44MTQzIDcyLjcxMTkgMzguNTU4OSA3Mi44MzE2QzM4LjMwMzUgNzIuOTUxNCAzOC4wOCA3My4xMDMgMzcuOTA0NCA3My4yODY2QzM3LjcyODggNzMuNDcwMiAzNy41ODUxIDczLjY3NzcgMzcuNDg5NCA3My45MDkyQzM3LjM5MzYgNzQuMTQwNiAzNy4zNDU3IDc0LjM2NDEgMzcuMzQ1NyA3NC41ODc2SDQxLjMzNjVWNzQuNTg3NloiIGZpbGw9IndoaXRlIi8+PHBhdGggZD0iTTQzLjQxMTcgNzEuODFINDQuODcyM0w0Ni44NDM3IDc3LjAwNkg0Ni44NzU2TDQ4Ljc2NzMgNzEuODFINTAuMTE2Mkw0Ni45NTU1IDc5Ljg5NTNDNDYuODQzNyA4MC4xODI3IDQ2LjcyNCA4MC40NTQgNDYuNjA0MyA4MC42ODU1QzQ2LjQ4NDUgODAuOTI1IDQ2LjM0MDkgODEuMTI0NSA0Ni4xNzMzIDgxLjI5MjFDNDYuMDA1NyA4MS40NTk3IDQ1LjgwNjEgODEuNTk1NCA0NS41NjY3IDgxLjY4MzJDNDUuMzI3MiA4MS43NzkgNDUuMDM5OSA4MS44MjY5IDQ0LjY5NjcgODEuODI2OUM0NC41MTMxIDgxLjgyNjkgNDQuMzIxNSA4MS44MTg5IDQ0LjEzIDgxLjc5NDlDNDMuOTM4NCA4MS43NzEgNDMuNzU0OSA4MS43MjMxIDQzLjU3OTMgODEuNjUxM0w0My43MzA5IDgwLjUwMTlDNDMuOTc4MyA4MC42MDU3IDQ0LjIzMzggODAuNjUzNiA0NC40ODEyIDgwLjY1MzZDNDQuNjcyNyA4MC42NTM2IDQ0Ljg0MDMgODAuNjI5NiA0NC45NzYgODAuNTczOEM0NS4xMTE3IDgwLjUxNzkgNDUuMjIzNSA4MC40NDYxIDQ1LjMyNzIgODAuMzUwM0M0NS40MjMgODAuMjU0NSA0NS41MDI4IDgwLjEzNDggNDUuNTc0NyA4MC4wMDcxQzQ1LjYzODUgNzkuODc5NCA0NS43MDI0IDc5LjcyNzcgNDUuNzY2MiA3OS41NjAxTDQ2LjE3MzMgNzguNTA2NUw0My40MTE3IDcxLjgxWiIgZmlsbD0id2hpdGUiLz48cGF0aCBkPSJNNTAuODk4NCA3NS4xMzgzQzUwLjg5ODQgNzQuNjUxNCA1MC45ODYyIDc0LjE5NjUgNTEuMTY5NyA3My43NzM1QzUxLjM1MzMgNzMuMzUwNSA1MS42MDA4IDcyLjk4MzMgNTEuOTIgNzIuNjY0QzUyLjIzOTMgNzIuMzQ0OCA1Mi42MTQ0IDcyLjA5NzQgNTMuMDQ1NCA3MS45MTM4QzUzLjQ3NjQgNzEuNzMwMiA1My45MzkzIDcxLjY0MjQgNTQuNDM0MiA3MS42NDI0QzU0LjkyOTEgNzEuNjQyNCA1NS4zOTIgNzEuNzMwMiA1NS44MjMgNzEuOTEzOEM1Ni4yNTQgNzIuMDk3NCA1Ni42MjkxIDcyLjM0NDggNTYuOTQ4NCA3Mi42NjRDNTcuMjY3NyA3Mi45ODMzIDU3LjUxNTEgNzMuMzUwNSA1Ny42OTg3IDczLjc3MzVDNTcuODgyMiA3NC4xOTY1IDU3Ljk3IDc0LjY1MTQgNTcuOTcgNzUuMTM4M0M1Ny45NyA3NS42MjUyIDU3Ljg4MjIgNzYuMDgwMSA1Ny42OTg3IDc2LjUwMzJDNTcuNTE1MSA3Ni45MjYyIDU3LjI2NzcgNzcuMzAxMyA1Ni45NDg0IDc3LjYxMjZDNTYuNjI5MSA3Ny45MjM5IDU2LjI1NCA3OC4xNzEzIDU1LjgyMyA3OC4zNTQ5QzU1LjM5MiA3OC41Mzg1IDU0LjkyOTEgNzguNjI2MyA1NC40MzQyIDc4LjYyNjNDNTMuOTM5MyA3OC42MjYzIDUzLjQ3NjQgNzguNTM4NSA1My4wNDU0IDc4LjM1NDlDNTIuNjE0NCA3OC4xNzEzIDUyLjIzOTMgNzcuOTIzOSA1MS45MiA3Ny42MTI2QzUxLjYwMDggNzcuMzAxMyA1MS4zNTMzIDc2LjkyNjIgNTEuMTY5NyA3Ni41MDMyQzUwLjk4NjIgNzYuMDgwMSA1MC44OTg0IDc1LjYyNTIgNTAuODk4NCA3NS4xMzgzWk01Mi4yNDczIDc1LjEzODNDNTIuMjQ3MyA3NS40NzM1IDUyLjI5NTEgNzUuNzg0OCA1Mi4zOTg5IDc2LjA3MjJDNTIuNTAyNyA3Ni4zNTk1IDUyLjY0NjMgNzYuNTk4OSA1Mi44Mzc5IDc2Ljc5ODVDNTMuMDIxNSA3Ni45OTggNTMuMjUyOSA3Ny4xNTc3IDUzLjUyNDMgNzcuMjc3NEM1My43OTU3IDc3LjM5NzEgNTQuMDk5IDc3LjQ1MyA1NC40MzQyIDc3LjQ1M0M1NC43Njk0IDc3LjQ1MyA1NS4wNzI3IDc3LjM5NzEgNTUuMzQ0MSA3Ny4yNzc0QzU1LjYxNTUgNzcuMTU3NyA1NS44NDY5IDc2Ljk5OCA1Ni4wMzA1IDc2Ljc5ODVDNTYuMjE0MSA3Ni41OTg5IDU2LjM2NTcgNzYuMzUxNSA1Ni40Njk1IDc2LjA3MjJDNTYuNTczMyA3NS43ODQ4IDU2LjYyMTIgNzUuNDczNSA1Ni42MjEyIDc1LjEzODNDNTYuNjIxMiA3NC44MDMxIDU2LjU3MzMgNzQuNDkxOCA1Ni40Njk1IDc0LjIwNDVDNTYuMzY1NyA3My45MTcxIDU2LjIyMjEgNzMuNjc3NyA1Ni4wMzA1IDczLjQ3ODJDNTUuODQ2OSA3My4yNzg2IDU1LjYxNTUgNzMuMTE5IDU1LjM0NDEgNzIuOTk5M0M1NS4wNzI3IDcyLjg3OTUgNTQuNzY5NCA3Mi44MjM3IDU0LjQzNDIgNzIuODIzN0M1NC4wOTkgNzIuODIzNyA1My43OTU3IDcyLjg3OTUgNTMuNTI0MyA3Mi45OTkzQzUzLjI1MjkgNzMuMTE5IDUzLjAyMTUgNzMuMjc4NiA1Mi44Mzc5IDczLjQ3ODJDNTIuNjU0MyA3My42Nzc3IDUyLjUwMjcgNzMuOTI1MSA1Mi4zOTg5IDc0LjIwNDVDNTIuMjk1MSA3NC40OTE4IDUyLjI0NzMgNzQuODAzMSA1Mi4yNDczIDc1LjEzODNaIiBmaWxsPSJ3aGl0ZSIvPjxwYXRoIGQ9Ik01OS41NTgzIDcxLjgxSDYwLjgxOTRWNzIuODMxN0g2MC44NDM0QzYxLjAwMyA3Mi40NzI1IDYxLjI4MjQgNzIuMTg1MiA2MS42NzM1IDcxLjk2OTdDNjIuMDY0NiA3MS43NDYyIDYyLjUxOTUgNzEuNjQyNCA2My4wMzgzIDcxLjY0MjRDNjMuMzU3NiA3MS42NDI0IDYzLjY2MDkgNzEuNjkwMyA2My45NTYyIDcxLjc4NjFDNjQuMjUxNSA3MS44ODE5IDY0LjUwNjkgNzIuMDMzNSA2NC43MzA0IDcyLjI0MUM2NC45NTM5IDcyLjQ0ODUgNjUuMTI5NSA3Mi43MTE5IDY1LjI1NzIgNzMuMDMxMkM2NS4zODQ5IDczLjM1MDUgNjUuNDU2NyA3My43MzM2IDY1LjQ1NjcgNzQuMTcyNlY3OC40NTg3SDY0LjE5NTZWNzQuNTIzOEM2NC4xOTU2IDc0LjIxMjUgNjQuMTU1NyA3My45NDkxIDY0LjA2NzkgNzMuNzMzNkM2My45ODAxIDczLjUxMDEgNjMuODY4NCA3My4zMzQ1IDYzLjczMjcgNzMuMTk4OEM2My41ODkgNzMuMDYzMSA2My40Mjk0IDcyLjk2NzMgNjMuMjQ1OCA3Mi45MDM1QzYzLjA2MjIgNzIuODM5NiA2Mi44NzA3IDcyLjgxNTcgNjIuNjc5MSA3Mi44MTU3QzYyLjQxNTcgNzIuODE1NyA2Mi4xNzYzIDcyLjg1NTYgNjEuOTUyOCA3Mi45NDM0QzYxLjcyOTMgNzMuMDMxMiA2MS41Mjk4IDczLjE1ODkgNjEuMzYyMiA3My4zNDI1QzYxLjE5NDYgNzMuNTI2MSA2MS4wNTg5IDczLjc1NzUgNjAuOTcxMSA3NC4wMzY5QzYwLjg3NTMgNzQuMzE2MiA2MC44Mjc0IDc0LjY1MTUgNjAuODI3NCA3NS4wMzQ2Vjc4LjQ1ODdINTkuNTY2M1Y3MS44MUg1OS41NTgzWiIgZmlsbD0id2hpdGUiLz48cGF0aCBkPSJNNzQuMDM2OSA3OC40NjY2SDcyLjc3NThWNzcuNTA4OUg3Mi43NDM5QzcyLjQ5NjQgNzcuODY4IDcyLjE2OTIgNzguMTM5NCA3MS43MzgyIDc4LjMzODlDNzEuMzE1MiA3OC41Mzg1IDcwLjg3NjIgNzguNjM0MiA3MC40MjkyIDc4LjYzNDJDNjkuOTEwNCA3OC42MzQyIDY5LjQ0NzUgNzguNTQ2NSA2OS4wMzI0IDc4LjM3MDlDNjguNjE3NCA3OC4xOTUzIDY4LjI1ODIgNzcuOTQ3OCA2Ny45NjI5IDc3LjYyODZDNjcuNjY3NiA3Ny4zMDkzIDY3LjQ0NDEgNzYuOTQyMiA2Ny4yODQ1IDc2LjUxOTFDNjcuMTI0OSA3Ni4wOTYxIDY3LjA0NSA3NS42NDEyIDY3LjA0NSA3NS4xNDYzQzY3LjA0NSA3NC42NTE1IDY3LjEyNDkgNzQuMTg4NSA2Ny4yODQ1IDczLjc2NTVDNjcuNDQ0MSA3My4zNDI1IDY3LjY2NzYgNzIuOTY3MyA2Ny45NjI5IDcyLjY1NjFDNjguMjU4MiA3Mi4zNDQ4IDY4LjYxNzQgNzIuMDk3NCA2OS4wMzI0IDcxLjkyMThDNjkuNDQ3NSA3MS43NDYyIDY5LjkxODQgNzEuNjU4NCA3MC40MjkyIDcxLjY1ODRDNzAuOTA4MSA3MS42NTg0IDcxLjM1NTEgNzEuNzYyMSA3MS43NzgxIDcxLjk2MTdDNzIuMjAxMSA3Mi4xNjEyIDcyLjUyMDQgNzIuNDQwNiA3Mi43NDM5IDcyLjc4MzhINzIuNzc1OFY2Ny44NjcxSDc0LjAzNjlWNzguNDY2NlY3OC40NjY2Wk03MC41ODA5IDc3LjQ1M0M3MC45MTYxIDc3LjQ1MyA3MS4yMTk0IDc3LjM5NzEgNzEuNDkwOCA3Ny4yNzc0QzcxLjc2MjEgNzcuMTU3NyA3MS45OTM2IDc2Ljk5OCA3Mi4xNzcyIDc2Ljc5ODVDNzIuMzYwNyA3Ni41OTkgNzIuNTEyNCA3Ni4zNTE1IDcyLjYxNjIgNzYuMDcyMkM3Mi43MTk5IDc1Ljc4NDggNzIuNzY3OCA3NS40NzM2IDcyLjc2NzggNzUuMTM4M0M3Mi43Njc4IDc0LjgwMzEgNzIuNzE5OSA3NC40OTE4IDcyLjYxNjIgNzQuMjA0NUM3Mi41MTI0IDczLjkxNzIgNzIuMzY4NyA3My42Nzc3IDcyLjE3NzIgNzMuNDc4MkM3MS45OTM2IDczLjI3ODYgNzEuNzYyMSA3My4xMTkgNzEuNDkwOCA3Mi45OTkzQzcxLjIxOTQgNzIuODc5NSA3MC45MTYxIDcyLjgyMzcgNzAuNTgwOSA3Mi44MjM3QzcwLjI0NTYgNzIuODIzNyA2OS45NDIzIDcyLjg3OTUgNjkuNjcxIDcyLjk5OTNDNjkuMzk5NiA3My4xMTkgNjkuMTY4MSA3My4yNzg2IDY4Ljk4NDYgNzMuNDc4MkM2OC44MDEgNzMuNjc3NyA2OC42NDkzIDczLjkyNTEgNjguNTQ1NiA3NC4yMDQ1QzY4LjQ0MTggNzQuNDkxOCA2OC4zOTM5IDc0LjgwMzEgNjguMzkzOSA3NS4xMzgzQzY4LjM5MzkgNzUuNDczNiA2OC40NDE4IDc1Ljc4NDggNjguNTQ1NiA3Ni4wNzIyQzY4LjY0OTMgNzYuMzU5NSA2OC43OTMgNzYuNTk5IDY4Ljk4NDYgNzYuNzk4NUM2OS4xNjgxIDc2Ljk5OCA2OS4zOTk2IDc3LjE1NzcgNjkuNjcxIDc3LjI3NzRDNjkuOTQyMyA3Ny4zOTcxIDcwLjI0NTYgNzcuNDUzIDcwLjU4MDkgNzcuNDUzWiIgZmlsbD0id2hpdGUiLz48cGF0aCBkPSJNNzYuOTQyMiA3OC41NDY1Qzc2LjY4NjggNzguNTQ2NSA3Ni40NzEzIDc4LjQ1ODcgNzYuMjg3NyA3OC4yNzUxQzc2LjEwNDEgNzguMDkxNSA3Ni4wMTYzIDc3Ljg3NiA3Ni4wMTYzIDc3LjYyMDZDNzYuMDE2MyA3Ny4zNjUyIDc2LjEwNDEgNzcuMTQ5NyA3Ni4yODc3IDc2Ljk2NjFDNzYuNDcxMyA3Ni43ODI1IDc2LjY4NjggNzYuNjk0NyA3Ni45NDIyIDc2LjY5NDdDNzcuMTk3NiA3Ni42OTQ3IDc3LjQxMzEgNzYuNzgyNSA3Ny41OTY3IDc2Ljk2NjFDNzcuNzgwMiA3Ny4xNDk3IDc3Ljg2OCA3Ny4zNjUyIDc3Ljg2OCA3Ny42MjA2Qzc3Ljg2OCA3Ny44NzYgNzcuNzgwMiA3OC4wOTE1IDc3LjU5NjcgNzguMjc1MUM3Ny40MTMxIDc4LjQ1ODcgNzcuMTk3NiA3OC41NDY1IDc2Ljk0MjIgNzguNTQ2NVoiIGZpbGw9IndoaXRlIi8+PC9nPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHdpZHRoPSIyMDciIGhlaWdodD0iOTAiIGZpbGw9IndoaXRlIi8+PC9jbGlwUGF0aD48L2RlZnM+PC9zdmc+),url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAiIGhlaWdodD0iOTAiIHZpZXdCb3g9IjAgMCA5MCA5MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBjbGlwLXBhdGg9InVybCgjY2xpcDApIj48cGF0aCBkPSJNNS41ODIwNCAxLjkzMTQ4TDEuNzMzMDMgNS43ODA0OUwxMS43NDUgMTUuNzkyNUwxNS41OTQxIDExLjk0MzVMNS41ODIwNCAxLjkzMTQ4WiIgZmlsbD0id2hpdGUiLz48cGF0aCBkPSJNMTQuMDY0IDQyLjMwMjJILTAuMDk1NDU5VjQ3Ljc0NTdIMTQuMDY0VjQyLjMwMjJaIiBmaWxsPSJ3aGl0ZSIvPjxwYXRoIGQ9Ik04NC4wMjQzIDEuODMzOTNMNzQuMDEyMyAxMS44NDU5TDc3Ljg2MTMgMTUuNjk1TDg3Ljg3MzQgNS42ODI5N0w4NC4wMjQzIDEuODMzOTNaIiBmaWxsPSJ3aGl0ZSIvPjxwYXRoIGQ9Ik00Ny41MDY1IDBINDIuMDYzMVYxNC4xNTkzSDQ3LjUwNjVWMFoiIGZpbGw9IndoaXRlIi8+PHBhdGggZD0iTTg5Ljg4ODcgNDIuMTgyNUg3NS43MjkzVjQ3LjYyNTlIODkuODg4N1Y0Mi4xODI1WiIgZmlsbD0id2hpdGUiLz48cGF0aCBkPSJNNzcuODU5NCA3NC4yMTg3TDc0LjAxMDMgNzguMDY3OEw4NC4wMjIyIDg4LjA3OThMODcuODcxMyA4NC4yMzA3TDc3Ljg1OTQgNzQuMjE4N1oiIGZpbGw9IndoaXRlIi8+PHBhdGggZD0iTTExLjc0MzQgNzQuMzE2MkwxLjczMTMyIDg0LjMyODJMNS41ODAzNyA4OC4xNzczTDE1LjU5MjQgNzguMTY1M0wxMS43NDM0IDc0LjMxNjJaIiBmaWxsPSJ3aGl0ZSIvPjxwYXRoIGQ9Ik00Ny41NTQ0IDc1Ljg0MDdINDIuMTExVjkwSDQ3LjU1NDRWNzUuODQwN1oiIGZpbGw9IndoaXRlIi8+PC9nPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHdpZHRoPSI5MCIgaGVpZ2h0PSI5MCIgZmlsbD0id2hpdGUiLz48L2NsaXBQYXRoPjwvZGVmcz48L3N2Zz4=);background-repeat:no-repeat,no-repeat;background-size:auto 56px,56px;background-position:left 84px top 84px,right 84px top 84px;display:flex;flex-direction:column;justify-content:flex-end}div#p>svg>foreignObject>section.title h1{padding-bottom:14px;margin-top:0;margin-bottom:1rem;font-size:49px }@media (min-width:400px){div#p>svg>foreignObject>section.title h1{font-size:calc(3vw + 37px);line-height:1.1 }}@media (min-width:1100px){div#p>svg>foreignObject>section.title h1{font-size:70px }}div#p>svg>foreignObject>section.title>:last-child{margin-bottom:0;padding-bottom:0}div#p>svg>foreignObject>section.quote-small{display:flex;flex-direction:column;justify-content:center}div#p>svg>foreignObject>section.quote-small h1{padding-bottom:14px;margin-top:0;margin-bottom:1rem;font-weight:600;font-size:42px ;font-weight:400!important}@media (min-width:400px){div#p>svg>foreignObject>section.quote-small h1{font-size:calc(2vw + 34px);line-height:1.1 }}@media (min-width:1100px){div#p>svg>foreignObject>section.quote-small h1{font-size:56px }}div#p>svg>foreignObject>section.quote-small>:last-child{margin-bottom:0;padding-bottom:0}div#p>svg>foreignObject>section.quote-large{display:flex;flex-direction:column;justify-content:center}div#p>svg>foreignObject>section.quote-large h1{padding-bottom:14px;margin-top:0;margin-bottom:1rem;font-size:49px }@media (min-width:400px){div#p>svg>foreignObject>section.quote-large h1{font-size:calc(3vw + 37px);line-height:1.1 }}@media (min-width:1100px){div#p>svg>foreignObject>section.quote-large h1{font-size:70px }}div#p>svg>foreignObject>section.quote-large>:last-child{margin-bottom:0;padding-bottom:0}div#p>svg>foreignObject>section.table table{table-layout:fixed;border-collapse:collapse;width:100%}div#p>svg>foreignObject>section.table table td,div#p>svg>foreignObject>section.table table th{padding:7px 0}div#p>svg>foreignObject>section.table table th{text-align:left;font-weight:600}div#p>svg>foreignObject>section.table table td{border-width:1px 0;border-style:solid;border-color:rgba(255,255,255,0.5)}div#p>svg>foreignObject>section[data-marpit-advanced-background=background]{display:block!important;padding:0!important}div#p>svg>foreignObject>section[data-marpit-advanced-background=background]:after,div#p>svg>foreignObject>section[data-marpit-advanced-background=background]:before,div#p>svg>foreignObject>section[data-marpit-advanced-background=content]:after,div#p>svg>foreignObject>section[data-marpit-advanced-background=content]:before{display:none!important}div#p>svg>foreignObject>section[data-marpit-advanced-background=background]>div[data-marpit-advanced-background-container]{all:initial;display:flex;flex-direction:row;height:100%;overflow:hidden;width:100%}div#p>svg>foreignObject>section[data-marpit-advanced-background=background]>div[data-marpit-advanced-background-container][data-marpit-advanced-background-direction=vertical]{flex-direction:column}div#p>svg>foreignObject>section[data-marpit-advanced-background=background][data-marpit-advanced-background-split]>div[data-marpit-advanced-background-container]{width:var(--marpit-advanced-background-split,50%)}div#p>svg>foreignObject>section[data-marpit-advanced-background=background][data-marpit-advanced-background-split=right]>div[data-marpit-advanced-background-container]{margin-left:calc(100% - var(--marpit-advanced-background-split, 50%))}div#p>svg>foreignObject>section[data-marpit-advanced-background=background]>div[data-marpit-advanced-background-container]>figure{all:initial;background-position:center;background-repeat:no-repeat;background-size:cover;flex:auto;margin:0}div#p>svg>foreignObject>section[data-marpit-advanced-background=content],div#p>svg>foreignObject>section[data-marpit-advanced-background=pseudo]{background:transparent!important}div#p>svg>foreignObject>section[data-marpit-advanced-background=pseudo],div#p>svg[data-marpit-svg]>foreignObject[data-marpit-advanced-background=pseudo]{pointer-events:none!important}div#p>svg>foreignObject>section[data-marpit-advanced-background-split]{width:100%;height:100%}</style></head><body><div class="bespoke-marp-osc"><button data-bespoke-marp-osc="prev" tabindex="-1" title="Previous slide">Previous slide</button><span data-bespoke-marp-osc="page"></span><button data-bespoke-marp-osc="next" tabindex="-1" title="Next slide">Next slide</button><button data-bespoke-marp-osc="fullscreen" tabindex="-1" title="Toggle fullscreen (f)">Toggle fullscreen</button></div><div id="p"><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="1" data-class="title" data-theme="microblink" class="title" style="--class:title;--theme:microblink;">
<h1>Porting your C++ code to the web with Emscripten</h1>
<p>Nenad Mikša, Head of TSI @ Microblink</p>
<p>@dodo at <a href="http://cpplang.slack.com">cpplang.slack.com</a><br />
<a href="mailto:meetup@microblink.com">meetup@microblink.com</a></p>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="2" data-theme="microblink" style="--theme:microblink;">
<h1>Emscripten</h1>
<p>From <a href="https://emscripten.org">emscripten.org</a>:</p>
<blockquote>
<p>a toolchain for compiling to asm.js and WebAssembly, built using LLVM, that lets you run C and C++ on the web at near-native speed without plugins.</p>
</blockquote>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="3" data-theme="microblink" style="--theme:microblink;">
<h1>Emscripten</h1>
<ul>
<li>compiler based on LLVM (clang)</li>
<li>SDK providing common libraries
<ul>
<li>file system IO, OpenGL, SDL, threading, networking, ...</li>
</ul>
</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="4" data-theme="microblink" style="--theme:microblink;">
<h1>Emscripten compiler</h1>
<ul>
<li>frontend
<ul>
<li>a python script</li>
</ul>
</li>
<li>backend
<ul>
<li>a c++ compiler</li>
<li>two available backends:
<ul>
<li>fastcomp</li>
<li>upstream</li>
</ul>
</li>
</ul>
</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="5" data-theme="microblink" style="--theme:microblink;">
<h2>Fastcomp backend</h2>
<ul>
<li>compilation steps:
<ul>
<li>C++ ➞ Bitcode</li>
</ul>
</li>
<li>linking steps:
<ul>
<li>Bitcode ➞ Javascript ➞ WebAssembly</li>
</ul>
</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="6" data-theme="microblink" style="--theme:microblink;">
<h3>Fastcomp build steps</h3>
<ul>
<li>C++ ➞ Bitcode
<ul>
<li>based on clang 6 (partial c++17 support)</li>
</ul>
</li>
<li>Bitcode ➞ Javascript
<ul>
<li>custom LLVM backend (<em>fastcomp</em>)</li>
<li>not available in mainline LLVM</li>
</ul>
</li>
<li>Javascript ➞ WebAssembly
<ul>
<li><em>asm2wasm</em> - part of <a href="https://github.com/WebAssembly/binaryen">binaryen project</a></li>
</ul>
</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="7" data-theme="microblink" style="--theme:microblink;">
<h3>Fastcomp backend - advantages and disadvantages</h3>
<ul>
<li>slow linking phase
<ul>
<li>effectively LTO always enabled</li>
</ul>
</li>
<li>suboptimal performance and code size
<ul>
<li>due to Javascript in compilation step</li>
</ul>
</li>
<li>stable</li>
<li>default backend until very recently (December 2019)</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="8" data-theme="microblink" style="--theme:microblink;">
<h2>Upstream backend</h2>
<ul>
<li>compilation steps:
<ul>
<li>C++ ➞ WebAssembly</li>
</ul>
</li>
<li>linking steps:
<ul>
<li>concatenation of WebAssembly object files</li>
<li>dead code removal</li>
<li>optionally <em>wasm2js</em></li>
</ul>
</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="9" data-theme="microblink" style="--theme:microblink;">
<h3>Upstream build steps</h3>
<ul>
<li>C++ ➞ WebAssembly
<ul>
<li>based on upstream LLVM project (currently clang 10)</li>
<li>all latest C++ features</li>
</ul>
</li>
<li>WebAssembly ➞ Javascript
<ul>
<li>optional - only to support old browsers</li>
</ul>
</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="10" data-theme="microblink" style="--theme:microblink;">
<h3>Upstream backend - advantages and disadvantages</h3>
<ul>
<li>fast linking</li>
<li>supports latest c++ features</li>
<li>direct C++ ➞ WebAssembly compilation</li>
<li>part of mainline LLVM</li>
<li>default backend as of emscripten v1.39.0</li>
<li>still too unstable for production use
<ul>
<li>common compiler crashes (ICEs)</li>
</ul>
</li>
<li>LTO completely broken</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="11" data-theme="microblink" style="--theme:microblink;">
<h1>WebAssembly</h1>
<p>From <a href="https://webassembly.org">webassembly.org</a>:</p>
<blockquote>
<p>a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.</p>
</blockquote>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="12" data-class="table" data-theme="microblink" class="table" style="--class:table;--theme:microblink;">
<h2>Differences to Javascript</h2>
<table>
<thead>
<tr>
<th style="text-align:left">WebAssembly</th>
<th style="text-align:left">Javascript</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">binary</td>
<td style="text-align:left">textual</td>
</tr>
<tr>
<td style="text-align:left">low-level (difficult to decompile)</td>
<td style="text-align:left">high-level (difficult to obfuscate)</td>
</tr>
<tr>
<td style="text-align:left">AOT compilation</td>
<td style="text-align:left">JIT</td>
</tr>
<tr>
<td style="text-align:left">custom memory</td>
<td style="text-align:left">garbage-collected heap</td>
</tr>
</tbody>
</table>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="13" data-class="table" data-theme="microblink" class="table" style="--class:table;--theme:microblink;">
<h2>Current limitations of WebAssembly</h2>
<ul>
<li>no support for threads</li>
<li>no support for SIMD</li>
<li>no access to system resources (files, network sockets, ...)</li>
<li>behaves as an embedded system</li>
<li>needs initialization from Javascript</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="14" data-class="table" data-theme="microblink" class="table" style="--class:table;--theme:microblink;">
<h2>Future of WebAssembly</h2>
<ul>
<li>support for <a href="https://github.com/WebAssembly/proposals/issues/14">threads</a></li>
<li>support for <a href="https://github.com/WebAssembly/proposals/issues/1">SIMD</a></li>
<li><a href="https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/">WebAssembly System Interface</a>
<ul>
<li>will provide access to system resources without the need for JS glue code</li>
</ul>
</li>
<li>avoiding JS initialization code (<a href="https://github.com/WebAssembly/proposals/issues/12">ES6 module integration</a>)</li>
<li><a href="https://webassembly.org/docs/future-features/">full list of planned features</a></li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="15" data-class="table" data-theme="microblink" class="table" style="--class:table;--theme:microblink;">
<h1>Emscripten SDK</h1>
<ul>
<li>provides missing WebAssembly features in terms of Javascript glue code
<ul>
<li><a href="https://emscripten.org/docs/porting/pthreads.html">threads using WebWorkers and SharedArrayBuffer</a></li>
<li><a href="https://emscripten.org/docs/porting/files/index.html">file system support</a></li>
<li><a href="https://emscripten.org/docs/porting/Audio.html">OpenAL implementation using Audio API</a></li>
<li><a href="https://emscripten.org/docs/porting/multimedia_and_graphics/index.html">EGL and OpenGL implementation using WebGL</a></li>
</ul>
</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="16" data-class="table" data-theme="microblink" class="table" style="--class:table;--theme:microblink;">
<h1>Emscripten SDK (continued)</h1>
<ul>
<li><a href="https://emscripten.org/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html#interacting-with-code">supports mixing C++ and Javascript code</a></li>
<li><a href="https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html">provides a simple facility for exporting C++ functions to Javascript</a></li>
<li>automatically generates JS initialization code</li>
<li>provides CMake toolchain file for easy porting of CMake-based projects</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="17" data-class="table" data-theme="microblink" class="table" style="--class:table;--theme:microblink;">
<h2>POSIX threads support</h2>
<ul>
<li>simply compile and link your code with <code>-s USE_PTHREADS=1</code> and use the usual <code>pthread_*</code> set of functions or <code>std::thread</code></li>
<li>features require support for <a href="https://developer.mozilla.org/en-US/docs/Web/API/Worker">WebWorkers</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer">SharedArrayBuffer</a>
<ul>
<li>SharedArrayBuffer disabled in most browsers due to <a href="https://meltdownattack.com">Spectre and Meltdown set of bugs</a></li>
<li>however, it's available in Google Chrome for Desktop v67 and above</li>
</ul>
</li>
<li>if building without thread support, <code>pthread_*</code> functions are still available, but calling them will crash your code</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="18" data-class="table" data-theme="microblink" class="table" style="--class:table;--theme:microblink;">
<h2>File system support</h2>
<ul>
<li>implemented with standard <code>fopen</code> and friends</li>
<li>works with <code>std::fstream</code> and other abstractions over <code>fopen</code> and friends</li>
<li>all required files need to be packaged at link time using <code>--preload-file</code> linker option
<ul>
<li><code>--preload-file real/path@/virtual/path</code></li>
<li>all packaged files are packed into a single <code>.data</code> file</li>
<li>automatically generated JS code automatically downloads the <code>.data</code> file and initializes the virtual file system during runtime initialization</li>
</ul>
</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="19" data-class="table" data-theme="microblink" class="table" style="--class:table;--theme:microblink;">
<h2>File writing support</h2>
<ul>
<li>multiple backends for standard functions:
<ul>
<li>MEMFS
<ul>
<li>in-memory, all writes lost after page reload</li>
</ul>
</li>
<li>NODEFS
<ul>
<li>wraps NodeJS filesystem functions</li>
</ul>
</li>
<li>IDBFS
<ul>
<li>uses browser's IndexedDB for storing data</li>
</ul>
</li>
<li>WORKERFS
<ul>
<li>read-only access to <code>File</code> and <code>Blob</code> objects inside a web worker</li>
</ul>
</li>
</ul>
</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="20" data-class="table" data-theme="microblink" class="table" style="--class:table;--theme:microblink;">
<h2>File system backends</h2>
<ul>
<li>by default, MEMFS is used (and is always mounted at <code>/</code>)</li>
<li>Javascript code can initialize other backends for other mount points
<ul>
<li>this is currently not possible from C++ <img class="emoji" draggable="false" alt="😞" src="https://twemoji.maxcdn.com/2/svg/1f61e.svg" data-marp-twemoji=""/></li>
</ul>
</li>
<li>Emscripten also has its own <a href="https://emscripten.org/docs/api_reference/emscripten.h.html#emscripten-h-asynchronous-file-system-api">Asynchronous File System API</a>
<ul>
<li>API to fetch files from the web asynchronously</li>
<li>a separate API, not a backend for <code>fopen</code> and friends</li>
</ul>
</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="21" data-class="table" data-theme="microblink" class="table" style="--class:table;--theme:microblink;">
<h2>EGL and OpenGL ES</h2>
<ul>
<li>imlemented with JS glue code forwarding GL calls to WebGL</li>
<li><a href="https://emscripten.org/docs/porting/multimedia_and_graphics/EGL-Support-in-Emscripten.html">EGL</a> used for creating WebGL context
<ul>
<li>identical procedure as in Android NDK</li>
</ul>
</li>
<li><a href="https://emscripten.org/docs/porting/multimedia_and_graphics/OpenGL-support.html">WebGL is subset of OpenGL ES 2.0/3.0</a>
<ul>
<li>if only compatible features are used, mapping is 1:1</li>
<li>Emscripten also supports emulating OpenGL ES features not available in WebGL
<ul>
<li>however, this comes with some performance cost</li>
</ul>
</li>
</ul>
</li>
<li>both WebGL 1 and WebGL 2 are supported</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="22" data-class="table" data-theme="microblink" class="table" style="--class:table;--theme:microblink;">
<h2>Mixing C++ and Javascript code</h2>
<pre><code class="language-c++"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><emscripten.h></span></span>
EM_JS(<span class="hljs-keyword">void</span>, call_alert, (), {
alert(<span class="hljs-string">'hello world!'</span>);
<span class="hljs-keyword">throw</span> <span class="hljs-string">'all done'</span>;
});
<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
call_alert();
<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="23" data-class="table" data-theme="microblink" class="table" style="--class:table;--theme:microblink;">
<h3>Inline mixing of code</h3>
<pre><code class="language-c++"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><emscripten.h></span></span>
<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>{
EM_ASM(
alert(<span class="hljs-string">'hello world!'</span>);
<span class="hljs-keyword">throw</span> <span class="hljs-string">'all done'</span>;
);
<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
</code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="24" data-class="table" data-theme="microblink" class="table" style="--class:table;--theme:microblink;">
<h2>Passing parameters from C++ to JS</h2>
<pre><code class="language-c++"><span class="hljs-keyword">template</span>< <span class="hljs-keyword">typename</span> Outcome >
<span class="hljs-function"><span class="hljs-keyword">auto</span> <span class="hljs-title">succeedOrDie</span><span class="hljs-params">( Outcome && outcome )</span> </span>{
<span class="hljs-keyword">if</span> ( outcome.has_value() ) {
<span class="hljs-keyword">return</span> <span class="hljs-built_in">std</span>::forward< Outcome >( outcome ).value();
} <span class="hljs-keyword">else</span> {
EM_ASM_( {
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Error( UTF8ToString( $<span class="hljs-number">0</span> ) );
}, outcome.error().data() );
}
}
</code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="25" data-class="table" data-theme="microblink" class="table" style="--class:table;--theme:microblink;">
<h2>Exporting C++ functions to Javascript</h2>
<pre><code class="language-c++"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><math.h></span></span>
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string"><emscripten.h></span></span>
<span class="hljs-function">EMSCRIPTEN_KEEPALIVE
<span class="hljs-keyword">int</span> <span class="hljs-title">int_sqrt</span><span class="hljs-params">(<span class="hljs-keyword">int</span> x)</span> </span>{
<span class="hljs-keyword">return</span> <span class="hljs-built_in">sqrt</span>(x);
}
</code></pre>
<p>To call from Javascript, use <code>cwrap</code> or <code>ccall</code>:</p>
<pre><code class="language-js"><span class="hljs-keyword">var</span> int_sqrt = Module.cwrap(<span class="hljs-string">'int_sqrt'</span>, <span class="hljs-string">'number'</span>, [<span class="hljs-string">'number'</span>]);
<span class="hljs-keyword">var</span> result = int_sqrt(<span class="hljs-number">12</span>);
</code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="26" data-class="table" data-theme="microblink" class="table" style="--class:table;--theme:microblink;">
<h2>Exporting C++ functions to Javascript (2)</h2>
<p>Calling with <code>ccall</code>:</p>
<pre><code class="language-js"><span class="hljs-comment">// Call C from JavaScript</span>
<span class="hljs-keyword">var</span> result = Module.ccall(<span class="hljs-string">'int_sqrt'</span>, <span class="hljs-comment">// name of C function</span>
<span class="hljs-string">'number'</span>, <span class="hljs-comment">// return type</span>
[<span class="hljs-string">'number'</span>], <span class="hljs-comment">// argument types</span>
[<span class="hljs-number">28</span>]); <span class="hljs-comment">// arguments</span>
</code></pre>
<p>Direct call (works only for primitive types):</p>
<pre><code class="language-js"><span class="hljs-keyword">var</span> result = Module._int_sqrt(<span class="hljs-number">28</span>);
</code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="27" data-class="table" data-theme="microblink" class="table" style="--class:table;--theme:microblink;">
<h2>Exporting C++ classes and value objects</h2>
<ul>
<li>very difficult and pointless to do that manually</li>
<li>two possible solutions:
<ul>
<li><a href="https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html">Embind</a></li>
<li><a href="https://emscripten.org/docs/porting/connecting_cpp_and_javascript/WebIDL-Binder.html">WebIDL Binder</a></li>
</ul>
</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="28" data-class="table" data-theme="microblink" class="table" style="--class:table;--theme:microblink;">
<h1>Embind</h1>
<ul>
<li>requires C++14</li>
<li>entire JS interface defined in C++ code</li>
<li>bindings are specified in <code>EMSCRIPTEN_BINDINGS</code> blocks</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="29" data-class="table" data-theme="microblink" class="table" style="--class:table;--theme:microblink;">
<h2>Embind class binding example</h2>
<pre><code class="language-c++"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">EmscriptenFaceDetector</span>
{</span>
<span class="hljs-keyword">public</span>:
EmscriptenFaceDetector();
<span class="hljs-function">EmscriptenFaceDetection <span class="hljs-title">detectFaces</span><span class="hljs-params">( emscripten::val <span class="hljs-keyword">const</span> & jsImageData )</span></span>;
<span class="hljs-keyword">private</span>:
FaceDetector detector_;
cv::Mat rgbaImage_;
};
</code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="30" data-class="table" data-theme="microblink" class="table" style="--class:table;--theme:microblink;">
<h2>Embind bindings code</h2>
<pre><code class="language-c++"><span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> emscripten;
EMSCRIPTEN_BINDINGS( FaceDetector )
{
class_< EmscriptenFaceDetector >( <span class="hljs-string">"FaceDetector"</span> )
.constructor()
.function( <span class="hljs-string">"detectFaces"</span>, &EmscriptenFaceDetector::detectFaces );
}
</code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="31" data-class="table" data-theme="microblink" class="table" style="--class:table;--theme:microblink;">
<h2>JS class usage</h2>
<pre><code class="language-js"><span class="hljs-keyword">var</span> faceDetector = <span class="hljs-keyword">new</span> Module.FaceDetector();
<span class="hljs-keyword">var</span> detectionResult = faceDetector.detectFaces( image );
<span class="hljs-comment">// free the memory</span>
faceDetector.delete();
</code></pre>
<ul>
<li><strong>NOTE</strong>
<ul>
<li>JS does not support finalizers</li>
<li>JS garbage collector will cleanup only the JS proxy object</li>
<li><code>delete</code> must be called to prevent leaks on the emscripten heap</li>
</ul>
</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="32" data-class="table" data-theme="microblink" class="table" style="--class:table;--theme:microblink;">
<h2>Embind value object example</h2>
<pre><code class="language-c++"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">EmscriptenFaceDetection</span>
{</span>
<span class="hljs-keyword">bool</span> detected = <span class="hljs-literal">false</span>;
<span class="hljs-keyword">int</span> x = <span class="hljs-number">0</span>;
<span class="hljs-keyword">int</span> y = <span class="hljs-number">0</span>;
<span class="hljs-keyword">int</span> <span class="hljs-built_in">width</span> = <span class="hljs-number">0</span>;
<span class="hljs-keyword">int</span> <span class="hljs-built_in">height</span> = <span class="hljs-number">0</span>;
};
</code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="33" data-class="table" data-theme="microblink" class="table" style="--class:table;--theme:microblink;">
<h2>Embind bindings code</h2>
<pre><code class="language-c++"><span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> emscripten;
EMSCRIPTEN_BINDINGS( FaceDetector )
{
value_object< EmscriptenFaceDetection >( <span class="hljs-string">"FaceDetection"</span> )
.field( <span class="hljs-string">"detected"</span>, &EmscriptenFaceDetection::detected )
.field( <span class="hljs-string">"x"</span> , &EmscriptenFaceDetection::x )
.field( <span class="hljs-string">"y"</span> , &EmscriptenFaceDetection::y )
.field( <span class="hljs-string">"width"</span> , &EmscriptenFaceDetection::<span class="hljs-built_in">width</span> )
.field( <span class="hljs-string">"height"</span> , &EmscriptenFaceDetection::<span class="hljs-built_in">height</span> );
}
</code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="34" data-class="table" data-theme="microblink" class="table" style="--class:table;--theme:microblink;">
<h2>JS object usage</h2>
<ul>
<li><code>FaceDetection</code> is normal JS object, on JS garbage-collected heap</li>
<li>developer does not need to manually call <code>delete</code></li>
<li>however, each transition of the JS ⬌ WebAssembly boundary creates a new copy</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="35" data-class="table" data-theme="microblink" class="table" style="--class:table;--theme:microblink;">
<h2>Handling JS objects in C++</h2>
<ul>
<li><a href="https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html#using-val-to-transliterate-javascript-to-c"><code>emscripten::val</code> type</a>
<ul>
<li>a proxy type to any JS object</li>
<li>provides utilities for accessing global JS properties</li>
<li>can be used to transliterate JS code into C++</li>
</ul>
</li>
<li>for example, obtaining width and height of the JS <code>ImageData</code> object:</li>
</ul>
<pre><code class="language-c++"><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">obtainImage</span><span class="hljs-params">( emscripten::val <span class="hljs-keyword">const</span> & jsImageData )</span>
</span>{
<span class="hljs-keyword">auto</span> <span class="hljs-built_in">width</span> = jsImageData[ <span class="hljs-string">"width"</span> ].as< <span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">long</span> >();
<span class="hljs-keyword">auto</span> <span class="hljs-built_in">height</span> = jsImageData[ <span class="hljs-string">"height"</span> ].as< <span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">long</span> >();
}
</code></pre>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="36" data-class="table" data-theme="microblink" class="table" style="--class:table;--theme:microblink;">
<h2>Generating modularized Javascript API</h2>
<ul>
<li>by default, all C++ functions and objects are exported as members of global <code>Module</code> object
<ul>
<li>this may cause conflicts with other Emscripten-generated JS libraries</li>
</ul>
</li>
<li>by linking with <code>-s MODULARIZE=1 -s EXPORT_NAME=ModuleName</code> Emscripten will generate a JS function named <code>ModuleName</code> which is used for initialization of WebAssembly</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="37" data-class="quote-large" data-theme="microblink" class="quote-large" style="--class:quote-large;--theme:microblink;">
<h1>Step-by-step example</h1>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="38" data-class="quote-large" data-theme="microblink" class="quote-large" style="--class:quote-large;--theme:microblink;">
<h1>Thank you</h1>
</section>
<script>!function(){"use strict";const t=()=>"Apple Computer, Inc."===navigator.vendor?[e]:[];function e(t){Array.from(document.getElementsByTagName("svg"),e=>{if(e.hasAttribute("data-marpit-svg")){const{clientHeight:r,clientWidth:a}=e;e.style.transform||(e.style.transform="translateZ(0)");const o=t||e.currentScale||1,i=e.viewBox.baseVal.width/o,n=e.viewBox.baseVal.height/o,s=Math.min(r/n,a/i);Array.from(e.querySelectorAll(":scope > foreignObject"),t=>{const e=t.x.baseVal.value,o=t.y.baseVal.value;Array.from(t.querySelectorAll(":scope > section"),t=>{t.style.transformOrigin||(t.style.transformOrigin="0 0");const l=(a-s*i)/2-e,c=(r-s*n)/2-o;t.style.transform=`translate3d(${l}px,${c}px,0) scale(${s}) translate(${e}px,${o}px)`})})}})}const r="data-marp-fitting",a="data-marp-fitting-code",o="data-marp-fitting-math",i=(t,e,r)=>{if(t.getAttribute(e)!==r)return t.setAttribute(e,r),!0};function n(e=!0){for(const e of t())e();Array.from(document.querySelectorAll(`svg[${r}="svg"]`),t=>{const e=t.firstChild,r=e.firstChild,{scrollWidth:n,scrollHeight:s}=r;let l,c=1;if(t.hasAttribute(a)&&(l=t.parentElement.parentElement),t.hasAttribute(o)&&(l=t.parentElement),l){const t=getComputedStyle(l),e=Math.ceil(l.clientWidth-parseFloat(t.paddingLeft)-parseFloat(t.paddingRight));e&&(c=e)}const p=Math.max(n,c),d=Math.max(s,1),m=`0 0 ${p} ${d}`;i(e,"width",`${p}`),i(e,"height",`${d}`),i(t,"preserveAspectRatio",getComputedStyle(t).getPropertyValue("--preserve-aspect-ratio")||"xMinYMin meet"),i(t,"viewBox",m)&&t.classList.toggle("__reflow__")}),e&&window.requestAnimationFrame(()=>n(e))}!function(){if("undefined"==typeof window)throw new Error("Marp Core's browser script is valid only in browser context.");window.marpCoreBrowserScript?console.warn("Marp Core's browser script has already executed."):(Object.defineProperty(window,"marpCoreBrowserScript",{value:!0}),n())}()}();
</script></foreignObject></svg></div><script>!function(){"use strict";var e={from:function(e,t){var n,r=1===(e.parent||e).nodeType?e.parent||e:document.querySelector(e.parent||e),s=[].filter.call("string"==typeof e.slides?r.querySelectorAll(e.slides):e.slides||r.children,(function(e){return"SCRIPT"!==e.nodeName})),o={},a=function(e,t){return(t=t||{}).index=s.indexOf(e),t.slide=e,t},i=function(e,t){o[e]=(o[e]||[]).filter((function(e){return e!==t}))},l=function(e,t){return(o[e]||[]).reduce((function(e,n){return e&&!1!==n(t)}),!0)},c=function(e,t){s[e]&&(n&&l("deactivate",a(n,t)),n=s[e],l("activate",a(n,t)))},u=function(e,t){var r=s.indexOf(n)+e;l(e>0?"next":"prev",a(n,t))&&c(r,t)},d={off:i,on:function(e,t){return(o[e]||(o[e]=[])).push(t),i.bind(null,e,t)},fire:l,slide:function(e,t){if(!arguments.length)return s.indexOf(n);l("slide",a(s[e],t))&&c(e,t)},next:u.bind(null,1),prev:u.bind(null,-1),parent:r,slides:s,destroy:function(e){l("destroy",a(n,e)),o={}}};return(t||[]).forEach((function(e){e(d)})),n||c(0),d}};function t(e){e.parent.classList.add("bespoke-marp-parent"),e.slides.map(e=>e.classList.add("bespoke-marp-slide")),e.on("activate",t=>{e.slides.map(e=>e.classList.remove("bespoke-marp-active")),t.slide.classList.add("bespoke-marp-active")})}function n(e=2e3){return t=>{let n;function r(){n&&clearTimeout(n),n=setTimeout(()=>{t.parent.classList.add("bespoke-marp-inactive")},e),t.parent.classList.remove("bespoke-marp-inactive")}document.addEventListener("mousedown",r),document.addEventListener("mousemove",r),document.addEventListener("touchend",r),setTimeout(r,0)}}const r=["AUDIO","BUTTON","INPUT","SELECT","TEXTAREA","VIDEO"];function s(e){e.parent.addEventListener("keydown",e=>{if(!e.target)return;const t=e.target;(r.includes(t.nodeName)||"true"===t.contentEditable)&&e.stopPropagation()})}function o(e){window.addEventListener("load",()=>{for(const t of e.slides){const e=t.querySelector("[data-marp-fitting]")?"":"hideable";t.setAttribute("data-bespoke-marp-load",e)}})}function a(e){let t=0,n=0;Object.defineProperty(e,"fragments",{enumerable:!0,value:e.slides.map(e=>[null,...e.querySelectorAll("[data-marpit-fragment]")])});const r=r=>void 0!==e.fragments[t][n+r],s=(r,s)=>{t=r,n=s,e.fragments.forEach((e,t)=>{e.forEach((e,n)=>{if(null==e)return;const o=t<r||t===r&&n<=s;e.setAttribute("data-bespoke-marp-fragment",o?"active":"inactive"),t===r&&n===s?e.setAttribute("data-bespoke-marp-current-fragment","current"):e.removeAttribute("data-bespoke-marp-current-fragment")})}),e.fragmentIndex=s;const o={slide:e.slides[r],index:r,fragments:e.fragments[r],fragmentIndex:s};e.fire("fragment",o)};e.on("next",()=>{if(r(1))return s(t,n+1),!1;const o=t+1;e.fragments[o]&&s(o,0)}),e.on("prev",()=>{if(r(-1))return s(t,n-1),!1;const o=t-1;e.fragments[o]&&s(o,e.fragments[o].length-1)}),e.on("slide",({index:t,fragment:n})=>{let r=0;if(void 0!==n){const s=e.fragments[t];if(s){const{length:e}=s;r=-1===n?e-1:Math.min(Math.max(n,0),e-1)}}s(t,r)}),s(0,0)}var i,l=function(e,t){return e(t={exports:{}},t.exports),t.exports}((function(e){
/*!
* screenfull
* v5.0.0 - 2019-09-09
* (c) Sindre Sorhus; MIT License
*/
!function(){var t="undefined"!=typeof window&&void 0!==window.document?window.document:{},n=e.exports,r=function(){for(var e,n=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],r=0,s=n.length,o={};r<s;r++)if((e=n[r])&&e[1]in t){for(r=0;r<e.length;r++)o[n[0][r]]=e[r];return o}return!1}(),s={change:r.fullscreenchange,error:r.fullscreenerror},o={request:function(e){return new Promise(function(n,s){var o=function(){this.off("change",o),n()}.bind(this);this.on("change",o),e=e||t.documentElement,Promise.resolve(e[r.requestFullscreen]()).catch(s)}.bind(this))},exit:function(){return new Promise(function(e,n){if(this.isFullscreen){var s=function(){this.off("change",s),e()}.bind(this);this.on("change",s),Promise.resolve(t[r.exitFullscreen]()).catch(n)}else e()}.bind(this))},toggle:function(e){return this.isFullscreen?this.exit():this.request(e)},onchange:function(e){this.on("change",e)},onerror:function(e){this.on("error",e)},on:function(e,n){var r=s[e];r&&t.addEventListener(r,n,!1)},off:function(e,n){var r=s[e];r&&t.removeEventListener(r,n,!1)},raw:r};r?(Object.defineProperties(o,{isFullscreen:{get:function(){return Boolean(t[r.fullscreenElement])}},element:{enumerable:!0,get:function(){return t[r.fullscreenElement]}},isEnabled:{enumerable:!0,get:function(){return Boolean(t[r.fullscreenEnabled])}}}),n?e.exports=o:window.screenfull=o):n?e.exports={isEnabled:!1}:window.screenfull={isEnabled:!1}}()}));l.isEnabled;function c(e){e.fullscreen=()=>{l.isEnabled&&l.toggle(document.body)},document.addEventListener("keydown",t=>{70!==t.which&&122!==t.which||t.altKey||t.ctrlKey||t.metaKey||!l.isEnabled||(e.fullscreen(),t.preventDefault())})}function u(e={}){const t=Object.assign({interval:200},e);return e=>{document.addEventListener("keydown",t=>{(32===t.which&&t.shiftKey||33===t.which||37===t.which||38===t.which)&&e.prev(),(32===t.which&&!t.shiftKey||34===t.which||39===t.which||40===t.which)&&e.next(),35===t.which&&e.slide(e.slides.length-1,{fragment:-1}),36===t.which&&e.slide(0)});let n,r,s=0;e.parent.addEventListener("wheel",o=>{let a=!1;const l=(e,t)=>{var n;e&&(a=a||function(e,t){return function(e,t){const n=t===i.X?"Width":"Height";return e[`client${n}`]<e[`scroll${n}`]}(e,t)&&function(e,t){const{overflow:n}=e,r=e[`overflow${t}`];return"auto"===n||"scroll"===n||"auto"===r||"scroll"===r}(getComputedStyle(e),t)}(e,t)),(null===(n=e)||void 0===n?void 0:n.parentElement)&&l(e.parentElement,t)};if(0!==o.deltaX&&l(o.target,i.X),0!==o.deltaY&&l(o.target,i.Y),a)return;o.preventDefault(),r&&clearTimeout(r),r=setTimeout(()=>{n=0},t.interval);const c=Date.now()-s<t.interval,u=Math.sqrt(Math.pow(o.deltaX,2)+Math.pow(o.deltaY,2)),d=u<=n;if(n=u,c||d)return;let f;(o.deltaX>0||o.deltaY>0)&&(f="next"),(o.deltaX<0||o.deltaY<0)&&(f="prev"),f&&(e[f](),s=Date.now())})}}function d(e=".bespoke-marp-osc"){const t=document.querySelector(e);if(!t)return()=>{};const n=(e,n)=>{t.querySelectorAll(`[data-bespoke-marp-osc=${JSON.stringify(e)}]`).forEach(n)};return l.isEnabled||n("fullscreen",e=>e.style.display="none"),e=>{t.addEventListener("click",t=>{if(t.target instanceof HTMLElement){const{bespokeMarpOsc:n}=t.target.dataset;switch(n&&t.target.blur(),n){case"next":e.next();break;case"prev":e.prev();break;case"fullscreen":"function"==typeof e.fullscreen&&l.isEnabled&&e.fullscreen()}}}),e.parent.appendChild(t),e.on("activate",({index:t})=>{n("page",n=>n.textContent=`Page ${t+1} of ${e.slides.length}`)}),e.on("fragment",({index:t,fragments:r,fragmentIndex:s})=>{n("prev",e=>e.disabled=0===t&&0===s),n("next",n=>n.disabled=t===e.slides.length-1&&s===r.length-1)}),l.isEnabled&&l.onchange(()=>n("fullscreen",e=>e.classList.toggle("exit",l.isEnabled&&l.isFullscreen)))}}!function(e){e.X="X",e.Y="Y"}(i||(i={}));const f=".bespoke-progress-bar";function h(e){e.on("activate",t=>{document.querySelectorAll(f).forEach(n=>{n.style.flexBasis=`${100*t.index/(e.slides.length-1)}%`})})}const m=(...e)=>history.replaceState(...e),g=e=>new URLSearchParams(location.search).get(e),p=e=>{const t=g(e);return b({[e]:void 0}),t},b=(e,t={})=>{const n=Object.assign({location:location,setter:m},t),r=new URLSearchParams(n.location.search);for(const t of Object.keys(e)){const n=e[t];"string"==typeof n?r.set(t,n):r.delete(t)}try{n.setter(null,document.title,((e,{protocol:t,host:n,pathname:r,hash:s}=location)=>{const o=e.toString();return`${t}//${n}${r}${o?"?":""}${o}${s}`})(r,n.location))}catch(e){console.error(e)}},v=e=>{const t=Number.parseInt(e,10);return Number.isNaN(t)?null:t};function w(e={}){const t=Object.assign({history:!0},e);return e=>{let n=!0;const r=e=>{const t=n;try{return n=!0,e()}finally{n=t}},s=(t={fragment:!0})=>{((t,n)=>{const{fragments:r,slides:s}=e,o=Math.max(0,Math.min(t,s.length-1)),a=Math.max(0,Math.min(n||0,r[o].length-1));o===e.slide()&&a===e.fragmentIndex||e.slide(o,{fragment:a})})((v(location.hash.slice(1))||1)-1,t.fragment?v(g("f")||""):null)};e.on("fragment",({index:e,fragmentIndex:r})=>{n||b({f:0===r||r.toString()},{location:Object.assign(Object.assign({},location),{hash:`#${e+1}`}),setter:(...e)=>t.history?history.pushState(...e):history.replaceState(...e)})}),setTimeout(()=>{s(),window.addEventListener("hashchange",()=>r(()=>{s({fragment:!1}),b({f:void 0})})),window.addEventListener("popstate",()=>{n||r(()=>s())}),n=!1},0)}}var y=self.crypto||self.msCrypto,E=function(e){e=e||21;for(var t="",n=y.getRandomValues(new Uint8Array(e));e--;)t+="QLUint8ARdomValuesObj0h6345-79BCrypgJzHKTNYDSMkXPZ_FfG1WcqvwxEI2"[63&n[e]];return t};function x(e={}){const t=e.key||E(),n=`bespoke-marp-sync-${t}`,r=()=>{const e=localStorage.getItem(n);return e?JSON.parse(e):Object.create(null)},s=e=>{const t=r(),s=Object.assign(Object.assign({},t),e(t));return localStorage.setItem(n,JSON.stringify(s)),s};return s(e=>({reference:(e.reference||0)+1})),e=>{Object.defineProperty(e,"syncKey",{value:t,enumerable:!0}),setTimeout(()=>{e.on("fragment",e=>{s(()=>({index:e.index,fragmentIndex:e.fragmentIndex}))})},0),window.addEventListener("storage",t=>{if(t.key===n&&t.oldValue&&t.newValue){const n=JSON.parse(t.oldValue),r=JSON.parse(t.newValue);n.index===r.index&&n.fragmentIndex===r.fragmentIndex||e.slide(r.index,{fragment:r.fragmentIndex})}}),e.on("destroy",()=>{const{reference:e}=r();void 0===e||e<=1?localStorage.removeItem(n):s(()=>({reference:e-1}))})}}function k(e={}){const t=Object.assign({slope:Math.tan(-35*Math.PI/180),swipeThreshold:30},e);return e=>{let n;const r=e.parent,s=e=>{const t=r.getBoundingClientRect();return{x:e.pageX-(t.left+t.right)/2,y:e.pageY-(t.top+t.bottom)/2}};r.addEventListener("touchstart",e=>{n=1===e.touches.length?s(e.touches[0]):void 0}),r.addEventListener("touchmove",e=>{if(n)if(1===e.touches.length){e.preventDefault();const t=s(e.touches[0]),r=t.x-n.x,o=t.y-n.y;n.delta=Math.sqrt(Math.pow(Math.abs(r),2)+Math.pow(Math.abs(o),2)),n.radian=Math.atan2(r,o)}else n=void 0}),r.addEventListener("touchend",r=>{if(n){if(n.delta&&n.delta>=t.swipeThreshold){let s=n.radian-t.slope;s=(s+Math.PI)%(2*Math.PI)-Math.PI,e[s<0?"next":"prev"](),r.stopPropagation()}n=void 0}})}}!function(r=document.getElementById("p")){const i=p("sync")||void 0,l=e.from(r,[s,t,n(),o,w({history:!1}),u(),c,h,k(),d(),a,x({key:i})]);window.addEventListener("beforeunload",()=>b({sync:l.syncKey})),window.addEventListener("unload",()=>l.destroy())}()}();
</script></body></html>