1 | # Amplify UI Components
|
2 |
|
3 | [Amplify UI Components](#) is an open-source UI component library that encapsulates cloud-connected workflows inside of framework-agnostic UI components.
|
4 |
|
5 | ## Frameworks
|
6 |
|
7 | | Framework | Package | Version | READMEs | Quick Start |
|
8 | | ------------------ | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------: | ----------------------------------- |
|
9 | | **React** | [`@aws-amplify/ui-react`](https://www.npmjs.com/package/@aws-amplify/ui-react) | [![version](https://img.shields.io/npm/v/@aws-amplify/ui-react/ui-preview.svg)](https://www.npmjs.com/package/@aws-amplify/ui-react) | [`README.md`](../amplify-ui-react/README.md) | [`React`](#react) |
|
10 | | **Angular** | [`@aws-amplify/ui-angular`](https://www.npmjs.com/package/@aws-amplify/ui-angular) | [![version](https://img.shields.io/npm/v/@aws-amplify/ui-angular/ui-preview.svg)](https://www.npmjs.com/package/@aws-amplify/ui-angular) | [`README.md`](../amplify-ui-angular/README.md) | [`Angular`](#angular) |
|
11 | | **Vue** | [`@aws-amplify/ui-vue`](https://www.npmjs.com/package/@aws-amplify/ui-vue) | [![version](https://img.shields.io/npm/v/@aws-amplify/ui-vue/ui-preview.svg)](https://www.npmjs.com/package/@aws-amplify/ui-vue) | [`README.md`](../amplify-ui-vue/README.md) | [`Vue`](#vue) |
|
12 | | **Web Components** | [`@aws-amplify/ui-components`](https://www.npmjs.com/package/@aws-amplify/ui-components) | [![version](https://img.shields.io/npm/v/@aws-amplify/ui-components/ui-preview.svg)](https://www.npmjs.com/package/@aws-amplify/ui-components) | [`README.md`](README.md) | [`Web Components`](#web-components) |
|
13 |
|
14 | ## Quick Start
|
15 |
|
16 | In this Quick Start guide you will set up an Authenticator component and the cloud resources required to use it inside of your app.
|
17 |
|
18 | **Prerequisites**
|
19 |
|
20 | - Follow [Get Started](https://aws-amplify.github.io/docs/) on Amplify Docs.
|
21 | - Use [Amplify CLI](https://aws-amplify.github.io/docs/cli-toolchain/quickstart#auth-examples) to initialize your project set up Auth cloud resources.
|
22 |
|
23 | **Frameworks**
|
24 |
|
25 | - [React](#react)
|
26 | - [Angular](#angular)
|
27 | - [Vue](#vue)
|
28 | - [Web Components](#web-components)
|
29 |
|
30 | #### React
|
31 |
|
32 | ##### Installation
|
33 |
|
34 | ```
|
35 | yarn add aws-amplify@ui-preview @aws-amplify/ui-react@ui-preview
|
36 | ```
|
37 |
|
38 | ##### Usage
|
39 |
|
40 | ```js
|
41 | import React from 'react';
|
42 | import Amplify from 'aws-amplify';
|
43 | import { AmplifyAuthenticator, AmplifySignOut } from '@aws-amplify/ui-react';
|
44 | import awsconfig from './aws-exports';
|
45 |
|
46 | Amplify.configure(awsconfig);
|
47 |
|
48 | const App = () => {
|
49 | <AmplifyAuthenticator>
|
50 | <div>
|
51 | My App
|
52 | <AmplifySignOut />
|
53 | </div>
|
54 | </AmplifyAuthenticator>;
|
55 | };
|
56 | ```
|
57 |
|
58 | #### Angular
|
59 |
|
60 | ##### Installation
|
61 |
|
62 | ```
|
63 | yarn add aws-amplify@ui-preview @aws-amplify/ui-angular@ui-preview
|
64 | ```
|
65 |
|
66 | ##### Usage
|
67 |
|
68 | _app.module.ts_
|
69 |
|
70 | ```js
|
71 | import { BrowserModule } from '@angular/platform-browser';
|
72 | import { NgModule } from '@angular/core';
|
73 | import { AppComponent } from './app.component';
|
74 |
|
75 | import { AmplifyUIAngularModule } from '@aws-amplify/ui-angular';
|
76 | import Amplify from 'aws-amplify';
|
77 | import awsconfig from './aws-exports';
|
78 |
|
79 | Amplify.configure(awsconfig);
|
80 |
|
81 | @NgModule({
|
82 | declarations: [AppComponent],
|
83 | imports: [AmplifyUIAngularModule, BrowserModule],
|
84 | providers: [],
|
85 | bootstrap: [AppComponent],
|
86 | })
|
87 | export class AppModule {}
|
88 | ```
|
89 |
|
90 | _app.component.html_
|
91 |
|
92 | ```html
|
93 | <amplify-authenticator>
|
94 | <div>
|
95 | My App
|
96 | <amplify-sign-out></amplify-sign-out>
|
97 | </div>
|
98 | </amplify-authenticator>
|
99 | ```
|
100 |
|
101 | #### Vue
|
102 |
|
103 | ##### Installation
|
104 |
|
105 | ```
|
106 | yarn add aws-amplify@ui-preview @aws-amplify/ui-vue@ui-preview
|
107 | ```
|
108 |
|
109 | ##### Usage
|
110 |
|
111 | _main.ts_
|
112 |
|
113 | ```js
|
114 | import Vue from 'vue';
|
115 | import App from './App.vue';
|
116 | import '@aws-amplify/ui-vue';
|
117 | import Amplify from 'aws-amplify';
|
118 | import awsconfig from './aws-exports';
|
119 |
|
120 | Amplify.configure(awsconfig);
|
121 |
|
122 | new Vue({
|
123 | render: h => h(App),
|
124 | }).$mount('#app');
|
125 | ```
|
126 |
|
127 | _App.vue_
|
128 |
|
129 | ```html
|
130 | <template>
|
131 | <amplify-authenticator>
|
132 | <div>
|
133 | My App
|
134 | <amplify-sign-out></amplify-sign-out>
|
135 | </div>
|
136 | </amplify-authenticator>
|
137 | </template>
|
138 | ```
|
139 |
|
140 | #### Web Components
|
141 |
|
142 | ##### Installation
|
143 |
|
144 | ```
|
145 | yarn add aws-amplify@ui-preview @aws-amplify/ui-components@ui-preview
|
146 | ```
|
147 |
|
148 | ##### Usage
|
149 |
|
150 | _app.js_
|
151 |
|
152 | ```js
|
153 | import '@aws-amplify/ui-vue';
|
154 | import Amplify from 'aws-amplify';
|
155 | import awsconfig from './aws-exports';
|
156 |
|
157 | Amplify.configure(awsconfig);
|
158 | ```
|
159 |
|
160 | _index.html_
|
161 |
|
162 | ```html
|
163 | <!DOCTYPE html>
|
164 | <html lang="en">
|
165 | <body>
|
166 | <amplify-authenticator>
|
167 | <div>
|
168 | My App
|
169 | <amplify-sign-out></amplify-sign-out>
|
170 | </div>
|
171 | </amplify-authenticator>
|
172 |
|
173 | <script src="app.js"></script>
|
174 | </body>
|
175 | </html>
|
176 | ```
|
177 |
|
178 | ## Components
|
179 |
|
180 | - #### [amplify-authenticator](src/components/amplify-authenticator/readme.md)
|
181 |
|
182 | <img width="450" alt="amplify-authenticator" src="https://user-images.githubusercontent.com/3868826/74710028-86392f80-51d5-11ea-951a-d582cb55d351.png">
|
183 |
|
184 | - [amplify-sign-in](src/components/amplify-sign-in/readme.md)
|
185 |
|
186 | - [amplify-sign-up](src/components/amplify-sign-up/readme.md)
|
187 |
|
188 | - [amplify-sign-out](src/components/amplify-sign-out/readme.md)
|
189 |
|
190 | - [amplify-confirm-sign-up](src/components/amplify-confirm-sign-up/readme.md)
|
191 |
|
192 | - [amplify-forgot-password](src/components/amplify-forgot-password/readme.md)
|
193 |
|
194 | - [amplify-require-new-password](src/components/amplify-require-new-password/readme.md)
|
195 |
|
196 | - [amplify-verify-contact](src/components/amplify-verify-contact/readme.md)
|
197 |
|
198 | - [amplify-totp-setup](src/components/amplify-totp-setup/readme.md)
|
199 |
|
200 | - [amplify-greetings](src/components/amplify-greetings/readme.md)
|
201 |
|
202 | ## Customization
|
203 |
|
204 | Amplify UI Components use [slots](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot) to allow for component customization. Component customization and slot usage is exemplified below.
|
205 |
|
206 | ### Amplify Authenticator
|
207 |
|
208 | **Slots**
|
209 |
|
210 | > You can override the [components listed above](#components) and pass them into these slots to preserve the authenticator state flow.
|
211 |
|
212 | | Name | Description |
|
213 | | ------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
|
214 | | `"sign-in"` | Content placed inside of the sign in workflow for when a user wants to sign into their account |
|
215 | | `"confirm-sign-in"` | Content placed inside of the confirm sign in workflow for when a user needs to confirm the account they signed in with |
|
216 | | `"sign-up"` | Content placed inside of the sign up workflow for when a user wants to register a new account |
|
217 | | `"confirm-sign-up"` | Content placed inside of the confirm sign up workflow for when a user needs to confirm the account they signed up with |
|
218 | | `"forgot-password"` | Content placed inside of the forgot password workflow for when a user wants to reset their password |
|
219 | | `"require-new-password"` | Content placed inside of the require new password workflow for when a user is required to update their password |
|
220 | | `"verify-contact"` | Content placed inside of the verify-contact workflow for when a user must verify their contact information |
|
221 | | `"totp-setup"` | Content placed inside of the totp-setup workflow for when a user opts to use TOTP MFA |
|
222 | | `"greetings"` | Content placed inside of the greetings navigation for when a user is signed in |
|
223 |
|
224 | **Frameworks**
|
225 |
|
226 | - [React](#react-1)
|
227 | - [Angular](#angular-1)
|
228 | - [Vue](#vue-1)
|
229 | - [Web Components](#web-components-1)
|
230 |
|
231 | #### React
|
232 |
|
233 | ```js
|
234 | import { AmplifyAuthenticator, AmplifySignIn, AmplifySignUp } from '@aws-amplify/ui-react';
|
235 |
|
236 | const App = () => {
|
237 | <AmplifyAuthenticator>
|
238 | <AmplifySignIn headerText="My Custom Sign In Header" slot="sign-in" />
|
239 | <AmplifySignUp headerText="My Custom Sign Up Header" slot="sign-up" />
|
240 |
|
241 | <div>
|
242 | My App
|
243 | <AmplifySignOut />
|
244 | </div>
|
245 | </AmplifyAuthenticator>;
|
246 | };
|
247 | ```
|
248 |
|
249 | Alternatively, you can use the `withAuthenticator` higher-order component (HoC):
|
250 |
|
251 | ```js
|
252 | import { withAuthenticator } from '@aws-amplify/ui-react';
|
253 |
|
254 | ...
|
255 |
|
256 | export default withAuthenticator(App);
|
257 | // or
|
258 | export default withAuthenticator(App, { /* ...amplifyAuthenticatorSettings */ })
|
259 | });
|
260 | ```
|
261 |
|
262 | #### Angular
|
263 |
|
264 | ```html
|
265 | <amplify-authenticator>
|
266 | <amplify-sign-in header-text="My Custom Sign In Header" slot="sign-in" />
|
267 | <amplify-sign-up header-text="My Custom Sign In Header" slot="sign-up" />
|
268 |
|
269 | <div>
|
270 | My App
|
271 | <amplify-sign-out></amplify-sign-out>
|
272 | </div>
|
273 | </amplify-authenticator>
|
274 | ```
|
275 |
|
276 | #### Vue
|
277 |
|
278 | ```html
|
279 | <amplify-authenticator>
|
280 | <amplify-sign-in header-text="My Custom Sign In Header" slot="sign-in" />
|
281 | <amplify-sign-up header-text="My Custom Sign In Header" slot="sign-up" />
|
282 |
|
283 | <div>
|
284 | My App
|
285 | <amplify-sign-out></amplify-sign-out>
|
286 | </div>
|
287 | </amplify-authenticator>
|
288 | ```
|
289 |
|
290 | #### Web Components
|
291 |
|
292 | ```html
|
293 | <amplify-authenticator>
|
294 | <amplify-sign-in header-text="My Custom Sign In Header" slot="sign-in" />
|
295 | <amplify-sign-up header-text="My Custom Sign In Header" slot="sign-up" />
|
296 |
|
297 | <div>
|
298 | My App
|
299 | <amplify-sign-out></amplify-sign-out>
|
300 | </div>
|
301 | </amplify-authenticator>
|
302 | ```
|
303 |
|
304 | ## Theming
|
305 |
|
306 | Theming for the UI components can be achieved by using [CSS Variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties). You can enable theming in your app by overriding the below mentioned CSS variable values. To do that, add the following code in root css file.
|
307 |
|
308 | ```
|
309 | :root{
|
310 |
|
311 | --amplify-primary-color: #ff6347;
|
312 | --amplify-primary-tint: #ff7359;
|
313 | --amplify-primary-shade: #e0573e;
|
314 |
|
315 | }
|
316 |
|
317 | ```
|
318 |
|
319 | ### Supported CSS Custom properties
|
320 |
|
321 | #### For Typography
|
322 |
|
323 | | Custom Properties | Default Value |
|
324 | | ----------------------- | -------------------------------------------------------------------------------------------- |
|
325 | | `--amplify-font-family` | 'Amazon Ember', 'Helvetica Neue Light', 'Helvetica Neue', 'Helvetica', 'Arial', 'sans-serif' |
|
326 | | `--amplify-text-xxs` | 0.75rem |
|
327 | | `--amplify-text-xs` | 0.81rem |
|
328 | | `--amplify-text-sm` | 0.875rem |
|
329 | | `--amplify-text-md` | 1rem |
|
330 | | `--amplify-text-lg` | 1.5rem |
|
331 | | `--amplify-text-xl` | 2rem |
|
332 | | `--amplify-text-xxl` | 2.5rem |
|
333 |
|
334 | #### For Colors
|
335 |
|
336 | | Custom Properties | Default Value |
|
337 | | ------------------------------ | -------------------- |
|
338 | | `--amplify-primary-color` | #ff9900 |
|
339 | | `--amplify-primary-contrast` | var(--amplify-white) |
|
340 | | `--amplify-primary-tint` | #ffac31 |
|
341 | | `--amplify-primary-shade` | #e88b01 |
|
342 | | `--amplify-secondary-color` | #152939 |
|
343 | | `--amplify-secondary-contrast` | var(--amplify-white) |
|
344 | | `--amplify-secondary-tint` | #31465f |
|
345 | | `--amplify-secondary-shade` | #1F2A37 |
|
346 | | `--amplify-tertiary-color` | #5d8aff |
|
347 | | `--amplify-tertiary-contrast` | var(--amplify-white) |
|
348 | | `--amplify-tertiary-tint` | #7da1ff |
|
349 | | `--amplify-tertiary-shade` | #537BE5 |
|
350 | | `--amplify-grey` | #828282 |
|
351 | | `--amplify-light-grey` | #c4c4c4 |
|
352 | | `--amplify-white` | #ffffff |
|
353 | | `--amplify-red` | #dd3f5b |
|
354 | | `--amplify-blue` | #099ac8 |
|
355 |
|
356 | ## Amplify Authenticator `usernameAlias`
|
357 |
|
358 | The `amplify-authenticator` component has the ability to sign in or sign up with `email` or `phone_number` instead of default `username`. To achieve this, you first need to setup the userpool to allow email or phone number as the username [using the cli workflow](https://aws-amplify.github.io/docs/cli-toolchain/quickstart#configuring-auth-without-social-providers) or through the [Cognito Console](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-attributes.html#user-pool-settings-aliases-settings-option-2). To reflect this in the `amplify-authenticator` component, you can use the `usernameAlias` property. It can take one of the three values - `email`, `phone_number` or `username`. Default is set to `username`.
|
359 |
|
360 | **Usage:**
|
361 |
|
362 | ```js
|
363 | // react
|
364 | <AmplifyAuthenticator usernameAlias="email" />
|
365 |
|
366 | // angular, vue or web components
|
367 | <amplify-authenticator username-alias="phone_number" />
|
368 | ```
|
369 |
|
370 | ## Amplify Authenticator `federated`
|
371 |
|
372 | The `amplify-authenticator` component supports Federated Sign In through Cognito Identity Pools (IDP) with external providers like Amazon, Auth0, Facebook, & Google.
|
373 |
|
374 | The `federated` prop implements the `FederatedConfig`:
|
375 |
|
376 | ```ts
|
377 | export interface FederatedConfig {
|
378 | auth0Config?: {
|
379 | audience?: string;
|
380 | clientID: string;
|
381 | domain: string;
|
382 | responseType: string;
|
383 | redirectUri: string;
|
384 | returnTo?: string;
|
385 | scope?: string;
|
386 | };
|
387 | amazonClientId?: string;
|
388 | facebookAppId?: string;
|
389 | googleClientId?: string;
|
390 | oauthConfig?: {
|
391 | [key: string]: any;
|
392 | };
|
393 | }
|
394 | ```
|
395 |
|
396 | **Usage:**
|
397 |
|
398 | ```js
|
399 | const federated = {
|
400 | amazonClientId: "your_amazon_client_id",
|
401 | facebookAppId: "your_facebook_app_id",
|
402 | googleClientId: "your_google_client_id",
|
403 | oauthConfig: {
|
404 | redirectSignIn: "http://localhost:1234/",
|
405 | redirectSignOut: "http://localhost:1234/",
|
406 | }
|
407 | }
|
408 |
|
409 | // react
|
410 | <AmplifyAuthenticator federated={federated} />
|
411 |
|
412 | // angular, vue, or web components
|
413 | <amplify-authenticator federated={federated} />
|
414 | ```
|
415 |
|
416 | ## Migration Guide
|
417 |
|
418 | - [React](#react-2)
|
419 | - [Angular](#angular-2)
|
420 | - [Vue](#vue-2)
|
421 | - [Web Components](#web-components-2)
|
422 |
|
423 | #### React
|
424 |
|
425 | ##### Installation
|
426 |
|
427 | ```diff
|
428 | - yarn add aws-amplify-react
|
429 | + yarn add @aws-amplify/ui-react@ui-preview
|
430 | ```
|
431 |
|
432 | ##### Usage
|
433 |
|
434 | ```diff
|
435 | - import { Authenticator } from 'aws-amplify-react';
|
436 | + import { AmplifyAuthenticator } from '@aws-amplify/ui-react';
|
437 |
|
438 | const App = () => (
|
439 |
|
440 | + <AmplifyAuthenticator>
|
441 | - <Authenticator>
|
442 | <div>
|
443 | My App
|
444 | + <AmplifySignOut />
|
445 | </div>
|
446 | + </AmplifyAuthenticator>;
|
447 | - </Authenticator>
|
448 | );
|
449 | ```
|
450 |
|
451 | If you're using the [`withAuthenticator`](https://aws-amplify.github.io/docs/js/authentication#using-withauthenticator-hoc) higher-order component (HoC):
|
452 |
|
453 | ```diff
|
454 | - import { withAuthenticator } from 'aws-amplify-react';
|
455 | + import { withAuthenticator } from '@aws-amplify/ui-react';
|
456 |
|
457 | ...
|
458 |
|
459 | export default withAuthenticator(App);
|
460 | ```
|
461 |
|
462 | **Note:** If you were providing additional options to `withAuthenticator` (e.g. `includeGreetings`, `authenticatorComponents`, `federated`, `theme`), these have changed:
|
463 |
|
464 | > [amplify-authenticator#properties](src/components/amplify-authenticator/readme.md#properties)
|
465 |
|
466 | #### Angular
|
467 |
|
468 | ##### Installation
|
469 |
|
470 | ```diff
|
471 | - yarn add aws-amplify-angular
|
472 | + yarn add @aws-amplify/ui-angular@ui-preview
|
473 | ```
|
474 |
|
475 | ##### Usage
|
476 |
|
477 | _app.module.ts_
|
478 |
|
479 | ```diff
|
480 | import { BrowserModule } from '@angular/platform-browser';
|
481 | import { NgModule } from '@angular/core';
|
482 | import { AppComponent } from './app.component';
|
483 | - import { AmplifyAngularModule, AmplifyService } from 'aws-amplify-angular';
|
484 | + import { AmplifyUIAngularModule } from '@aws-amplify/ui-angular';
|
485 | import Amplify from 'aws-amplify';
|
486 | import awsconfig from './aws-exports';
|
487 |
|
488 | Amplify.configure(awsconfig);
|
489 |
|
490 | @NgModule({
|
491 | declarations: [AppComponent],
|
492 | - imports: [AmplifyAngularModule, BrowserModule],
|
493 | + imports: [AmplifyUIAngularModule, BrowserModule],
|
494 | - providers: [AmplifyService],
|
495 | + providers: [],
|
496 | bootstrap: [AppComponent],
|
497 | })
|
498 | export class AppModule {}
|
499 | ```
|
500 |
|
501 | #### Vue
|
502 |
|
503 | ##### Installation
|
504 |
|
505 | ```diff
|
506 | - yarn add aws-amplify-vue
|
507 | + yarn add @aws-amplify/ui-vue@ui-preview
|
508 | ```
|
509 |
|
510 | ##### Usage
|
511 |
|
512 | _main.ts_
|
513 |
|
514 | ```diff
|
515 | import Vue from 'vue';
|
516 | import App from "./App.vue";
|
517 | - import Amplify, * as AmplifyModules from 'aws-amplify'
|
518 | - import { AmplifyPlugin } from 'aws-amplify-vue'
|
519 | + import '@aws-amplify/ui-vue';
|
520 | + import Amplify from 'aws-amplify';
|
521 | + import awsconfig from './aws-exports';
|
522 |
|
523 | Amplify.configure(awsconfig);
|
524 |
|
525 | new Vue({
|
526 | render: h => h(App),
|
527 | }).$mount('#app');
|
528 | ```
|
529 |
|
530 | ---
|
531 |
|
532 | ![Built With Stencil](https://img.shields.io/badge/-Built%20With%20Stencil-16161d.svg?logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE5LjIuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA1MTIgNTEyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI%2BCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI%2BCgkuc3Qwe2ZpbGw6I0ZGRkZGRjt9Cjwvc3R5bGU%2BCjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik00MjQuNywzNzMuOWMwLDM3LjYtNTUuMSw2OC42LTkyLjcsNjguNkgxODAuNGMtMzcuOSwwLTkyLjctMzAuNy05Mi43LTY4LjZ2LTMuNmgzMzYuOVYzNzMuOXoiLz4KPHBhdGggY2xhc3M9InN0MCIgZD0iTTQyNC43LDI5Mi4xSDE4MC40Yy0zNy42LDAtOTIuNy0zMS05Mi43LTY4LjZ2LTMuNkgzMzJjMzcuNiwwLDkyLjcsMzEsOTIuNyw2OC42VjI5Mi4xeiIvPgo8cGF0aCBjbGFzcz0ic3QwIiBkPSJNNDI0LjcsMTQxLjdIODcuN3YtMy42YzAtMzcuNiw1NC44LTY4LjYsOTIuNy02OC42SDMzMmMzNy45LDAsOTIuNywzMC43LDkyLjcsNjguNlYxNDEuN3oiLz4KPC9zdmc%2BCg%3D%3D&colorA=16161d&style=flat-square)
|