gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] branch master updated (ca50e75c5 -> 3e060b804)


From: gnunet
Subject: [taler-wallet-core] branch master updated (ca50e75c5 -> 3e060b804)
Date: Mon, 24 Oct 2022 10:46:18 +0200

This is an automated email from the git hooks/post-receive script.

dold pushed a change to branch master
in repository wallet-core.

    from ca50e75c5 take latest translation 'es'
     new fb52ced35 mark clause schnorr test as experimental
     new 3e060b804 repo: integrate packages from former merchant-backoffice.git

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../{anastasis-webui => demobank-ui}/.gitignore    |     0
 packages/demobank-ui/.storybook/.babelrc           |    25 +
 packages/demobank-ui/.storybook/main.js            |    57 +
 packages/demobank-ui/.storybook/preview.js         |    55 +
 packages/demobank-ui/README.md                     |    19 +
 packages/demobank-ui/TODO                          |    45 +
 packages/demobank-ui/build-bank-translations.sh    |    32 +
 {contrib => packages/demobank-ui/contrib}/po2ts    |     0
 packages/demobank-ui/mocks/json-server/db.json     |     4 +
 packages/demobank-ui/mocks/window.js               |    27 +
 packages/demobank-ui/package.json                  |   100 +
 packages/demobank-ui/preact.config.js              |    70 +
 packages/demobank-ui/preact.mock.js                |    55 +
 packages/demobank-ui/preact.single-config.js       |    60 +
 packages/demobank-ui/remove-link-stylesheet.sh     |     8 +
 packages/demobank-ui/src/.babelrc                  |     3 +
 .../src/assets/empty.png                           |   Bin
 .../src/assets/example/id1.jpg                     |   Bin
 .../src/assets/favicon.ico                         |   Bin
 .../src/assets/icons/android-chrome-192x192.png    |   Bin
 .../src/assets/icons/android-chrome-512x512.png    |   Bin
 .../src/assets/icons/apple-touch-icon.png          |   Bin
 .../src/assets/icons/auth_method/email.svg         |     0
 .../src/assets/icons/auth_method/postal.svg        |     0
 .../src/assets/icons/auth_method/question.svg      |     0
 .../src/assets/icons/auth_method/sms.svg           |     0
 .../src/assets/icons/auth_method/video.svg         |     0
 .../src/assets/icons/favicon-16x16.png             |   Bin
 .../src/assets/icons/favicon-32x32.png             |   Bin
 .../src/assets/icons/languageicon.svg              |     0
 .../src/assets/icons/mstile-150x150.png            |   Bin
 packages/demobank-ui/src/assets/logo-white.svg     |    45 +
 .../src/assets/logo.jpeg                           |   Bin
 .../demobank-ui/src/components/AsyncButton.tsx     |    66 +
 packages/demobank-ui/src/components/FileButton.tsx |    57 +
 .../demobank-ui/src/components/Notifications.tsx   |    74 +
 packages/demobank-ui/src/components/QR.tsx         |    48 +
 packages/demobank-ui/src/components/app.tsx        |    14 +
 .../src/components/fields/DateInput.tsx            |    90 +
 .../src/components/fields/EmailInput.tsx           |    57 +
 .../src/components/fields/FileInput.tsx            |   104 +
 .../src/components/fields/ImageInput.tsx           |    93 +
 .../src/components/fields/NumberInput.tsx          |    56 +
 .../src/components/fields/TextInput.tsx            |    68 +
 .../src/components/menu/LangSelector.tsx           |   101 +
 .../src/components/menu/NavigationBar.tsx          |    53 +
 .../demobank-ui/src/components/menu/SideBar.tsx    |    73 +
 packages/demobank-ui/src/components/menu/index.tsx |   135 +
 .../src/components/picker/DatePicker.tsx           |   356 +
 .../components/picker/DurationPicker.stories.tsx   |    55 +
 .../src/components/picker/DurationPicker.tsx       |   211 +
 packages/demobank-ui/src/context/translation.ts    |    73 +
 packages/demobank-ui/src/declaration.d.ts          |    20 +
 packages/demobank-ui/src/hooks/async.ts            |    80 +
 packages/demobank-ui/src/hooks/index.ts            |   151 +
 packages/demobank-ui/src/i18n/bank.pot             |   258 +
 packages/demobank-ui/src/i18n/de.po                |   257 +
 packages/demobank-ui/src/i18n/en.po                |   266 +
 packages/demobank-ui/src/i18n/index.tsx            |   211 +
 packages/demobank-ui/src/i18n/it.po                |   258 +
 packages/demobank-ui/src/i18n/poheader             |    27 +
 packages/demobank-ui/src/i18n/strings-prelude      |    19 +
 packages/demobank-ui/src/i18n/strings.ts           |   472 +
 packages/demobank-ui/src/index.tsx                 |     3 +
 packages/demobank-ui/src/manifest.json             |    21 +
 packages/demobank-ui/src/pages/home/index.tsx      |  2018 ++
 packages/demobank-ui/src/pages/notfound/index.tsx  |    16 +
 .../src/pages/notfound/style.css}                  |     0
 .../src/pages/profile/index.stories.tsx            |    38 +
 packages/demobank-ui/src/pages/profile/index.tsx   |    42 +
 .../src/pages/profile/style.css}                   |     0
 .../src/scss/DurationPicker.scss                   |     0
 packages/demobank-ui/src/scss/_aside.scss          |   128 +
 packages/demobank-ui/src/scss/_card.scss           |    69 +
 .../demobank-ui/src/scss/_custom-calendar.scss     |   263 +
 packages/demobank-ui/src/scss/_footer.scss         |    35 +
 packages/demobank-ui/src/scss/_form.scss           |    71 +
 packages/demobank-ui/src/scss/_hero-bar.scss       |    55 +
 packages/demobank-ui/src/scss/_loading.scss        |    51 +
 packages/demobank-ui/src/scss/_main-section.scss   |    24 +
 packages/demobank-ui/src/scss/_misc.scss           |    50 +
 packages/demobank-ui/src/scss/_mixins.scss         |    34 +
 packages/demobank-ui/src/scss/_modal.scss          |    35 +
 packages/demobank-ui/src/scss/_nav-bar.scss        |   144 +
 packages/demobank-ui/src/scss/_table.scss          |   179 +
 packages/demobank-ui/src/scss/_theme-default.scss  |   136 +
 packages/demobank-ui/src/scss/_tiles.scss          |    24 +
 packages/demobank-ui/src/scss/_title-bar.scss      |    50 +
 packages/demobank-ui/src/scss/bank.scss            |   264 +
 packages/demobank-ui/src/scss/colors-bank.scss     |    31 +
 packages/demobank-ui/src/scss/demo.scss            |   157 +
 .../src/scss/fonts/XRXV3I6Li01BKofINeaE.ttf        |   Bin
 packages/demobank-ui/src/scss/fonts/nunito.css     |    22 +
 .../fonts/materialdesignicons-webfont-4.9.95.eot   |   Bin
 .../fonts/materialdesignicons-webfont-4.9.95.ttf   |   Bin
 .../fonts/materialdesignicons-webfont-4.9.95.woff  |   Bin
 .../fonts/materialdesignicons-webfont-4.9.95.woff2 |   Bin
 .../scss/icons/materialdesignicons-4.9.95.min.css  |     3 +
 packages/demobank-ui/src/scss/libs/_all.scss       |    29 +
 packages/demobank-ui/src/scss/main.scss            |     4 +
 packages/demobank-ui/src/scss/pure.scss            |  1328 ++
 .../sample.ts => demobank-ui/src/style/index.css}  |     0
 packages/demobank-ui/src/template.html             |    52 +
 .../demobank-ui/tests/__mocks__/browserMocks.ts    |    21 +
 packages/demobank-ui/tests/__mocks__/fileMocks.ts  |     3 +
 packages/demobank-ui/tests/__mocks__/setupTests.ts |     6 +
 packages/demobank-ui/tests/__tests__/homepage.js   |   466 +
 packages/demobank-ui/tests/declarations.d.ts       |     3 +
 packages/demobank-ui/tsconfig.json                 |    60 +
 packages/merchant-backend-ui/.gitignore            |     9 +
 packages/merchant-backend-ui/.storybook/.babelrc   |    25 +
 packages/merchant-backend-ui/.storybook/main.js    |    82 +
 packages/merchant-backend-ui/.storybook/preview.js |    73 +
 packages/merchant-backend-ui/README.md             |    30 +
 .../merchant-backend-ui/contrib}/po2ts             |     0
 packages/merchant-backend-ui/copyleft-header.js    |    15 +
 packages/merchant-backend-ui/package.json          |   144 +
 packages/merchant-backend-ui/render-examples.ts    |    83 +
 packages/merchant-backend-ui/rollup.config.js      |   112 +
 .../src/assets/empty.png                           |   Bin
 .../src/assets/icons/android-chrome-192x192.png    |   Bin
 .../src/assets/icons/android-chrome-512x512.png    |   Bin
 .../src/assets/icons/apple-touch-icon.png          |   Bin
 .../src/assets/icons/favicon-16x16.png             |   Bin
 .../src/assets/icons/favicon-32x32.png             |   Bin
 .../src/assets/icons/languageicon.svg              |     0
 .../src/assets/icons/mstile-150x150.png            |   Bin
 .../merchant-backend-ui/src/components/Footer.tsx  |    32 +
 packages/merchant-backend-ui/src/components/QR.tsx |    41 +
 .../merchant-backend-ui/src/context/backend.ts     |    82 +
 packages/merchant-backend-ui/src/context/config.ts |    32 +
 packages/merchant-backend-ui/src/context/fetch.ts  |    40 +
 .../merchant-backend-ui/src/context/instance.ts    |    35 +
 .../merchant-backend-ui/src/context/listener.ts    |    35 +
 .../merchant-backend-ui/src/context/translation.ts |    59 +
 packages/merchant-backend-ui/src/css/pure-min.css  |   973 +
 packages/merchant-backend-ui/src/css/style.css     |    61 +
 packages/merchant-backend-ui/src/custom.d.ts       |    40 +
 packages/merchant-backend-ui/src/declaration.d.ts  |  1384 ++
 packages/merchant-backend-ui/src/hooks/async.ts    |    76 +
 packages/merchant-backend-ui/src/hooks/backend.ts  |   262 +
 packages/merchant-backend-ui/src/hooks/index.ts    |   110 +
 packages/merchant-backend-ui/src/hooks/instance.ts |   187 +
 packages/merchant-backend-ui/src/hooks/listener.ts |    68 +
 .../merchant-backend-ui/src/hooks/notification.ts  |    43 +
 .../merchant-backend-ui/src/hooks/notifications.ts |    48 +
 packages/merchant-backend-ui/src/hooks/order.ts    |   217 +
 packages/merchant-backend-ui/src/hooks/product.ts  |   223 +
 packages/merchant-backend-ui/src/hooks/tips.ts     |   159 +
 packages/merchant-backend-ui/src/hooks/transfer.ts |   150 +
 packages/merchant-backend-ui/src/i18n/de.po        |  1057 +
 packages/merchant-backend-ui/src/i18n/en.po        |  1057 +
 packages/merchant-backend-ui/src/i18n/es.po        |  1065 +
 packages/merchant-backend-ui/src/i18n/fr.po        |  1057 +
 packages/merchant-backend-ui/src/i18n/index.tsx    |   203 +
 packages/merchant-backend-ui/src/i18n/it.po        |  1057 +
 packages/merchant-backend-ui/src/i18n/poheader     |    27 +
 .../merchant-backend-ui/src/i18n/strings-prelude   |    19 +
 packages/merchant-backend-ui/src/i18n/strings.ts   |  3445 +++
 packages/merchant-backend-ui/src/i18n/sv.po        |  1057 +
 .../src/i18n/taler-merchant-backoffice.pot         |  1054 +
 packages/merchant-backend-ui/src/index.tsx         |    61 +
 .../src/pages/DepletedTip.stories.tsx              |    40 +
 .../merchant-backend-ui/src/pages/DepletedTip.tsx  |    60 +
 .../src/pages/OfferRefund.stories.tsx              |    45 +
 .../merchant-backend-ui/src/pages/OfferRefund.tsx  |   154 +
 .../src/pages/OfferTip.stories.tsx                 |    45 +
 .../merchant-backend-ui/src/pages/OfferTip.tsx     |   141 +
 .../src/pages/RequestPayment.stories.tsx           |    45 +
 .../src/pages/RequestPayment.tsx                   |   196 +
 .../src/pages/ShowOrderDetails.examples.ts         |   219 +
 .../src/pages/ShowOrderDetails.stories.tsx         |    49 +
 .../src/pages/ShowOrderDetails.tsx                 |   551 +
 packages/merchant-backend-ui/src/styled/index.tsx  |   178 +
 packages/merchant-backend-ui/src/utils/amount.ts   |    69 +
 .../merchant-backend-ui/src/utils/constants.ts     |    47 +
 packages/merchant-backend-ui/src/utils/table.ts    |    37 +
 packages/merchant-backend-ui/src/utils/types.ts    |    31 +
 .../tests/__mocks__/browserMocks.ts                |    42 +
 .../tests/__mocks__/fileMocks.ts                   |    24 +
 .../tests/__mocks__/fileTransformer.js             |    31 +
 .../tests/__mocks__/setupTests.ts                  |    28 +
 .../tests/funcitons/regex.test.ts                  |    87 +
 packages/merchant-backend-ui/tests/util.ts         |    62 +
 packages/merchant-backend-ui/tsconfig.back.json    |    23 +
 packages/merchant-backend-ui/tsconfig.json         |    61 +
 packages/merchant-backoffice-ui/.gitignore         |     6 +
 .../merchant-backoffice-ui/.storybook/.babelrc     |    25 +
 packages/merchant-backoffice-ui/.storybook/main.js |    57 +
 .../merchant-backoffice-ui/.storybook/preview.js   |    74 +
 .../merchant-backoffice-ui/contrib}/po2ts          |     0
 packages/merchant-backoffice-ui/copyleft-header.js |    15 +
 packages/merchant-backoffice-ui/package.json       |   123 +
 packages/merchant-backoffice-ui/preact.config.js   |    70 +
 .../merchant-backoffice-ui/preact.single-config.js |    62 +
 .../remove-link-stylesheet.sh                      |     8 +
 packages/merchant-backoffice-ui/src/.babelrc       |    26 +
 .../merchant-backoffice-ui/src/AdminRoutes.tsx     |    58 +
 .../src/ApplicationReadyRoutes.tsx                 |   120 +
 .../merchant-backoffice-ui/src/InstanceRoutes.tsx  |   528 +
 .../src/assets/empty.png                           |   Bin
 .../src/assets/icons/android-chrome-192x192.png    |   Bin
 .../src/assets/icons/android-chrome-512x512.png    |   Bin
 .../src/assets/icons/apple-touch-icon.png          |   Bin
 .../src/assets/icons/favicon-16x16.png             |   Bin
 .../src/assets/icons/favicon-32x32.png             |   Bin
 .../src/assets/icons/languageicon.svg              |     0
 .../src/assets/icons/mstile-150x150.png            |   Bin
 .../src/assets/logo.jpeg                           |   Bin
 .../src/components/exception/AsyncButton.tsx       |    49 +
 .../src/components/exception/QR.tsx                |    49 +
 .../src/components/exception/loading.tsx           |    32 +
 .../src/components/exception/login.tsx             |   143 +
 .../src/components/form/FormProvider.tsx           |    81 +
 .../src/components/form/Input.tsx                  |    71 +
 .../src/components/form/InputArray.tsx             |    97 +
 .../src/components/form/InputBoolean.tsx           |    72 +
 .../src/components/form/InputCurrency.tsx          |    47 +
 .../src/components/form/InputDate.tsx              |   159 +
 .../src/components/form/InputDuration.tsx          |   172 +
 .../src/components/form/InputGroup.tsx             |    66 +
 .../src/components/form/InputImage.tsx             |    95 +
 .../src/components/form/InputLocation.tsx          |    43 +
 .../src/components/form/InputNumber.tsx            |    42 +
 .../src/components/form/InputPayto.tsx             |    39 +
 .../src/components/form/InputPaytoForm.tsx         |   392 +
 .../src/components/form/InputSearchProduct.tsx     |   139 +
 .../src/components/form/InputSecured.stories.tsx   |    55 +
 .../src/components/form/InputSecured.tsx           |   119 +
 .../src/components/form/InputSelector.tsx          |    86 +
 .../src/components/form/InputStock.stories.tsx     |   162 +
 .../src/components/form/InputStock.tsx             |   171 +
 .../src/components/form/InputTaxes.tsx             |    97 +
 .../src/components/form/InputWithAddon.tsx         |    77 +
 .../src/components/form/TextField.tsx              |    53 +
 .../src/components/form/useField.tsx               |    86 +
 .../src/components/form/useGroupField.tsx          |    40 +
 .../instance/DefaultInstanceFormFields.tsx         |   135 +
 .../src/components/menu/LangSelector.tsx           |    73 +
 .../src/components/menu/NavigationBar.tsx          |    58 +
 .../src/components/menu/SideBar.tsx                |   227 +
 .../src/components/menu/index.tsx                  |   210 +
 .../src/components/modal/index.tsx                 |   262 +
 .../notifications/CreatedSuccessfully.tsx          |    49 +
 .../notifications/Notifications.stories.tsx        |    57 +
 .../src/components/notifications/index.tsx         |    52 +
 .../src/components/picker/DatePicker.tsx           |   324 +
 .../components/picker/DurationPicker.stories.tsx   |    50 +
 .../src/components/picker/DurationPicker.tsx       |   211 +
 .../product/InventoryProductForm.stories.tsx       |    58 +
 .../components/product/InventoryProductForm.tsx    |    95 +
 .../components/product/NonInventoryProductForm.tsx |   146 +
 .../src/components/product/ProductForm.tsx         |   176 +
 .../src/components/product/ProductList.tsx         |   105 +
 .../merchant-backoffice-ui/src/context/backend.ts  |    82 +
 .../merchant-backoffice-ui/src/context/config.ts   |    32 +
 .../merchant-backoffice-ui/src/context/fetch.ts    |    54 +
 .../merchant-backoffice-ui/src/context/instance.ts |    35 +
 .../merchant-backoffice-ui/src/context/listener.ts |    35 +
 .../src/context/translation.ts                     |    59 +
 packages/merchant-backoffice-ui/src/custom.d.ts    |    40 +
 .../merchant-backoffice-ui/src/declaration.d.ts    |  1443 ++
 packages/merchant-backoffice-ui/src/hooks/async.ts |    76 +
 .../merchant-backoffice-ui/src/hooks/backend.ts    |   319 +
 packages/merchant-backoffice-ui/src/hooks/index.ts |   110 +
 .../merchant-backoffice-ui/src/hooks/instance.ts   |   292 +
 .../merchant-backoffice-ui/src/hooks/listener.ts   |    81 +
 .../src/hooks/notifications.ts                     |    48 +
 packages/merchant-backoffice-ui/src/hooks/order.ts |   323 +
 .../merchant-backoffice-ui/src/hooks/product.ts    |   187 +
 .../merchant-backoffice-ui/src/hooks/reserves.ts   |   218 +
 .../merchant-backoffice-ui/src/hooks/transfer.ts   |   217 +
 packages/merchant-backoffice-ui/src/i18n/de.po     |  1057 +
 packages/merchant-backoffice-ui/src/i18n/en.po     |  1057 +
 packages/merchant-backoffice-ui/src/i18n/es.po     |  1065 +
 packages/merchant-backoffice-ui/src/i18n/fr.po     |  1057 +
 packages/merchant-backoffice-ui/src/i18n/index.tsx |   215 +
 packages/merchant-backoffice-ui/src/i18n/it.po     |  1057 +
 packages/merchant-backoffice-ui/src/i18n/poheader  |    27 +
 .../src/i18n/strings-prelude                       |    19 +
 .../merchant-backoffice-ui/src/i18n/strings.ts     |  3445 +++
 packages/merchant-backoffice-ui/src/i18n/sv.po     |  1057 +
 .../src/i18n/taler-merchant-backoffice.pot         |  1054 +
 packages/merchant-backoffice-ui/src/index.tsx      |   111 +
 packages/merchant-backoffice-ui/src/manifest.json  |    21 +
 .../src/paths/admin/create/Create.stories.tsx      |    46 +
 .../src/paths/admin/create/CreatePage.tsx          |   234 +
 .../admin/create/InstanceCreatedSuccessfully.tsx   |    65 +
 .../src/paths/admin/create/index.tsx               |    74 +
 .../src/paths/admin/list/TableActive.tsx           |   184 +
 .../src/paths/admin/list/View.stories.tsx          |    82 +
 .../src/paths/admin/list/View.tsx                  |    80 +
 .../src/paths/admin/list/index.tsx                 |   126 +
 .../src/paths/instance/details/DetailPage.tsx      |    87 +
 .../src/paths/instance/details/Details.stories.tsx |    61 +
 .../src/paths/instance/details/index.tsx           |    65 +
 .../src/paths/instance/kyc/list/ListPage.tsx       |   178 +
 .../src/paths/instance/kyc/list/index.tsx          |    51 +
 .../instance/orders/create/Create.stories.tsx      |    70 +
 .../paths/instance/orders/create/CreatePage.tsx    |   576 +
 .../orders/create/OrderCreatedSuccessfully.tsx     |    89 +
 .../src/paths/instance/orders/create/index.tsx     |    82 +
 .../instance/orders/details/Detail.stories.tsx     |   137 +
 .../paths/instance/orders/details/DetailPage.tsx   |   776 +
 .../src/paths/instance/orders/details/Timeline.tsx |   128 +
 .../src/paths/instance/orders/details/index.tsx    |    67 +
 .../paths/instance/orders/list/List.stories.tsx    |   107 +
 .../src/paths/instance/orders/list/ListPage.tsx    |   146 +
 .../src/paths/instance/orders/list/Table.tsx       |   412 +
 .../src/paths/instance/orders/list/index.tsx       |   171 +
 .../instance/products/create/Create.stories.tsx    |    42 +
 .../paths/instance/products/create/CreatePage.tsx  |    65 +
 .../products/create/CreatedSuccessfully.tsx        |    67 +
 .../src/paths/instance/products/create/index.tsx   |    55 +
 .../paths/instance/products/list/List.stories.tsx  |    58 +
 .../src/paths/instance/products/list/Table.tsx     |   479 +
 .../src/paths/instance/products/list/index.tsx     |    80 +
 .../instance/products/update/Update.stories.tsx    |    71 +
 .../paths/instance/products/update/UpdatePage.tsx  |    77 +
 .../src/paths/instance/products/update/index.tsx   |    71 +
 .../instance/reserves/create/Create.stories.tsx    |    42 +
 .../paths/instance/reserves/create/CreatePage.tsx  |   168 +
 .../create/CreatedSuccessfully.stories.tsx         |    53 +
 .../reserves/create/CreatedSuccessfully.tsx        |    79 +
 .../src/paths/instance/reserves/create/index.tsx   |    71 +
 .../paths/instance/reserves/details/DetailPage.tsx |   278 +
 .../instance/reserves/details/Details.stories.tsx  |   105 +
 .../paths/instance/reserves/details/TipInfo.tsx    |    87 +
 .../src/paths/instance/reserves/details/index.tsx  |    56 +
 .../instance/reserves/list/AutorizeTipModal.tsx    |    85 +
 .../instance/reserves/list/CreatedSuccessfully.tsx |   100 +
 .../paths/instance/reserves/list/List.stories.tsx  |   102 +
 .../src/paths/instance/reserves/list/Table.tsx     |   313 +
 .../src/paths/instance/reserves/list/index.tsx     |   117 +
 .../instance/transfers/create/Create.stories.tsx   |    43 +
 .../paths/instance/transfers/create/CreatePage.tsx |   104 +
 .../src/paths/instance/transfers/create/index.tsx  |    60 +
 .../paths/instance/transfers/list/List.stories.tsx |    93 +
 .../src/paths/instance/transfers/list/ListPage.tsx |    89 +
 .../src/paths/instance/transfers/list/Table.tsx    |   225 +
 .../src/paths/instance/transfers/list/index.tsx    |    85 +
 .../src/paths/instance/transfers/update/index.tsx  |    26 +
 .../src/paths/instance/update/Update.stories.tsx   |    61 +
 .../src/paths/instance/update/UpdatePage.tsx       |   259 +
 .../src/paths/instance/update/index.tsx            |   113 +
 .../src/paths/login/index.tsx                      |    29 +
 .../src/paths/notfound/index.tsx                   |    36 +
 .../merchant-backoffice-ui/src/schemas/index.ts    |   202 +
 .../src/scss/DurationPicker.scss                   |    71 +
 .../merchant-backoffice-ui/src/scss/_aside.scss    |   179 +
 .../merchant-backoffice-ui/src/scss/_card.scss     |    69 +
 .../src/scss/_custom-calendar.scss                 |   254 +
 .../merchant-backoffice-ui/src/scss/_footer.scss   |    35 +
 .../merchant-backoffice-ui/src/scss/_form.scss     |    64 +
 .../merchant-backoffice-ui/src/scss/_hero-bar.scss |    55 +
 .../merchant-backoffice-ui/src/scss/_loading.scss  |    51 +
 .../src/scss/_main-section.scss                    |    24 +
 .../merchant-backoffice-ui/src/scss/_misc.scss     |    50 +
 .../merchant-backoffice-ui/src/scss/_mixins.scss   |    34 +
 .../merchant-backoffice-ui/src/scss/_modal.scss    |    35 +
 .../merchant-backoffice-ui/src/scss/_nav-bar.scss  |   144 +
 .../merchant-backoffice-ui/src/scss/_table.scss    |   173 +
 .../src/scss/_theme-default.scss                   |   136 +
 .../merchant-backoffice-ui/src/scss/_tiles.scss    |    25 +
 .../src/scss/_title-bar.scss                       |    50 +
 .../src/scss/fonts/XRXV3I6Li01BKofINeaE.ttf        |   Bin
 .../src/scss/fonts/nunito.css                      |    22 +
 .../fonts/materialdesignicons-webfont-4.9.95.eot   |   Bin
 .../fonts/materialdesignicons-webfont-4.9.95.ttf   |   Bin
 .../fonts/materialdesignicons-webfont-4.9.95.woff  |   Bin
 .../fonts/materialdesignicons-webfont-4.9.95.woff2 |   Bin
 .../scss/icons/materialdesignicons-4.9.95.min.css  |     3 +
 .../merchant-backoffice-ui/src/scss/libs/_all.scss |    29 +
 packages/merchant-backoffice-ui/src/scss/main.scss |   191 +
 packages/merchant-backoffice-ui/src/sw.js          |    25 +
 packages/merchant-backoffice-ui/src/template.html  |    52 +
 .../merchant-backoffice-ui/src/utils/amount.ts     |    70 +
 .../merchant-backoffice-ui/src/utils/constants.ts  |   194 +
 .../src/utils/switchableAxios.ts                   |    66 +
 packages/merchant-backoffice-ui/src/utils/table.ts |    37 +
 packages/merchant-backoffice-ui/src/utils/types.ts |    31 +
 .../tests/__mocks__/browserMocks.ts                |    42 +
 .../tests/__mocks__/fileMocks.ts                   |    24 +
 .../tests/__mocks__/fileTransformer.js             |    31 +
 .../tests/__mocks__/setupTests.ts                  |    28 +
 packages/merchant-backoffice-ui/tests/axiosMock.ts |   445 +
 .../tests/context/backend.test.tsx                 |   172 +
 .../merchant-backoffice-ui/tests/declarations.d.ts |    28 +
 .../tests/functions/regex.test.ts                  |    87 +
 .../merchant-backoffice-ui/tests/header.test.tsx   |    63 +
 .../tests/hooks/async.test.ts                      |   158 +
 .../tests/hooks/listener.test.ts                   |    62 +
 .../tests/hooks/notification.test.ts               |    51 +
 .../tests/hooks/swr/index.tsx                      |    45 +
 .../tests/hooks/swr/instance.test.ts               |   636 +
 .../tests/hooks/swr/order.test.ts                  |   567 +
 .../tests/hooks/swr/product.test.ts                |   338 +
 .../tests/hooks/swr/reserve.test.ts                |   470 +
 .../tests/hooks/swr/transfer.test.ts               |   268 +
 .../merchant-backoffice-ui/tests/stories.test.tsx  |    89 +
 packages/merchant-backoffice-ui/tsconfig.json      |    61 +
 .../src/integrationtests/test-clause-schnorr.ts    |     2 +-
 pnpm-lock.yaml                                     | 23139 +++++++++++++++----
 403 files changed, 82224 insertions(+), 4775 deletions(-)
 copy packages/{anastasis-webui => demobank-ui}/.gitignore (100%)
 create mode 100644 packages/demobank-ui/.storybook/.babelrc
 create mode 100644 packages/demobank-ui/.storybook/main.js
 create mode 100644 packages/demobank-ui/.storybook/preview.js
 create mode 100644 packages/demobank-ui/README.md
 create mode 100644 packages/demobank-ui/TODO
 create mode 100755 packages/demobank-ui/build-bank-translations.sh
 copy {contrib => packages/demobank-ui/contrib}/po2ts (100%)
 create mode 100644 packages/demobank-ui/mocks/json-server/db.json
 create mode 100644 packages/demobank-ui/mocks/window.js
 create mode 100644 packages/demobank-ui/package.json
 create mode 100644 packages/demobank-ui/preact.config.js
 create mode 100644 packages/demobank-ui/preact.mock.js
 create mode 100644 packages/demobank-ui/preact.single-config.js
 create mode 100755 packages/demobank-ui/remove-link-stylesheet.sh
 create mode 100644 packages/demobank-ui/src/.babelrc
 copy packages/{anastasis-webui => demobank-ui}/src/assets/empty.png (100%)
 copy packages/{anastasis-webui => demobank-ui}/src/assets/example/id1.jpg 
(100%)
 copy packages/{anastasis-webui => demobank-ui}/src/assets/favicon.ico (100%)
 copy packages/{anastasis-webui => 
demobank-ui}/src/assets/icons/android-chrome-192x192.png (100%)
 copy packages/{anastasis-webui => 
demobank-ui}/src/assets/icons/android-chrome-512x512.png (100%)
 copy packages/{anastasis-webui => 
demobank-ui}/src/assets/icons/apple-touch-icon.png (100%)
 copy packages/{anastasis-webui => 
demobank-ui}/src/assets/icons/auth_method/email.svg (100%)
 copy packages/{anastasis-webui => 
demobank-ui}/src/assets/icons/auth_method/postal.svg (100%)
 copy packages/{anastasis-webui => 
demobank-ui}/src/assets/icons/auth_method/question.svg (100%)
 copy packages/{anastasis-webui => 
demobank-ui}/src/assets/icons/auth_method/sms.svg (100%)
 copy packages/{anastasis-webui => 
demobank-ui}/src/assets/icons/auth_method/video.svg (100%)
 copy packages/{anastasis-webui => 
demobank-ui}/src/assets/icons/favicon-16x16.png (100%)
 copy packages/{anastasis-webui => 
demobank-ui}/src/assets/icons/favicon-32x32.png (100%)
 copy packages/{anastasis-webui => 
demobank-ui}/src/assets/icons/languageicon.svg (100%)
 copy packages/{anastasis-webui => 
demobank-ui}/src/assets/icons/mstile-150x150.png (100%)
 create mode 100644 packages/demobank-ui/src/assets/logo-white.svg
 copy packages/{anastasis-webui => demobank-ui}/src/assets/logo.jpeg (100%)
 create mode 100644 packages/demobank-ui/src/components/AsyncButton.tsx
 create mode 100644 packages/demobank-ui/src/components/FileButton.tsx
 create mode 100644 packages/demobank-ui/src/components/Notifications.tsx
 create mode 100644 packages/demobank-ui/src/components/QR.tsx
 create mode 100644 packages/demobank-ui/src/components/app.tsx
 create mode 100644 packages/demobank-ui/src/components/fields/DateInput.tsx
 create mode 100644 packages/demobank-ui/src/components/fields/EmailInput.tsx
 create mode 100644 packages/demobank-ui/src/components/fields/FileInput.tsx
 create mode 100644 packages/demobank-ui/src/components/fields/ImageInput.tsx
 create mode 100644 packages/demobank-ui/src/components/fields/NumberInput.tsx
 create mode 100644 packages/demobank-ui/src/components/fields/TextInput.tsx
 create mode 100644 packages/demobank-ui/src/components/menu/LangSelector.tsx
 create mode 100644 packages/demobank-ui/src/components/menu/NavigationBar.tsx
 create mode 100644 packages/demobank-ui/src/components/menu/SideBar.tsx
 create mode 100644 packages/demobank-ui/src/components/menu/index.tsx
 create mode 100644 packages/demobank-ui/src/components/picker/DatePicker.tsx
 create mode 100644 
packages/demobank-ui/src/components/picker/DurationPicker.stories.tsx
 create mode 100644 
packages/demobank-ui/src/components/picker/DurationPicker.tsx
 create mode 100644 packages/demobank-ui/src/context/translation.ts
 create mode 100644 packages/demobank-ui/src/declaration.d.ts
 create mode 100644 packages/demobank-ui/src/hooks/async.ts
 create mode 100644 packages/demobank-ui/src/hooks/index.ts
 create mode 100644 packages/demobank-ui/src/i18n/bank.pot
 create mode 100644 packages/demobank-ui/src/i18n/de.po
 create mode 100644 packages/demobank-ui/src/i18n/en.po
 create mode 100644 packages/demobank-ui/src/i18n/index.tsx
 create mode 100644 packages/demobank-ui/src/i18n/it.po
 create mode 100644 packages/demobank-ui/src/i18n/poheader
 create mode 100644 packages/demobank-ui/src/i18n/strings-prelude
 create mode 100644 packages/demobank-ui/src/i18n/strings.ts
 create mode 100644 packages/demobank-ui/src/index.tsx
 create mode 100644 packages/demobank-ui/src/manifest.json
 create mode 100644 packages/demobank-ui/src/pages/home/index.tsx
 create mode 100644 packages/demobank-ui/src/pages/notfound/index.tsx
 copy packages/{pogen/example/proj1/src/sample.ts => 
demobank-ui/src/pages/notfound/style.css} (100%)
 create mode 100644 packages/demobank-ui/src/pages/profile/index.stories.tsx
 create mode 100644 packages/demobank-ui/src/pages/profile/index.tsx
 copy packages/{pogen/example/proj1/src/sample.ts => 
demobank-ui/src/pages/profile/style.css} (100%)
 copy packages/{anastasis-webui => demobank-ui}/src/scss/DurationPicker.scss 
(100%)
 create mode 100644 packages/demobank-ui/src/scss/_aside.scss
 create mode 100644 packages/demobank-ui/src/scss/_card.scss
 create mode 100644 packages/demobank-ui/src/scss/_custom-calendar.scss
 create mode 100644 packages/demobank-ui/src/scss/_footer.scss
 create mode 100644 packages/demobank-ui/src/scss/_form.scss
 create mode 100644 packages/demobank-ui/src/scss/_hero-bar.scss
 create mode 100644 packages/demobank-ui/src/scss/_loading.scss
 create mode 100644 packages/demobank-ui/src/scss/_main-section.scss
 create mode 100644 packages/demobank-ui/src/scss/_misc.scss
 create mode 100644 packages/demobank-ui/src/scss/_mixins.scss
 create mode 100644 packages/demobank-ui/src/scss/_modal.scss
 create mode 100644 packages/demobank-ui/src/scss/_nav-bar.scss
 create mode 100644 packages/demobank-ui/src/scss/_table.scss
 create mode 100644 packages/demobank-ui/src/scss/_theme-default.scss
 create mode 100644 packages/demobank-ui/src/scss/_tiles.scss
 create mode 100644 packages/demobank-ui/src/scss/_title-bar.scss
 create mode 100644 packages/demobank-ui/src/scss/bank.scss
 create mode 100644 packages/demobank-ui/src/scss/colors-bank.scss
 create mode 100644 packages/demobank-ui/src/scss/demo.scss
 copy packages/{anastasis-webui => 
demobank-ui}/src/scss/fonts/XRXV3I6Li01BKofINeaE.ttf (100%)
 create mode 100644 packages/demobank-ui/src/scss/fonts/nunito.css
 copy packages/{anastasis-webui/src/scss => 
demobank-ui/src/scss/icons}/fonts/materialdesignicons-webfont-4.9.95.eot (100%)
 copy packages/{anastasis-webui/src/scss => 
demobank-ui/src/scss/icons}/fonts/materialdesignicons-webfont-4.9.95.ttf (100%)
 copy packages/{anastasis-webui/src/scss => 
demobank-ui/src/scss/icons}/fonts/materialdesignicons-webfont-4.9.95.woff (100%)
 copy packages/{anastasis-webui/src/scss => 
demobank-ui/src/scss/icons}/fonts/materialdesignicons-webfont-4.9.95.woff2 
(100%)
 create mode 100644 
packages/demobank-ui/src/scss/icons/materialdesignicons-4.9.95.min.css
 create mode 100644 packages/demobank-ui/src/scss/libs/_all.scss
 create mode 100644 packages/demobank-ui/src/scss/main.scss
 create mode 100644 packages/demobank-ui/src/scss/pure.scss
 copy packages/{pogen/example/proj1/src/sample.ts => 
demobank-ui/src/style/index.css} (100%)
 create mode 100644 packages/demobank-ui/src/template.html
 create mode 100644 packages/demobank-ui/tests/__mocks__/browserMocks.ts
 create mode 100644 packages/demobank-ui/tests/__mocks__/fileMocks.ts
 create mode 100644 packages/demobank-ui/tests/__mocks__/setupTests.ts
 create mode 100644 packages/demobank-ui/tests/__tests__/homepage.js
 create mode 100644 packages/demobank-ui/tests/declarations.d.ts
 create mode 100644 packages/demobank-ui/tsconfig.json
 create mode 100644 packages/merchant-backend-ui/.gitignore
 create mode 100644 packages/merchant-backend-ui/.storybook/.babelrc
 create mode 100644 packages/merchant-backend-ui/.storybook/main.js
 create mode 100644 packages/merchant-backend-ui/.storybook/preview.js
 create mode 100644 packages/merchant-backend-ui/README.md
 copy {contrib => packages/merchant-backend-ui/contrib}/po2ts (100%)
 create mode 100644 packages/merchant-backend-ui/copyleft-header.js
 create mode 100644 packages/merchant-backend-ui/package.json
 create mode 100644 packages/merchant-backend-ui/render-examples.ts
 create mode 100644 packages/merchant-backend-ui/rollup.config.js
 copy packages/{anastasis-webui => merchant-backend-ui}/src/assets/empty.png 
(100%)
 copy packages/{anastasis-webui => 
merchant-backend-ui}/src/assets/icons/android-chrome-192x192.png (100%)
 copy packages/{anastasis-webui => 
merchant-backend-ui}/src/assets/icons/android-chrome-512x512.png (100%)
 copy packages/{anastasis-webui => 
merchant-backend-ui}/src/assets/icons/apple-touch-icon.png (100%)
 copy packages/{anastasis-webui => 
merchant-backend-ui}/src/assets/icons/favicon-16x16.png (100%)
 copy packages/{anastasis-webui => 
merchant-backend-ui}/src/assets/icons/favicon-32x32.png (100%)
 copy packages/{anastasis-webui => 
merchant-backend-ui}/src/assets/icons/languageicon.svg (100%)
 copy packages/{anastasis-webui => 
merchant-backend-ui}/src/assets/icons/mstile-150x150.png (100%)
 create mode 100644 packages/merchant-backend-ui/src/components/Footer.tsx
 create mode 100644 packages/merchant-backend-ui/src/components/QR.tsx
 create mode 100644 packages/merchant-backend-ui/src/context/backend.ts
 create mode 100644 packages/merchant-backend-ui/src/context/config.ts
 create mode 100644 packages/merchant-backend-ui/src/context/fetch.ts
 create mode 100644 packages/merchant-backend-ui/src/context/instance.ts
 create mode 100644 packages/merchant-backend-ui/src/context/listener.ts
 create mode 100644 packages/merchant-backend-ui/src/context/translation.ts
 create mode 100644 packages/merchant-backend-ui/src/css/pure-min.css
 create mode 100644 packages/merchant-backend-ui/src/css/style.css
 create mode 100644 packages/merchant-backend-ui/src/custom.d.ts
 create mode 100644 packages/merchant-backend-ui/src/declaration.d.ts
 create mode 100644 packages/merchant-backend-ui/src/hooks/async.ts
 create mode 100644 packages/merchant-backend-ui/src/hooks/backend.ts
 create mode 100644 packages/merchant-backend-ui/src/hooks/index.ts
 create mode 100644 packages/merchant-backend-ui/src/hooks/instance.ts
 create mode 100644 packages/merchant-backend-ui/src/hooks/listener.ts
 create mode 100644 packages/merchant-backend-ui/src/hooks/notification.ts
 create mode 100644 packages/merchant-backend-ui/src/hooks/notifications.ts
 create mode 100644 packages/merchant-backend-ui/src/hooks/order.ts
 create mode 100644 packages/merchant-backend-ui/src/hooks/product.ts
 create mode 100644 packages/merchant-backend-ui/src/hooks/tips.ts
 create mode 100644 packages/merchant-backend-ui/src/hooks/transfer.ts
 create mode 100644 packages/merchant-backend-ui/src/i18n/de.po
 create mode 100644 packages/merchant-backend-ui/src/i18n/en.po
 create mode 100644 packages/merchant-backend-ui/src/i18n/es.po
 create mode 100644 packages/merchant-backend-ui/src/i18n/fr.po
 create mode 100644 packages/merchant-backend-ui/src/i18n/index.tsx
 create mode 100644 packages/merchant-backend-ui/src/i18n/it.po
 create mode 100644 packages/merchant-backend-ui/src/i18n/poheader
 create mode 100644 packages/merchant-backend-ui/src/i18n/strings-prelude
 create mode 100644 packages/merchant-backend-ui/src/i18n/strings.ts
 create mode 100644 packages/merchant-backend-ui/src/i18n/sv.po
 create mode 100644 
packages/merchant-backend-ui/src/i18n/taler-merchant-backoffice.pot
 create mode 100644 packages/merchant-backend-ui/src/index.tsx
 create mode 100644 
packages/merchant-backend-ui/src/pages/DepletedTip.stories.tsx
 create mode 100644 packages/merchant-backend-ui/src/pages/DepletedTip.tsx
 create mode 100644 
packages/merchant-backend-ui/src/pages/OfferRefund.stories.tsx
 create mode 100644 packages/merchant-backend-ui/src/pages/OfferRefund.tsx
 create mode 100644 packages/merchant-backend-ui/src/pages/OfferTip.stories.tsx
 create mode 100644 packages/merchant-backend-ui/src/pages/OfferTip.tsx
 create mode 100644 
packages/merchant-backend-ui/src/pages/RequestPayment.stories.tsx
 create mode 100644 packages/merchant-backend-ui/src/pages/RequestPayment.tsx
 create mode 100644 
packages/merchant-backend-ui/src/pages/ShowOrderDetails.examples.ts
 create mode 100644 
packages/merchant-backend-ui/src/pages/ShowOrderDetails.stories.tsx
 create mode 100644 packages/merchant-backend-ui/src/pages/ShowOrderDetails.tsx
 create mode 100644 packages/merchant-backend-ui/src/styled/index.tsx
 create mode 100644 packages/merchant-backend-ui/src/utils/amount.ts
 create mode 100644 packages/merchant-backend-ui/src/utils/constants.ts
 create mode 100644 packages/merchant-backend-ui/src/utils/table.ts
 create mode 100644 packages/merchant-backend-ui/src/utils/types.ts
 create mode 100644 packages/merchant-backend-ui/tests/__mocks__/browserMocks.ts
 create mode 100644 packages/merchant-backend-ui/tests/__mocks__/fileMocks.ts
 create mode 100644 
packages/merchant-backend-ui/tests/__mocks__/fileTransformer.js
 create mode 100644 packages/merchant-backend-ui/tests/__mocks__/setupTests.ts
 create mode 100644 packages/merchant-backend-ui/tests/funcitons/regex.test.ts
 create mode 100644 packages/merchant-backend-ui/tests/util.ts
 create mode 100644 packages/merchant-backend-ui/tsconfig.back.json
 create mode 100644 packages/merchant-backend-ui/tsconfig.json
 create mode 100644 packages/merchant-backoffice-ui/.gitignore
 create mode 100644 packages/merchant-backoffice-ui/.storybook/.babelrc
 create mode 100644 packages/merchant-backoffice-ui/.storybook/main.js
 create mode 100644 packages/merchant-backoffice-ui/.storybook/preview.js
 copy {contrib => packages/merchant-backoffice-ui/contrib}/po2ts (100%)
 create mode 100644 packages/merchant-backoffice-ui/copyleft-header.js
 create mode 100644 packages/merchant-backoffice-ui/package.json
 create mode 100644 packages/merchant-backoffice-ui/preact.config.js
 create mode 100644 packages/merchant-backoffice-ui/preact.single-config.js
 create mode 100644 packages/merchant-backoffice-ui/remove-link-stylesheet.sh
 create mode 100644 packages/merchant-backoffice-ui/src/.babelrc
 create mode 100644 packages/merchant-backoffice-ui/src/AdminRoutes.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/ApplicationReadyRoutes.tsx
 create mode 100644 packages/merchant-backoffice-ui/src/InstanceRoutes.tsx
 copy packages/{anastasis-webui => merchant-backoffice-ui}/src/assets/empty.png 
(100%)
 copy packages/{anastasis-webui => 
merchant-backoffice-ui}/src/assets/icons/android-chrome-192x192.png (100%)
 copy packages/{anastasis-webui => 
merchant-backoffice-ui}/src/assets/icons/android-chrome-512x512.png (100%)
 copy packages/{anastasis-webui => 
merchant-backoffice-ui}/src/assets/icons/apple-touch-icon.png (100%)
 copy packages/{anastasis-webui => 
merchant-backoffice-ui}/src/assets/icons/favicon-16x16.png (100%)
 copy packages/{anastasis-webui => 
merchant-backoffice-ui}/src/assets/icons/favicon-32x32.png (100%)
 copy packages/{anastasis-webui => 
merchant-backoffice-ui}/src/assets/icons/languageicon.svg (100%)
 copy packages/{anastasis-webui => 
merchant-backoffice-ui}/src/assets/icons/mstile-150x150.png (100%)
 copy packages/{anastasis-webui => merchant-backoffice-ui}/src/assets/logo.jpeg 
(100%)
 create mode 100644 
packages/merchant-backoffice-ui/src/components/exception/AsyncButton.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/exception/QR.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/exception/loading.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/exception/login.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/form/FormProvider.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/form/Input.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/form/InputArray.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/form/InputBoolean.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/form/InputCurrency.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/form/InputDate.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/form/InputDuration.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/form/InputGroup.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/form/InputImage.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/form/InputLocation.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/form/InputNumber.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/form/InputPayto.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/form/InputPaytoForm.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/form/InputSearchProduct.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/form/InputSecured.stories.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/form/InputSecured.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/form/InputSelector.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/form/InputStock.stories.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/form/InputStock.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/form/InputTaxes.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/form/InputWithAddon.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/form/TextField.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/form/useField.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/form/useGroupField.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/instance/DefaultInstanceFormFields.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/menu/LangSelector.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/menu/NavigationBar.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/menu/index.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/modal/index.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/notifications/CreatedSuccessfully.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/notifications/Notifications.stories.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/notifications/index.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/picker/DatePicker.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/picker/DurationPicker.stories.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/picker/DurationPicker.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/product/InventoryProductForm.stories.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/product/InventoryProductForm.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/product/NonInventoryProductForm.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/product/ProductForm.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/components/product/ProductList.tsx
 create mode 100644 packages/merchant-backoffice-ui/src/context/backend.ts
 create mode 100644 packages/merchant-backoffice-ui/src/context/config.ts
 create mode 100644 packages/merchant-backoffice-ui/src/context/fetch.ts
 create mode 100644 packages/merchant-backoffice-ui/src/context/instance.ts
 create mode 100644 packages/merchant-backoffice-ui/src/context/listener.ts
 create mode 100644 packages/merchant-backoffice-ui/src/context/translation.ts
 create mode 100644 packages/merchant-backoffice-ui/src/custom.d.ts
 create mode 100644 packages/merchant-backoffice-ui/src/declaration.d.ts
 create mode 100644 packages/merchant-backoffice-ui/src/hooks/async.ts
 create mode 100644 packages/merchant-backoffice-ui/src/hooks/backend.ts
 create mode 100644 packages/merchant-backoffice-ui/src/hooks/index.ts
 create mode 100644 packages/merchant-backoffice-ui/src/hooks/instance.ts
 create mode 100644 packages/merchant-backoffice-ui/src/hooks/listener.ts
 create mode 100644 packages/merchant-backoffice-ui/src/hooks/notifications.ts
 create mode 100644 packages/merchant-backoffice-ui/src/hooks/order.ts
 create mode 100644 packages/merchant-backoffice-ui/src/hooks/product.ts
 create mode 100644 packages/merchant-backoffice-ui/src/hooks/reserves.ts
 create mode 100644 packages/merchant-backoffice-ui/src/hooks/transfer.ts
 create mode 100644 packages/merchant-backoffice-ui/src/i18n/de.po
 create mode 100644 packages/merchant-backoffice-ui/src/i18n/en.po
 create mode 100644 packages/merchant-backoffice-ui/src/i18n/es.po
 create mode 100644 packages/merchant-backoffice-ui/src/i18n/fr.po
 create mode 100644 packages/merchant-backoffice-ui/src/i18n/index.tsx
 create mode 100644 packages/merchant-backoffice-ui/src/i18n/it.po
 create mode 100644 packages/merchant-backoffice-ui/src/i18n/poheader
 create mode 100644 packages/merchant-backoffice-ui/src/i18n/strings-prelude
 create mode 100644 packages/merchant-backoffice-ui/src/i18n/strings.ts
 create mode 100644 packages/merchant-backoffice-ui/src/i18n/sv.po
 create mode 100644 
packages/merchant-backoffice-ui/src/i18n/taler-merchant-backoffice.pot
 create mode 100644 packages/merchant-backoffice-ui/src/index.tsx
 create mode 100644 packages/merchant-backoffice-ui/src/manifest.json
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/admin/create/Create.stories.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/admin/create/CreatePage.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/admin/create/InstanceCreatedSuccessfully.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/admin/create/index.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/admin/list/TableActive.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/admin/list/View.stories.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/admin/list/View.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/admin/list/index.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/details/DetailPage.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/details/Details.stories.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/details/index.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/kyc/list/ListPage.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/kyc/list/index.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/orders/create/Create.stories.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/orders/create/CreatePage.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/orders/create/OrderCreatedSuccessfully.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/orders/create/index.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/orders/details/Detail.stories.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/orders/details/DetailPage.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/orders/details/Timeline.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/orders/details/index.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/orders/list/List.stories.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/orders/list/ListPage.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/orders/list/Table.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/orders/list/index.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/products/create/Create.stories.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/products/create/CreatePage.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/products/create/CreatedSuccessfully.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/products/create/index.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/products/list/List.stories.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/products/list/Table.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/products/list/index.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/products/update/Update.stories.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/products/update/UpdatePage.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/products/update/index.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/reserves/create/Create.stories.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatePage.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatedSuccessfully.stories.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatedSuccessfully.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/reserves/create/index.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/reserves/details/DetailPage.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/reserves/details/Details.stories.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/reserves/details/TipInfo.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/reserves/details/index.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/reserves/list/AutorizeTipModal.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/reserves/list/CreatedSuccessfully.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/reserves/list/List.stories.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/reserves/list/Table.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/reserves/list/index.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/transfers/create/Create.stories.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/transfers/create/CreatePage.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/transfers/create/index.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/transfers/list/List.stories.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/transfers/list/ListPage.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/transfers/list/Table.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/transfers/list/index.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/transfers/update/index.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/update/Update.stories.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx
 create mode 100644 
packages/merchant-backoffice-ui/src/paths/instance/update/index.tsx
 create mode 100644 packages/merchant-backoffice-ui/src/paths/login/index.tsx
 create mode 100644 packages/merchant-backoffice-ui/src/paths/notfound/index.tsx
 create mode 100644 packages/merchant-backoffice-ui/src/schemas/index.ts
 create mode 100644 packages/merchant-backoffice-ui/src/scss/DurationPicker.scss
 create mode 100644 packages/merchant-backoffice-ui/src/scss/_aside.scss
 create mode 100644 packages/merchant-backoffice-ui/src/scss/_card.scss
 create mode 100644 
packages/merchant-backoffice-ui/src/scss/_custom-calendar.scss
 create mode 100644 packages/merchant-backoffice-ui/src/scss/_footer.scss
 create mode 100644 packages/merchant-backoffice-ui/src/scss/_form.scss
 create mode 100644 packages/merchant-backoffice-ui/src/scss/_hero-bar.scss
 create mode 100644 packages/merchant-backoffice-ui/src/scss/_loading.scss
 create mode 100644 packages/merchant-backoffice-ui/src/scss/_main-section.scss
 create mode 100644 packages/merchant-backoffice-ui/src/scss/_misc.scss
 create mode 100644 packages/merchant-backoffice-ui/src/scss/_mixins.scss
 create mode 100644 packages/merchant-backoffice-ui/src/scss/_modal.scss
 create mode 100644 packages/merchant-backoffice-ui/src/scss/_nav-bar.scss
 create mode 100644 packages/merchant-backoffice-ui/src/scss/_table.scss
 create mode 100644 packages/merchant-backoffice-ui/src/scss/_theme-default.scss
 create mode 100644 packages/merchant-backoffice-ui/src/scss/_tiles.scss
 create mode 100644 packages/merchant-backoffice-ui/src/scss/_title-bar.scss
 copy packages/{anastasis-webui => 
merchant-backoffice-ui}/src/scss/fonts/XRXV3I6Li01BKofINeaE.ttf (100%)
 create mode 100644 packages/merchant-backoffice-ui/src/scss/fonts/nunito.css
 copy packages/{anastasis-webui/src/scss => 
merchant-backoffice-ui/src/scss/icons}/fonts/materialdesignicons-webfont-4.9.95.eot
 (100%)
 copy packages/{anastasis-webui/src/scss => 
merchant-backoffice-ui/src/scss/icons}/fonts/materialdesignicons-webfont-4.9.95.ttf
 (100%)
 copy packages/{anastasis-webui/src/scss => 
merchant-backoffice-ui/src/scss/icons}/fonts/materialdesignicons-webfont-4.9.95.woff
 (100%)
 copy packages/{anastasis-webui/src/scss => 
merchant-backoffice-ui/src/scss/icons}/fonts/materialdesignicons-webfont-4.9.95.woff2
 (100%)
 create mode 100644 
packages/merchant-backoffice-ui/src/scss/icons/materialdesignicons-4.9.95.min.css
 create mode 100644 packages/merchant-backoffice-ui/src/scss/libs/_all.scss
 create mode 100644 packages/merchant-backoffice-ui/src/scss/main.scss
 create mode 100644 packages/merchant-backoffice-ui/src/sw.js
 create mode 100644 packages/merchant-backoffice-ui/src/template.html
 create mode 100644 packages/merchant-backoffice-ui/src/utils/amount.ts
 create mode 100644 packages/merchant-backoffice-ui/src/utils/constants.ts
 create mode 100644 packages/merchant-backoffice-ui/src/utils/switchableAxios.ts
 create mode 100644 packages/merchant-backoffice-ui/src/utils/table.ts
 create mode 100644 packages/merchant-backoffice-ui/src/utils/types.ts
 create mode 100644 
packages/merchant-backoffice-ui/tests/__mocks__/browserMocks.ts
 create mode 100644 packages/merchant-backoffice-ui/tests/__mocks__/fileMocks.ts
 create mode 100644 
packages/merchant-backoffice-ui/tests/__mocks__/fileTransformer.js
 create mode 100644 
packages/merchant-backoffice-ui/tests/__mocks__/setupTests.ts
 create mode 100644 packages/merchant-backoffice-ui/tests/axiosMock.ts
 create mode 100644 
packages/merchant-backoffice-ui/tests/context/backend.test.tsx
 create mode 100644 packages/merchant-backoffice-ui/tests/declarations.d.ts
 create mode 100644 
packages/merchant-backoffice-ui/tests/functions/regex.test.ts
 create mode 100644 packages/merchant-backoffice-ui/tests/header.test.tsx
 create mode 100644 packages/merchant-backoffice-ui/tests/hooks/async.test.ts
 create mode 100644 packages/merchant-backoffice-ui/tests/hooks/listener.test.ts
 create mode 100644 
packages/merchant-backoffice-ui/tests/hooks/notification.test.ts
 create mode 100644 packages/merchant-backoffice-ui/tests/hooks/swr/index.tsx
 create mode 100644 
packages/merchant-backoffice-ui/tests/hooks/swr/instance.test.ts
 create mode 100644 
packages/merchant-backoffice-ui/tests/hooks/swr/order.test.ts
 create mode 100644 
packages/merchant-backoffice-ui/tests/hooks/swr/product.test.ts
 create mode 100644 
packages/merchant-backoffice-ui/tests/hooks/swr/reserve.test.ts
 create mode 100644 
packages/merchant-backoffice-ui/tests/hooks/swr/transfer.test.ts
 create mode 100644 packages/merchant-backoffice-ui/tests/stories.test.tsx
 create mode 100644 packages/merchant-backoffice-ui/tsconfig.json

diff --git a/packages/anastasis-webui/.gitignore 
b/packages/demobank-ui/.gitignore
similarity index 100%
copy from packages/anastasis-webui/.gitignore
copy to packages/demobank-ui/.gitignore
diff --git a/packages/demobank-ui/.storybook/.babelrc 
b/packages/demobank-ui/.storybook/.babelrc
new file mode 100644
index 000000000..610b6f339
--- /dev/null
+++ b/packages/demobank-ui/.storybook/.babelrc
@@ -0,0 +1,25 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+{
+    "presets": [
+        "preact-cli/babel"
+    ]
+}
\ No newline at end of file
diff --git a/packages/demobank-ui/.storybook/main.js 
b/packages/demobank-ui/.storybook/main.js
new file mode 100644
index 000000000..f8e4bbcc7
--- /dev/null
+++ b/packages/demobank-ui/.storybook/main.js
@@ -0,0 +1,57 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+
+module.exports = {
+  "stories": [
+    "../src/**/*.stories.mdx",
+    "../src/**/*.stories.@(js|jsx|ts|tsx)"
+  ],
+  "addons": [
+    "@storybook/preset-scss",
+    "@storybook/addon-a11y",
+    "@storybook/addon-essentials" //docs, control, actions, viewpot, toolbar, 
background
+  ],
+  // sb does not yet support new jsx transform by default
+  // https://github.com/storybookjs/storybook/issues/12881
+  // https://github.com/storybookjs/storybook/issues/12952
+  babel: async (options) => ({
+    ...options,
+    presets: [
+      ...options.presets,
+      [
+        '@babel/preset-react', {
+          runtime: 'automatic',
+        },
+        'preset-react-jsx-transform' 
+      ],
+    ],
+  }),
+  webpackFinal: (config) => {
+    // should be removed after storybook 6.3
+    // 
https://github.com/storybookjs/storybook/issues/12853#issuecomment-821576113
+    config.resolve.alias = {
+      react: "preact/compat",
+      "react-dom": "preact/compat",
+    };
+    return config;
+  },
+}
\ No newline at end of file
diff --git a/packages/demobank-ui/.storybook/preview.js 
b/packages/demobank-ui/.storybook/preview.js
new file mode 100644
index 000000000..9ab4d9404
--- /dev/null
+++ b/packages/demobank-ui/.storybook/preview.js
@@ -0,0 +1,55 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+import "../src/scss/main.scss"
+import { TranslationProvider } from '../src/context/translation'
+import { h } from 'preact';
+
+
+export const parameters = {
+  controls: { expanded: true },
+  options: {
+    storySort: (a, b) => {
+      return (a[1].args.order ?? 0) - (b[1].args.order ?? 0)
+      // return a[1].kind === b[1].kind ? 0 : a[1].id.localeCompare(b[1].id, 
undefined, { numeric: true })
+    }
+  },
+}
+
+export const globalTypes = {
+  locale: {
+    name: 'Locale',
+    description: 'Internationalization locale',
+    defaultValue: 'en',
+    toolbar: {
+      icon: 'globe',
+      items: [
+        { value: 'en', right: '🇺🇸', title: 'English' },
+        { value: 'es', right: '🇪🇸', title: 'Spanish' },
+      ],
+    },
+  },
+};
+
+export const decorators = [
+  (Story, { globals }) => {
+    document.body.parentElement.classList = "has-aside-left 
has-aside-mobile-transition has-navbar-fixed-top has-aside-expanded"
+    return <Story />
+  },
+  (Story, { globals }) => <TranslationProvider initial='en' 
forceLang={globals.locale}>
+    <Story />
+  </TranslationProvider>,
+];
diff --git a/packages/demobank-ui/README.md b/packages/demobank-ui/README.md
new file mode 100644
index 000000000..c014929ce
--- /dev/null
+++ b/packages/demobank-ui/README.md
@@ -0,0 +1,19 @@
+# bank web
+
+## CLI Commands
+
+- `npm install`: Installs dependencies
+
+- `npm run dev`: Run a development, HMR server
+
+- `npm run serve`: Run a production-like server
+
+- `npm run build`: Production-ready build
+
+- `npm run lint`: Pass TypeScript files using ESLint
+
+- `npm run test`: Run Jest and Enzyme with
+  
[`enzyme-adapter-preact-pure`](https://github.com/preactjs/enzyme-adapter-preact-pure)
 for
+  your tests
+
+For detailed explanation on how things work, checkout the [CLI 
Readme](https://github.com/developit/preact-cli/blob/master/README.md).
diff --git a/packages/demobank-ui/TODO b/packages/demobank-ui/TODO
new file mode 100644
index 000000000..a399ada58
--- /dev/null
+++ b/packages/demobank-ui/TODO
@@ -0,0 +1,45 @@
+Urgent TODOs:
+
+- General:
+  * not only Nora dark-theme, but default light! (CSS)
+  * auto-focus on input fields is not working well
+  * buttons should be visibly insensitive
+    as long as required input fields are not
+    working
+  * next required invalid/missing input field is
+    not properly highlighted in red
+  * Logout button needs more padding to the right (CSS)
+
+- Error bar:
+  * shows JSON, should only show good error message
+    and numeric code, not JSON syntax
+  * should auto-hide after next action, no need for
+    "clear"!
+  * need variant "status bar" in green (or blue)
+    which shows status of last operation
+
+* H1-Titles:
+  * Center more (currently way on the left) (CSS)
+
+- Assets:
+  * Numeric amount needs to be shown MUCH bigger (CSS)
+  * Center more? (CSS)
+
+- Payments:
+  * Amount to withdraw currently shown in white-on-white (CSS)
+  * Big frame drawn around notebook-tabs is not nice (CSS)
+  * Center more? (CSS)
+  * "Wire to bank account"
+    - maybe split two types (payto and IBAN) into
+      two tabs?
+    - currently cannot switch back from payto to IBAN
+
+- Withdraw:
+  * Should use new 'status' bar at the end, instead
+    of extra dialog with "close" button
+  * ditto for bank-wire-transfer final stage
+
+- Footer:
+  * overlaps with transaction history or other
+    content, needs to consistently show at the
+    end! => change rendering logic!? (CSS?)
diff --git a/packages/demobank-ui/build-bank-translations.sh 
b/packages/demobank-ui/build-bank-translations.sh
new file mode 100755
index 000000000..85c8ad0c1
--- /dev/null
+++ b/packages/demobank-ui/build-bank-translations.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+set -eu
+
+# NOTE: the <Translate> node somehow didn't get
+# the strings extracted.  Only i18n`` did
+
+function build {
+  POTGEN=node_modules/@gnu-taler/pogen/bin/pogen
+  PACKAGE_NAME=$1
+
+  find src/ \( -type f -name "*.ts" -or -name "*.tsx" \) ! -name "*.d.ts" \
+      | xargs node $POTGEN \
+      | msguniq \
+      | msgmerge src/i18n/poheader - \
+      > src/i18n/$PACKAGE_NAME.pot
+  
+  # merge existing translations: fails when NO .po-files were found.
+  for pofile in $(ls src/i18n/*.po 2> /dev/null || true); do 
+    echo merging $pofile; 
+    msgmerge -o $pofile $pofile src/i18n/$PACKAGE_NAME.pot; 
+  done;
+  
+  # generate .ts file containing all translations
+  cat src/i18n/strings-prelude > src/i18n/strings.ts
+  for pofile in $(ls src/i18n/*.po 2> /dev/null || true); do \
+    echo appending $pofile; \
+    ./contrib/po2ts $pofile >> src/i18n/strings.ts; \
+  done; 
+}
+
+build bank
diff --git a/contrib/po2ts b/packages/demobank-ui/contrib/po2ts
similarity index 100%
copy from contrib/po2ts
copy to packages/demobank-ui/contrib/po2ts
diff --git a/packages/demobank-ui/mocks/json-server/db.json 
b/packages/demobank-ui/mocks/json-server/db.json
new file mode 100644
index 000000000..44d3ccab2
--- /dev/null
+++ b/packages/demobank-ui/mocks/json-server/db.json
@@ -0,0 +1,4 @@
+{
+  "register": {},
+  "transactions": {}
+}
diff --git a/packages/demobank-ui/mocks/window.js 
b/packages/demobank-ui/mocks/window.js
new file mode 100644
index 000000000..f396ff9e3
--- /dev/null
+++ b/packages/demobank-ui/mocks/window.js
@@ -0,0 +1,27 @@
+Object.defineProperty(window, 'requestAnimationFrame', {
+  value: function(cb) {} // Silence the browser.
+})
+
+Object.defineProperty(window, 'localStorage', {
+  value: {
+    store: {},
+    getItem: function(key) {
+      return this.store[key];
+    },
+    setItem: function(key, value) {
+      return this.store[key] = value;
+    },
+    clear: function() {
+      this.store = {};
+    }
+  }
+});
+Object.defineProperty(window, 'location', {
+  value: {
+    origin: "http://localhost:8080";, /* where taler-local rev proxy listens to 
*/
+    search: "",
+    pathname: "/sandbox/demobanks/default",
+  }
+})
+
+export default window;
diff --git a/packages/demobank-ui/package.json 
b/packages/demobank-ui/package.json
new file mode 100644
index 000000000..bd686365b
--- /dev/null
+++ b/packages/demobank-ui/package.json
@@ -0,0 +1,100 @@
+{
+  "private": true,
+  "name": "bank",
+  "version": "0.1.0",
+  "license": "AGPL-3.0-OR-LATER",
+  "scripts": {
+    "dev": "preact watch --port ${PORT:=9090} --no-sw --no-esm -c 
preact.mock.js",
+    "build": "preact build --no-sw --no-esm -c preact.single-config.js --dest 
build && sh remove-link-stylesheet.sh",
+    "serve": "sirv build --port ${PORT:=8080} --cors --single",
+    "lint": "eslint 'src/**/*.{js,jsx,ts,tsx}'",
+    "test": "jest ./tests",
+    "build-storybook": "build-storybook",
+    "serve-single": "sirv single --port ${PORT:=8080} --cors --single",
+    "pretty": "prettier --write src",
+    "storybook": "start-storybook -p 6006"
+  },
+  "eslintConfig": {
+    "parser": "@typescript-eslint/parser",
+    "extends": [
+      "preact",
+      "plugin:@typescript-eslint/recommended"
+    ],
+    "ignorePatterns": [
+      "build/"
+    ],
+    "rules": {
+      "@typescript-eslint/no-explicit-any": [0],
+      "@typescript-eslint/ban-ts-comment": [1],
+      "quotes": [2, "single", {"allowTemplateLiterals": true,"avoidEscape": 
false}],
+      "indent": [2,2],
+      "prefer-arrow-callback": [2, {"allowNamedFunctions": false, 
"allowUnboundThis": true}],
+      "curly": [2,"multi"],
+      "prefer-template": [1]
+    }
+  },
+  "dependencies": {
+    "base64-inline-loader": "1.1.1",
+    "date-fns": "2.25.0",
+    "jed": "1.1.1",
+    "preact": "^10.5.15",
+    "preact-render-to-string": "^5.1.19",
+    "preact-router": "^3.2.1",
+    "qrcode-generator": "^1.4.4",
+    "swr": "1.1"
+  },
+  "devDependencies": {
+    "@babel/core": "^7.13.16",
+    "@babel/plugin-transform-react-jsx": "^7.12.13",
+    "@babel/plugin-transform-react-jsx-source": "^7.12.13",
+    "@babel/preset-env": "^7.16.7",
+    "@creativebulma/bulma-tooltip": "^1.2.0",
+    "@gnu-taler/pogen": "^0.0.5",
+    "@storybook/addon-a11y": "6.2.9",
+    "@storybook/addon-actions": "6.2.9",
+    "@storybook/addon-essentials": "6.2.9",
+    "@storybook/addon-links": "6.2.9",
+    "@storybook/preact": "6.2.9",
+    "@storybook/preset-scss": "^1.0.3",
+    "@testing-library/jest-dom": "^5.16.1",
+    "@testing-library/preact": "^2.0.1",
+    "@testing-library/preact-hooks": "^1.1.0",
+    "@types/enzyme": "^3.10.10",
+    "@types/jest": "^27.0.2",
+    "@typescript-eslint/eslint-plugin": "^5.3.0",
+    "@typescript-eslint/parser": "^5.3.0",
+    "babel-loader": "^8.2.2",
+    "base64-inline-loader": "^1.1.1",
+    "bulma": "^0.9.3",
+    "bulma-checkbox": "^1.1.1",
+    "bulma-radio": "^1.1.1",
+    "enzyme": "^3.11.0",
+    "enzyme-adapter-preact-pure": "^3.2.0",
+    "eslint": "^8.1.0",
+    "eslint-config-preact": "^1.2.0",
+    "html-webpack-inline-chunk-plugin": "^1.1.1",
+    "html-webpack-inline-source-plugin": "0.0.10",
+    "html-webpack-skip-assets-plugin": "^1.0.1",
+    "inline-chunk-html-plugin": "^1.1.1",
+    "jest": "^27.3.1",
+    "jest-fetch-mock": "^3.0.3",
+    "jest-preset-preact": "^4.0.5",
+    "jest-watch-typeahead": "^1.0.0",
+    "jest-environment-jsdom": "^27.4.6",
+    "jssha": "^3.2.0",
+    "po2json": "^0.4.5",
+    "preact-cli": "3.0.5",
+    "sass": "1.32.13",
+    "sass-loader": "^10",
+    "script-ext-html-webpack-plugin": "^2.1.5",
+    "sirv-cli": "^1.0.14",
+    "typescript": "^4.4.4"
+  },
+  "jest": {
+    "preset": "jest-preset-preact",
+    "setupFiles": [
+      "<rootDir>/tests/__mocks__/browserMocks.ts",
+      "<rootDir>/tests/__mocks__/setupTests.ts"
+    ]
+  }
+}
diff --git a/packages/demobank-ui/preact.config.js 
b/packages/demobank-ui/preact.config.js
new file mode 100644
index 000000000..8e640f3ff
--- /dev/null
+++ b/packages/demobank-ui/preact.config.js
@@ -0,0 +1,70 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { DefinePlugin } from 'webpack';
+
+import pack from './package.json';
+import * as cp from 'child_process';
+
+const commitHash = cp.execSync('git rev-parse --short HEAD').toString();
+
+export default {
+  webpack(config, env, helpers) {
+    // ensure that process.env will not be undefined on runtime
+    config.node.process = 'mock'
+
+    // add __VERSION__ to be use in the html
+    config.plugins.push(
+      new DefinePlugin({
+        'process.env.__VERSION__': JSON.stringify(env.isProd ? pack.version : 
`dev-${commitHash}`) ,
+      }),
+    );
+
+    // suddenly getting out of memory error from build process, error below [1]
+    // FIXME: remove preact-cli, use rollup
+    let { index } = helpers.getPluginsByName(config, 
'WebpackFixStyleOnlyEntriesPlugin')[0]
+    config.plugins.splice(index, 1)   
+  }
+}
+
+
+
+/* [1] from this error decided to remove plugin 'webpack-fix-style-only-entries
+   leaving this error for future reference
+
+
+<--- Last few GCs --->
+
+[32479:0x2e01870]    19969 ms: Mark-sweep 1869.4 (1950.2) -> 1443.1 (1504.1) 
MB, 497.5 / 0.0 ms  (average mu = 0.631, current mu = 0.455) allocation failure 
scavenge might not succeed
+[32479:0x2e01870]    21907 ms: Mark-sweep 2016.9 (2077.9) -> 1628.6 (1681.4) 
MB, 1596.0 / 0.0 ms  (average mu = 0.354, current mu = 0.176) allocation 
failure scavenge might not succeed
+
+<--- JS stacktrace --->
+
+==== JS stack trace =========================================
+
+    0: ExitFrame [pc: 0x13cf099]
+Security context: 0x2f4ca66c08d1 <JSObject>
+    1: /* anonymous * / [0x35d05555b4b9] 
[...path/merchant-backoffice/node_modules/.pnpm/webpack-fix-style-only-entries@0.5.2/node_modules/webpack-fix-style-only-entries/index.js:~80]
 [pc=0x2145e699d1a4](this=0x1149465410e9 <GlobalObject Object map = 
0xff481b5b5f9>,0x047e52e36a49 <Dependency map = 0x1ed1fe41cd19>)
+    2: arguments adaptor frame: 3...
+
+FATAL ERROR: invalid array length Allocation failed - JavaScript heap out of 
memory
+ 
+*/
\ No newline at end of file
diff --git a/packages/demobank-ui/preact.mock.js 
b/packages/demobank-ui/preact.mock.js
new file mode 100644
index 000000000..dc3ceb66d
--- /dev/null
+++ b/packages/demobank-ui/preact.mock.js
@@ -0,0 +1,55 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { DefinePlugin, ProvidePlugin } from 'webpack';
+
+import pack from './package.json';
+import * as cp from 'child_process';
+
+const commitHash = cp.execSync('git rev-parse --short HEAD').toString();
+import path from 'path';
+
+export default {
+  webpack(config, env, helpers) {
+    // Ensure that process.env will not be undefined at runtime.
+    config.node.process = 'mock'
+    let DEMO_SITES = {
+      "Blog": process.env.TALER_ENV_URL_MERCHANT_BLOG,
+      "Donations": process.env.TALER_ENV_URL_MERCHANT_DONATIONS,
+      "Survey": process.env.TALER_ENV_URL_MERCHANT_SURVEY,
+      "Landing": process.env.TALER_ENV_URL_INTRO,
+      "Bank": process.env.TALER_ENV_URL_BANK,
+    }
+    console.log("demo links found", DEMO_SITES);
+    // Add __VERSION__ to be use in the html.
+    config.plugins.push(
+      new DefinePlugin({
+        'process.env.__VERSION__': JSON.stringify(env.isProd ? pack.version : 
`dev-${commitHash}`) ,
+      }),
+      // 'window' gets mocked to point at a running euFin instance.
+      new ProvidePlugin({window: path.resolve("mocks/window")}),
+      new DefinePlugin({"DEMO_SITES": JSON.stringify(DEMO_SITES)})
+    );
+
+    let { index } = helpers.getPluginsByName(config, 
'WebpackFixStyleOnlyEntriesPlugin')[0]
+    config.plugins.splice(index, 1)   
+  }
+}
diff --git a/packages/demobank-ui/preact.single-config.js 
b/packages/demobank-ui/preact.single-config.js
new file mode 100644
index 000000000..0fb6f1d0e
--- /dev/null
+++ b/packages/demobank-ui/preact.single-config.js
@@ -0,0 +1,60 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import defaultConfig from './preact.config'
+
+export default {
+  webpack(config, env, helpers, options) {
+    defaultConfig.webpack(config, env, helpers, options)
+
+    //1. check no file is under /routers or /component/{routers,async} to 
prevent async components
+    // https://github.com/preactjs/preact-cli#route-based-code-splitting
+
+    //2. remove devtools to prevent sourcemaps
+    config.devtool = false
+
+    //3. change assetLoader to load assets inline
+    const loaders = helpers.getLoaders(config)
+    const assetsLoader = loaders.find(lo => 
lo.rule.test.test('something.woff'))
+    if (assetsLoader) {
+      assetsLoader.rule.use = 'base64-inline-loader'
+      assetsLoader.rule.loader = undefined
+    }
+
+    //4. remove critters
+    //critters remove the css bundle from htmlWebpackPlugin.files.css
+    //for now, pushing all the content into the html is enough
+    const crittersWrapper = helpers.getPluginsByName(config, 'Critters')
+    if (crittersWrapper && crittersWrapper.length > 0) {
+      const [{ index }] = crittersWrapper
+      config.plugins.splice(index, 1)
+    }
+
+    //5. remove favicon from src/assets
+
+    //6. remove performance hints since we now that this is going to be big
+    if (config.performance) {
+      config.performance.hints = false
+    }
+
+    //7. template.html should have a favicon and add js/css content
+  }
+}
diff --git a/packages/demobank-ui/remove-link-stylesheet.sh 
b/packages/demobank-ui/remove-link-stylesheet.sh
new file mode 100755
index 000000000..d3376b8e6
--- /dev/null
+++ b/packages/demobank-ui/remove-link-stylesheet.sh
@@ -0,0 +1,8 @@
+# This script has been placed in the public domain.
+
+FILE=$(ls build/bundle.*.css)
+BUNDLE=${FILE#build}
+grep -q '<link href="'$BUNDLE'" rel="stylesheet">' build/index.html || { echo 
bundle $BUNDLE not found in index.html; exit 1; }
+echo -n Removing link from index.html ...
+sed 's_<link href="'$BUNDLE'" rel="stylesheet">__' -i build/index.html
+echo done
diff --git a/packages/demobank-ui/src/.babelrc 
b/packages/demobank-ui/src/.babelrc
new file mode 100644
index 000000000..05f4dcc81
--- /dev/null
+++ b/packages/demobank-ui/src/.babelrc
@@ -0,0 +1,3 @@
+{
+  "presets": ["preact-cli/babel"]
+}
diff --git a/packages/anastasis-webui/src/assets/empty.png 
b/packages/demobank-ui/src/assets/empty.png
similarity index 100%
copy from packages/anastasis-webui/src/assets/empty.png
copy to packages/demobank-ui/src/assets/empty.png
diff --git a/packages/anastasis-webui/src/assets/example/id1.jpg 
b/packages/demobank-ui/src/assets/example/id1.jpg
similarity index 100%
copy from packages/anastasis-webui/src/assets/example/id1.jpg
copy to packages/demobank-ui/src/assets/example/id1.jpg
diff --git a/packages/anastasis-webui/src/assets/favicon.ico 
b/packages/demobank-ui/src/assets/favicon.ico
similarity index 100%
copy from packages/anastasis-webui/src/assets/favicon.ico
copy to packages/demobank-ui/src/assets/favicon.ico
diff --git 
a/packages/anastasis-webui/src/assets/icons/android-chrome-192x192.png 
b/packages/demobank-ui/src/assets/icons/android-chrome-192x192.png
similarity index 100%
copy from packages/anastasis-webui/src/assets/icons/android-chrome-192x192.png
copy to packages/demobank-ui/src/assets/icons/android-chrome-192x192.png
diff --git 
a/packages/anastasis-webui/src/assets/icons/android-chrome-512x512.png 
b/packages/demobank-ui/src/assets/icons/android-chrome-512x512.png
similarity index 100%
copy from packages/anastasis-webui/src/assets/icons/android-chrome-512x512.png
copy to packages/demobank-ui/src/assets/icons/android-chrome-512x512.png
diff --git a/packages/anastasis-webui/src/assets/icons/apple-touch-icon.png 
b/packages/demobank-ui/src/assets/icons/apple-touch-icon.png
similarity index 100%
copy from packages/anastasis-webui/src/assets/icons/apple-touch-icon.png
copy to packages/demobank-ui/src/assets/icons/apple-touch-icon.png
diff --git a/packages/anastasis-webui/src/assets/icons/auth_method/email.svg 
b/packages/demobank-ui/src/assets/icons/auth_method/email.svg
similarity index 100%
copy from packages/anastasis-webui/src/assets/icons/auth_method/email.svg
copy to packages/demobank-ui/src/assets/icons/auth_method/email.svg
diff --git a/packages/anastasis-webui/src/assets/icons/auth_method/postal.svg 
b/packages/demobank-ui/src/assets/icons/auth_method/postal.svg
similarity index 100%
copy from packages/anastasis-webui/src/assets/icons/auth_method/postal.svg
copy to packages/demobank-ui/src/assets/icons/auth_method/postal.svg
diff --git a/packages/anastasis-webui/src/assets/icons/auth_method/question.svg 
b/packages/demobank-ui/src/assets/icons/auth_method/question.svg
similarity index 100%
copy from packages/anastasis-webui/src/assets/icons/auth_method/question.svg
copy to packages/demobank-ui/src/assets/icons/auth_method/question.svg
diff --git a/packages/anastasis-webui/src/assets/icons/auth_method/sms.svg 
b/packages/demobank-ui/src/assets/icons/auth_method/sms.svg
similarity index 100%
copy from packages/anastasis-webui/src/assets/icons/auth_method/sms.svg
copy to packages/demobank-ui/src/assets/icons/auth_method/sms.svg
diff --git a/packages/anastasis-webui/src/assets/icons/auth_method/video.svg 
b/packages/demobank-ui/src/assets/icons/auth_method/video.svg
similarity index 100%
copy from packages/anastasis-webui/src/assets/icons/auth_method/video.svg
copy to packages/demobank-ui/src/assets/icons/auth_method/video.svg
diff --git a/packages/anastasis-webui/src/assets/icons/favicon-16x16.png 
b/packages/demobank-ui/src/assets/icons/favicon-16x16.png
similarity index 100%
copy from packages/anastasis-webui/src/assets/icons/favicon-16x16.png
copy to packages/demobank-ui/src/assets/icons/favicon-16x16.png
diff --git a/packages/anastasis-webui/src/assets/icons/favicon-32x32.png 
b/packages/demobank-ui/src/assets/icons/favicon-32x32.png
similarity index 100%
copy from packages/anastasis-webui/src/assets/icons/favicon-32x32.png
copy to packages/demobank-ui/src/assets/icons/favicon-32x32.png
diff --git a/packages/anastasis-webui/src/assets/icons/languageicon.svg 
b/packages/demobank-ui/src/assets/icons/languageicon.svg
similarity index 100%
copy from packages/anastasis-webui/src/assets/icons/languageicon.svg
copy to packages/demobank-ui/src/assets/icons/languageicon.svg
diff --git a/packages/anastasis-webui/src/assets/icons/mstile-150x150.png 
b/packages/demobank-ui/src/assets/icons/mstile-150x150.png
similarity index 100%
copy from packages/anastasis-webui/src/assets/icons/mstile-150x150.png
copy to packages/demobank-ui/src/assets/icons/mstile-150x150.png
diff --git a/packages/demobank-ui/src/assets/logo-white.svg 
b/packages/demobank-ui/src/assets/logo-white.svg
new file mode 100644
index 000000000..cb1f023c5
--- /dev/null
+++ b/packages/demobank-ui/src/assets/logo-white.svg
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   width="670"
+   height="300"
+   viewBox="0 0 201 90"
+   version="1.1"
+   id="svg8">
+  <g
+     id="logo">
+    <g
+       id="circles"
+       
style="fill:#FFF;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.327943">
+      <path
+         d="m 86.662153,1.1211936 c 15.589697,0 29.129227,9.4011664 
35.961027,23.2018054 h -5.81736 C 110.4866,13.623304 99.349002,6.5180852 
86.662153,6.5180852 c -19.690571,0 -35.652876,17.1120008 -35.652876,38.2205688 
0,10.331797 3.825597,19.704678 10.03957,26.582945 -1.342357,1.120912 
-2.771532,2.127905 -4.275488,3.006754 C 50.071485,66.553412 45.974857,56.15992 
45.974857,44.738654 c 0,-24.089211 18.216325,-43.6174604 40.687296,-43.6174604 
z M 122.51416,65.375898 c -6.86645,13.680134  [...]
+         id="path2350" />
+      <path
+         d="m 64.212372,1.1211936 c 1.052607,0 2.095998,0.042919 
3.128684,0.1270583 C 64.288864,2.8094199 61.427378,4.728606 58.802653,6.9555572 
41.679542,9.7498571 28.559494,25.601563 28.559494,44.738654 c 0,14.264563 
7.29059,26.702023 18.093843,33.268925 -1.593656,0.26719 -3.226966,0.406948 
-4.890748,0.406948 -1.239545,0 -2.46151,-0.07952 -3.663522,-0.229364 C 
29.191129,70.184015 23.525076,58.171633 23.525076,44.738654 23.525076,20.649443 
41.7414,1.1211936 64.212372,1.1211936 Z M 69.62 [...]
+         id="path2352" />
+      <path
+         d="m 41.762589,1.1211936 c 1.064296,0 2.118804,0.044379 
3.162607,0.1302161 -3.046523,1.558961 -5.903162,3.4745139 -8.52358,5.6968133 C 
19.254624,9.7205882 6.1097128,25.583465 6.1097128,44.738654 c 0,21.108568 
15.9624012,38.22057 35.6528762,38.22057 12.599746,0 23.672446,-7.007056 
30.013748,-17.583802 h 5.838515 C 70.748498,79.055727 57.26924,88.356116 
41.762589,88.356116 c -22.470907,0 -40.6871998,-19.52825 -40.6871998,-43.617462 
0,-24.089211 18.2162928,-43.6174604 40.6871998,-4 [...]
+         id="path2354" />
+    </g>
+    <g
+       id="letters"
+       style="fill:#FFF">
+      <path
+         d="m 76.135411,34.409066 h 9.161042 V 29.36588 H 61.857537 v 5.043186 
h 9.161137 v 25.92317 h 5.116737 z"
+         id="path2346" />
+      <path
+         d="m 92.647571,52.856334 h 13.659009 l 2.93009,7.476072 h 5.36461 L 
101.89122,29.144903 H 97.187186 L 84.477089,60.332406 h 5.199533 z m 
11.802109,-4.822276 h -9.944771 l 4.951718,-12.386462 z"
+         id="path2362" />
+      <path
+         d="m 123.80641,29.366084 h -4.58038 v 30.966322 h 20.54728 v 
-4.910253 c -5.32227,0 -10.64463,0 -15.9669,0 z"
+         id="path2356" />
+      <path
+         d="m 166.4722,29.366084 h -21.37564 v 30.966322 h 21.58203 v 
-4.910253 h -16.54771 v -8.27275 h 14.48439 V 42.23925 h -14.48439 v -7.962811 
h 16.34132 z"
+         id="path2360" />
+      <path
+         d="m 191.19035,39.474593 c 0,1.59947 -0.53646,2.87535 
-1.61628,3.818883 -1.07281,0.95124 -2.52409,1.422837 -4.34678,1.422837 h 
-7.44851 V 34.276439 h 7.4073 c 1.9051,0 3.38376,0.435027 4.42939,1.312178 
1.05226,0.870258 1.57488,2.167734 1.57488,3.885976 z m 6.06602,20.857813 
-7.79911,-11.723191 c 1.01771,-0.294794 1.94631,-0.714813 2.78553,-1.260566 
0.83885,-0.545619 1.56122,-1.209263 2.16629,-1.990627 0.60541,-0.781738 
1.07981,-1.681096 1.42369,-2.698345 0.34378,-1.017553 0.5156 [...]
+         id="path2358" />
+    </g>
+  </g>
+</svg>
diff --git a/packages/anastasis-webui/src/assets/logo.jpeg 
b/packages/demobank-ui/src/assets/logo.jpeg
similarity index 100%
copy from packages/anastasis-webui/src/assets/logo.jpeg
copy to packages/demobank-ui/src/assets/logo.jpeg
diff --git a/packages/demobank-ui/src/components/AsyncButton.tsx 
b/packages/demobank-ui/src/components/AsyncButton.tsx
new file mode 100644
index 000000000..0c4305668
--- /dev/null
+++ b/packages/demobank-ui/src/components/AsyncButton.tsx
@@ -0,0 +1,66 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { ComponentChildren, h, VNode } from 'preact';
+import { useLayoutEffect, useRef } from 'preact/hooks';
+// import { LoadingModal } from "../modal";
+import { useAsync } from '../hooks/async';
+// import { Translate } from "../../i18n";
+
+type Props = {
+  children: ComponentChildren;
+  disabled?: boolean;
+  onClick?: () => Promise<void>;
+  grabFocus?: boolean;
+  [rest: string]: any;
+};
+
+export function AsyncButton({
+  onClick,
+  grabFocus,
+  disabled,
+  children,
+  ...rest
+}: Props): VNode {
+  const { isLoading, request } = useAsync(onClick);
+
+  const buttonRef = useRef<HTMLButtonElement>(null);
+  useLayoutEffect(() => {
+    if (grabFocus) 
+      buttonRef.current?.focus();
+    
+  }, [grabFocus]);
+
+  // if (isSlow) {
+  //   return <LoadingModal onCancel={cancel} />;
+  // }
+  if (isLoading) 
+    return <button class="button">Loading...</button>;
+  
+
+  return (
+    <span data-tooltip={rest['data-tooltip']} style={{ marginLeft: 5 }}>
+      <button {...rest} ref={buttonRef} onClick={request} disabled={disabled}>
+        {children}
+      </button>
+    </span>
+  );
+}
diff --git a/packages/demobank-ui/src/components/FileButton.tsx 
b/packages/demobank-ui/src/components/FileButton.tsx
new file mode 100644
index 000000000..dba86ccbf
--- /dev/null
+++ b/packages/demobank-ui/src/components/FileButton.tsx
@@ -0,0 +1,57 @@
+import { h, VNode } from 'preact';
+import { useRef, useState } from 'preact/hooks';
+
+const MAX_IMAGE_UPLOAD_SIZE = 1024 * 1024;
+
+export interface FileTypeContent {
+  content: string;
+  type: string;
+  name: string;
+}
+
+interface Props {
+  label: string;
+  onChange: (v: FileTypeContent | undefined) => void;
+}
+export function FileButton(props: Props): VNode {
+  const fileInputRef = useRef<HTMLInputElement>(null);
+  const [sizeError, setSizeError] = useState(false);
+  return (
+    <div>
+      <button class="button" onClick={(e) => fileInputRef.current?.click()}>
+        <span>{props.label}</span>
+      </button>
+      <input
+        ref={fileInputRef}
+        style={{ display: 'none' }}
+        type="file"
+        onChange={(e) => {
+          const f: FileList | null = e.currentTarget.files;
+          if (!f || f.length != 1) 
+            return props.onChange(undefined);
+          
+          console.log(f);
+          if (f[0].size > MAX_IMAGE_UPLOAD_SIZE) {
+            setSizeError(true);
+            return props.onChange(undefined);
+          }
+          setSizeError(false);
+          return f[0].arrayBuffer().then((b) => {
+            const content = new Uint8Array(b).reduce(
+              (data, byte) => data + String.fromCharCode(byte),
+              '',
+            );
+            return props.onChange({
+              content,
+              name: f[0].name,
+              type: f[0].type,
+            });
+          });
+        }}
+      />
+      {sizeError && (
+        <p class="help is-danger">File should be smaller than 1 MB</p>
+      )}
+    </div>
+  );
+}
diff --git a/packages/demobank-ui/src/components/Notifications.tsx 
b/packages/demobank-ui/src/components/Notifications.tsx
new file mode 100644
index 000000000..09329442a
--- /dev/null
+++ b/packages/demobank-ui/src/components/Notifications.tsx
@@ -0,0 +1,74 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { h, VNode } from 'preact';
+
+export interface Notification {
+  message: string;
+  description?: string | VNode;
+  type: MessageType;
+}
+
+export type MessageType = 'INFO' | 'WARN' | 'ERROR' | 'SUCCESS';
+
+interface Props {
+  notifications: Notification[];
+  removeNotification?: (n: Notification) => void;
+}
+
+function messageStyle(type: MessageType): string {
+  switch (type) {
+  case 'INFO':
+    return 'message is-info';
+  case 'WARN':
+    return 'message is-warning';
+  case 'ERROR':
+    return 'message is-danger';
+  case 'SUCCESS':
+    return 'message is-success';
+  default:
+    return 'message';
+  }
+}
+
+export function Notifications({
+  notifications,
+  removeNotification,
+}: Props): VNode {
+  return (
+    <div class="block">
+      {notifications.map((n, i) => (
+        <article key={i} class={messageStyle(n.type)}>
+          <div class="message-header">
+            <p>{n.message}</p>
+            {removeNotification && (
+              <button
+                class="delete"
+                onClick={() => removeNotification && removeNotification(n)}
+              />
+            )}
+          </div>
+          {n.description && <div class="message-body">{n.description}</div>}
+        </article>
+      ))}
+    </div>
+  );
+}
diff --git a/packages/demobank-ui/src/components/QR.tsx 
b/packages/demobank-ui/src/components/QR.tsx
new file mode 100644
index 000000000..ee5b73c69
--- /dev/null
+++ b/packages/demobank-ui/src/components/QR.tsx
@@ -0,0 +1,48 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+import { h, VNode } from 'preact';
+import { useEffect, useRef } from 'preact/hooks';
+import qrcode from 'qrcode-generator';
+
+export function QR({ text }: { text: string }): VNode {
+  const divRef = useRef<HTMLDivElement>(null);
+  useEffect(() => {
+    const qr = qrcode(0, 'L');
+    qr.addData(text);
+    qr.make();
+    if (divRef.current)
+      divRef.current.innerHTML = qr.createSvgTag({
+        scalable: true,
+      });
+  });
+
+  return (
+    <div
+      style={{
+        width: '100%',
+        display: 'flex',
+        flexDirection: 'column',
+        alignItems: 'left',
+      }}
+    >
+      <div
+        style={{ width: '50%', minWidth: 200, maxWidth: 300 }}
+        ref={divRef}
+      />
+    </div>
+  );
+}
diff --git a/packages/demobank-ui/src/components/app.tsx 
b/packages/demobank-ui/src/components/app.tsx
new file mode 100644
index 000000000..5338c548e
--- /dev/null
+++ b/packages/demobank-ui/src/components/app.tsx
@@ -0,0 +1,14 @@
+import { FunctionalComponent, h } from 'preact';
+import { TranslationProvider } from '../context/translation';
+import { BankHome } from '../pages/home/index';
+import { Menu } from './menu';
+
+const App: FunctionalComponent = () => {
+  return (
+    <TranslationProvider>
+      <BankHome />
+    </TranslationProvider>
+  );
+};
+
+export default App;
diff --git a/packages/demobank-ui/src/components/fields/DateInput.tsx 
b/packages/demobank-ui/src/components/fields/DateInput.tsx
new file mode 100644
index 000000000..06ec4b6a7
--- /dev/null
+++ b/packages/demobank-ui/src/components/fields/DateInput.tsx
@@ -0,0 +1,90 @@
+import { format, subYears } from 'date-fns';
+import { h, VNode } from 'preact';
+import { useLayoutEffect, useRef, useState } from 'preact/hooks';
+import { DatePicker } from '../picker/DatePicker';
+
+export interface DateInputProps {
+  label: string;
+  grabFocus?: boolean;
+  tooltip?: string;
+  error?: string;
+  years?: Array<number>;
+  onConfirm?: () => void;
+  bind: [string, (x: string) => void];
+}
+
+export function DateInput(props: DateInputProps): VNode {
+  const inputRef = useRef<HTMLInputElement>(null);
+  useLayoutEffect(() => {
+    if (props.grabFocus) 
+      inputRef.current?.focus();
+    
+  }, [props.grabFocus]);
+  const [opened, setOpened] = useState(false);
+
+  const value = props.bind[0] || '';
+  const [dirty, setDirty] = useState(false);
+  const showError = dirty && props.error;
+
+  const calendar = subYears(new Date(), 30);
+
+  return (
+    <div class="field">
+      <label class="label">
+        {props.label}
+        {props.tooltip && (
+          <span class="icon has-tooltip-right" data-tooltip={props.tooltip}>
+            <i class="mdi mdi-information" />
+          </span>
+        )}
+      </label>
+      <div class="control">
+        <div class="field has-addons">
+          <p class="control">
+            <input
+              type="text"
+              class={showError ? 'input is-danger' : 'input'}
+              value={value}
+              onKeyPress={(e) => {
+                if (e.key === 'Enter' && props.onConfirm) 
+                  props.onConfirm()
+                
+              }}
+              onInput={(e) => {
+                const text = e.currentTarget.value;
+                setDirty(true);
+                props.bind[1](text);
+              }}
+              ref={inputRef}
+            />
+          </p>
+          <p class="control">
+            <a
+              class="button"
+              onClick={() => {
+                setOpened(true);
+              }}
+            >
+              <span class="icon">
+                <i class="mdi mdi-calendar" />
+              </span>
+            </a>
+          </p>
+        </div>
+      </div>
+      <p class="help">Using the format yyyy-mm-dd</p>
+      {showError && <p class="help is-danger">{props.error}</p>}
+      <DatePicker
+        opened={opened}
+        initialDate={calendar}
+        years={props.years}
+        closeFunction={() => setOpened(false)}
+        dateReceiver={(d) => {
+          setDirty(true);
+          const v = format(d, 'yyyy-MM-dd');
+          props.bind[1](v);
+        }}
+      />
+    </div>
+  );
+}
diff --git a/packages/demobank-ui/src/components/fields/EmailInput.tsx 
b/packages/demobank-ui/src/components/fields/EmailInput.tsx
new file mode 100644
index 000000000..8b64264ed
--- /dev/null
+++ b/packages/demobank-ui/src/components/fields/EmailInput.tsx
@@ -0,0 +1,57 @@
+import { h, VNode } from 'preact';
+import { useLayoutEffect, useRef, useState } from 'preact/hooks';
+
+export interface TextInputProps {
+  label: string;
+  grabFocus?: boolean;
+  error?: string;
+  placeholder?: string;
+  tooltip?: string;
+  onConfirm?: () => void;
+  bind: [string, (x: string) => void];
+}
+
+export function EmailInput(props: TextInputProps): VNode {
+  const inputRef = useRef<HTMLInputElement>(null);
+  useLayoutEffect(() => {
+    if (props.grabFocus) 
+      inputRef.current?.focus();
+    
+  }, [props.grabFocus]);
+  const value = props.bind[0];
+  const [dirty, setDirty] = useState(false);
+  const showError = dirty && props.error;
+  return (
+    <div class="field">
+      <label class="label">
+        {props.label}
+        {props.tooltip && (
+          <span class="icon has-tooltip-right" data-tooltip={props.tooltip}>
+            <i class="mdi mdi-information" />
+          </span>
+        )}
+      </label>
+      <div class="control has-icons-right">
+        <input
+          value={value}
+          required
+          placeholder={props.placeholder}
+          type="email"
+          class={showError ? 'input is-danger' : 'input'}
+          onKeyPress={(e) => {
+            if (e.key === 'Enter' && props.onConfirm) 
+              props.onConfirm()
+            
+          }}
+          onInput={(e) => {
+            setDirty(true);
+            props.bind[1]((e.target as HTMLInputElement).value);
+          }}
+          ref={inputRef}
+          style={{ display: 'block' }}
+        />
+      </div>
+      {showError && <p class="help is-danger">{props.error}</p>}
+    </div>
+  );
+}
diff --git a/packages/demobank-ui/src/components/fields/FileInput.tsx 
b/packages/demobank-ui/src/components/fields/FileInput.tsx
new file mode 100644
index 000000000..17413b907
--- /dev/null
+++ b/packages/demobank-ui/src/components/fields/FileInput.tsx
@@ -0,0 +1,104 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { h, VNode } from 'preact';
+import { useLayoutEffect, useRef, useState } from 'preact/hooks';
+
+const MAX_IMAGE_UPLOAD_SIZE = 1024 * 1024;
+
+export interface FileTypeContent {
+  content: string;
+  type: string;
+  name: string;
+}
+
+export interface FileInputProps {
+  label: string;
+  grabFocus?: boolean;
+  disabled?: boolean;
+  error?: string;
+  placeholder?: string;
+  tooltip?: string;
+  onChange: (v: FileTypeContent | undefined) => void;
+}
+
+export function FileInput(props: FileInputProps): VNode {
+  const inputRef = useRef<HTMLInputElement>(null);
+  useLayoutEffect(() => {
+    if (props.grabFocus) 
+      inputRef.current?.focus();
+    
+  }, [props.grabFocus]);
+
+  const fileInputRef = useRef<HTMLInputElement>(null);
+  const [sizeError, setSizeError] = useState(false);
+  return (
+    <div class="field">
+      <label class="label">
+        <a class="button" onClick={(e) => fileInputRef.current?.click()}>
+          <div class="icon is-small ">
+            <i class="mdi mdi-folder" />
+          </div>
+          <span>
+            {props.label}
+          </span>
+        </a>
+        {props.tooltip && (
+          <span class="icon has-tooltip-right" data-tooltip={props.tooltip}>
+            <i class="mdi mdi-information" />
+          </span>
+        )}
+      </label>
+      <div class="control">
+        <input
+          ref={fileInputRef}
+          style={{ display: 'none' }}
+          type="file"
+          // name={String(name)}
+          onChange={(e) => {
+            const f: FileList | null = e.currentTarget.files;
+            if (!f || f.length != 1) 
+              return props.onChange(undefined);
+            
+            console.log(f)
+            if (f[0].size > MAX_IMAGE_UPLOAD_SIZE) {
+              setSizeError(true);
+              return props.onChange(undefined);
+            }
+            setSizeError(false);
+            return f[0].arrayBuffer().then((b) => {
+              const b64 = btoa(
+                new Uint8Array(b).reduce(
+                  (data, byte) => data + String.fromCharCode(byte),
+                  '',
+                ),
+              );
+              return props.onChange({content: 
`data:${f[0].type};base64,${b64}`, name: f[0].name, type: f[0].type});
+            });
+          }}
+        />
+        {props.error && <p class="help is-danger">{props.error}</p>}
+        {sizeError && (
+          <p class="help is-danger">File should be smaller than 1 MB</p>
+        )}
+      </div>
+    </div>
+  );
+}
diff --git a/packages/demobank-ui/src/components/fields/ImageInput.tsx 
b/packages/demobank-ui/src/components/fields/ImageInput.tsx
new file mode 100644
index 000000000..98457af21
--- /dev/null
+++ b/packages/demobank-ui/src/components/fields/ImageInput.tsx
@@ -0,0 +1,93 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { h, VNode } from 'preact';
+import { useLayoutEffect, useRef, useState } from 'preact/hooks';
+import emptyImage from '../../assets/empty.png';
+import { TextInputProps } from './TextInput';
+
+const MAX_IMAGE_UPLOAD_SIZE = 1024 * 1024;
+
+export function ImageInput(props: TextInputProps): VNode {
+  const inputRef = useRef<HTMLInputElement>(null);
+  useLayoutEffect(() => {
+    if (props.grabFocus) 
+      inputRef.current?.focus();
+    
+  }, [props.grabFocus]);
+
+  const value = props.bind[0];
+  // const [dirty, setDirty] = useState(false)
+  const image = useRef<HTMLInputElement>(null);
+  const [sizeError, setSizeError] = useState(false);
+  function onChange(v: string): void {
+    // setDirty(true);
+    props.bind[1](v);
+  }
+  return (
+    <div class="field">
+      <label class="label">
+        {props.label}
+        {props.tooltip && (
+          <span class="icon has-tooltip-right" data-tooltip={props.tooltip}>
+            <i class="mdi mdi-information" />
+          </span>
+        )}
+      </label>
+      <div class="control">
+        <img
+          src={!value ? emptyImage : value}
+          style={{ width: 200, height: 200 }}
+          onClick={() => image.current?.click()}
+        />
+        <input
+          ref={image}
+          style={{ display: 'none' }}
+          type="file"
+          name={String(name)}
+          onChange={(e) => {
+            const f: FileList | null = e.currentTarget.files;
+            if (!f || f.length != 1) 
+              return onChange(emptyImage);
+            
+            if (f[0].size > MAX_IMAGE_UPLOAD_SIZE) {
+              setSizeError(true);
+              return onChange(emptyImage);
+            }
+            setSizeError(false);
+            return f[0].arrayBuffer().then((b) => {
+              const b64 = btoa(
+                new Uint8Array(b).reduce(
+                  (data, byte) => data + String.fromCharCode(byte),
+                  '',
+                ),
+              );
+              return onChange(`data:${f[0].type};base64,${b64}` as any);
+            });
+          }}
+        />
+        {props.error && <p class="help is-danger">{props.error}</p>}
+        {sizeError && (
+          <p class="help is-danger">Image should be smaller than 1 MB</p>
+        )}
+      </div>
+    </div>
+  );
+}
diff --git a/packages/demobank-ui/src/components/fields/NumberInput.tsx 
b/packages/demobank-ui/src/components/fields/NumberInput.tsx
new file mode 100644
index 000000000..881c61c57
--- /dev/null
+++ b/packages/demobank-ui/src/components/fields/NumberInput.tsx
@@ -0,0 +1,56 @@
+import { h, VNode } from 'preact';
+import { useLayoutEffect, useRef, useState } from 'preact/hooks';
+
+export interface TextInputProps {
+  label: string;
+  grabFocus?: boolean;
+  error?: string;
+  placeholder?: string;
+  tooltip?: string;
+  onConfirm?: () => void;
+  bind: [string, (x: string) => void];
+}
+
+export function PhoneNumberInput(props: TextInputProps): VNode {
+  const inputRef = useRef<HTMLInputElement>(null);
+  useLayoutEffect(() => {
+    if (props.grabFocus) 
+      inputRef.current?.focus();
+    
+  }, [props.grabFocus]);
+  const value = props.bind[0];
+  const [dirty, setDirty] = useState(false);
+  const showError = dirty && props.error;
+  return (
+    <div class="field">
+      <label class="label">
+        {props.label}
+        {props.tooltip && (
+          <span class="icon has-tooltip-right" data-tooltip={props.tooltip}>
+            <i class="mdi mdi-information" />
+          </span>
+        )}
+      </label>
+      <div class="control has-icons-right">
+        <input
+          value={value}
+          type="tel"
+          placeholder={props.placeholder}
+          class={showError ? 'input is-danger' : 'input'}
+          onKeyPress={(e) => {
+            if (e.key === 'Enter' && props.onConfirm) 
+              props.onConfirm()
+            
+          }}
+          onInput={(e) => {
+            setDirty(true);
+            props.bind[1]((e.target as HTMLInputElement).value);
+          }}
+          ref={inputRef}
+          style={{ display: 'block' }}
+        />
+      </div>
+      {showError && <p class="help is-danger">{props.error}</p>}
+    </div>
+  );
+}
diff --git a/packages/demobank-ui/src/components/fields/TextInput.tsx 
b/packages/demobank-ui/src/components/fields/TextInput.tsx
new file mode 100644
index 000000000..5cc9f32ad
--- /dev/null
+++ b/packages/demobank-ui/src/components/fields/TextInput.tsx
@@ -0,0 +1,68 @@
+import { h, VNode } from 'preact';
+import { useLayoutEffect, useRef, useState } from 'preact/hooks';
+
+export interface TextInputProps {
+  inputType?: 'text' | 'number' | 'multiline' | 'password';
+  label: string;
+  grabFocus?: boolean;
+  disabled?: boolean;
+  error?: string;
+  placeholder?: string;
+  tooltip?: string;
+  onConfirm?: () => void;
+  bind: [string, (x: string) => void];
+}
+
+const TextInputType = function ({ inputType, grabFocus, ...rest }: any): VNode 
{
+  const inputRef = useRef<HTMLInputElement>(null);
+  useLayoutEffect(() => {
+    if (grabFocus) 
+      inputRef.current?.focus();
+    
+  }, [grabFocus]);
+
+  return inputType === 'multiline' ? (
+    <textarea {...rest} rows={5} ref={inputRef} style={{ height: 'unset' }} />
+  ) : (
+    <input {...rest} type={inputType} ref={inputRef} />
+  );
+};
+
+export function TextInput(props: TextInputProps): VNode {
+  const value = props.bind[0];
+  const [dirty, setDirty] = useState(false);
+  const showError = dirty && props.error;
+  return (
+    <div class="field">
+      <label class="label">
+        {props.label}
+        {props.tooltip && (
+          <span class="icon has-tooltip-right" data-tooltip={props.tooltip}>
+            <i class="mdi mdi-information" />
+          </span>
+        )}
+      </label>
+      <div class="control has-icons-right">
+        <TextInputType
+          inputType={props.inputType}
+          value={value}
+          grabFocus={props.grabFocus}
+          disabled={props.disabled}
+          placeholder={props.placeholder}
+          class={showError ? 'input is-danger' : 'input'}
+          onKeyPress={(e: any) => {
+            if (e.key === 'Enter' && props.onConfirm) 
+              props.onConfirm();
+            
+          }}
+          onInput={(e: any) => {
+            setDirty(true);
+            props.bind[1]((e.target as HTMLInputElement).value);
+          }}
+          style={{ display: 'block' }}
+        />
+      </div>
+      {showError && <p class="help is-danger">{props.error}</p>}
+    </div>
+  );
+}
diff --git a/packages/demobank-ui/src/components/menu/LangSelector.tsx 
b/packages/demobank-ui/src/components/menu/LangSelector.tsx
new file mode 100644
index 000000000..221237a5b
--- /dev/null
+++ b/packages/demobank-ui/src/components/menu/LangSelector.tsx
@@ -0,0 +1,101 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { h, VNode, Fragment } from 'preact';
+import { useCallback, useEffect, useState } from 'preact/hooks';
+import langIcon from '../../assets/icons/languageicon.svg';
+import { useTranslationContext } from '../../context/translation';
+import { strings as messages } from '../../i18n/strings';
+
+type LangsNames = {
+  [P in keyof typeof messages]: string;
+};
+
+const names: LangsNames = {
+  es: 'Español [es]',
+  en: 'English [en]',
+  fr: 'Français [fr]',
+  de: 'Deutsch [de]',
+  sv: 'Svenska [sv]',
+  it: 'Italiano [it]',
+};
+
+function getLangName(s: keyof LangsNames | string): string {
+  if (names[s]) return names[s];
+  return String(s);
+}
+
+// FIXME: explain "like py".
+export function LangSelectorLikePy(): VNode {
+  const [updatingLang, setUpdatingLang] = useState(false);
+  const { lang, changeLanguage } = useTranslationContext();
+  const [hidden, setHidden] = useState(true)
+  useEffect(() => {
+    function bodyKeyPress(event:KeyboardEvent) {
+      if (event.code === 'Escape') 
+        setHidden(true);
+      
+    }
+    function bodyOnClick(event:Event) {
+      setHidden(true);
+    }
+    document.body.addEventListener('click', bodyOnClick)
+    document.body.addEventListener('keydown', bodyKeyPress as any)
+    return () => {
+      document.body.removeEventListener('keydown', bodyKeyPress as any)
+      document.body.removeEventListener('click', bodyOnClick)
+    }
+  },[])
+  return (
+    <Fragment>
+      <button name="language" onClick={(ev) => {
+        setHidden(h => !h);
+        ev.stopPropagation();
+      }}>
+        {getLangName(lang)}
+      </button>
+      <div id="lang" class={hidden ? 'hide' : ''}>
+        <div style="position: relative; overflow: visible;">
+          <div
+            class="nav"
+            style="position: absolute; max-height: 60vh; overflow-y: scroll">
+            {Object.keys(messages)
+              .filter((l) => l !== lang)
+              .map((l) => (
+                <a
+                  key={l}
+                  href="#"
+                  class="navbtn langbtn"
+                  value={l}
+                  onClick={() => {
+                    changeLanguage(l);
+                    setUpdatingLang(false);
+                  }}>
+                  {getLangName(l)}
+                </a>
+              ))}
+            <br />
+          </div>
+        </div>
+      </div>
+    </Fragment>
+  );
+}
diff --git a/packages/demobank-ui/src/components/menu/NavigationBar.tsx 
b/packages/demobank-ui/src/components/menu/NavigationBar.tsx
new file mode 100644
index 000000000..9e540213d
--- /dev/null
+++ b/packages/demobank-ui/src/components/menu/NavigationBar.tsx
@@ -0,0 +1,53 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { h, VNode } from 'preact';
+import logo from '../../assets/logo.jpeg';
+import { LangSelectorLikePy as LangSelector } from './LangSelector';
+
+interface Props {
+  onMobileMenu: () => void;
+  title: string;
+}
+
+export function NavigationBar({ onMobileMenu, title }: Props): VNode {
+  return (
+    <nav
+      class="navbar is-fixed-top"
+      role="navigation"
+      aria-label="main navigation"
+    >
+      <div class="navbar-brand">
+        <span class="navbar-item" style={{ fontSize: 24, fontWeight: 900 }}>
+          {title}
+        </span>
+      </div>
+
+      <div class="navbar-menu ">
+        <div class="navbar-end">
+          <div class="navbar-item" style={{ paddingTop: 4, paddingBottom: 4 }}>
+            {/* <LangSelector /> */}
+          </div>
+        </div>
+      </div>
+    </nav>
+  );
+}
diff --git a/packages/demobank-ui/src/components/menu/SideBar.tsx 
b/packages/demobank-ui/src/components/menu/SideBar.tsx
new file mode 100644
index 000000000..7f9981a1c
--- /dev/null
+++ b/packages/demobank-ui/src/components/menu/SideBar.tsx
@@ -0,0 +1,73 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { h, VNode } from 'preact';
+import { Translate } from '../../i18n';
+
+interface Props {
+  mobile?: boolean;
+}
+
+export function Sidebar({ mobile }: Props): VNode {
+  // const config = useConfigContext();
+  const config = { version: 'none' };
+  // FIXME: add replacement for __VERSION__ with the current version
+  const process = { env: { __VERSION__: '0.0.0' } };
+
+  return (
+    <aside class="aside is-placed-left is-expanded">
+      <div class="aside-tools">
+        <div class="aside-tools-label">
+          <div>
+            <b>euFin bank</b>
+          </div>
+          <div
+            class="is-size-7 has-text-right"
+            style={{ lineHeight: 0, marginTop: -10 }}
+          >
+            Version {process.env.__VERSION__} ({config.version})
+          </div>
+        </div>
+      </div>
+      <div class="menu is-menu-main">
+        <p class="menu-label">
+          <Translate>Bank menu</Translate>
+        </p>
+        <ul class="menu-list">
+          <li>
+            <div class="ml-4">
+              <span class="menu-item-label">
+                <Translate>Select option1</Translate>
+              </span>
+            </div>
+          </li>
+          <li>
+            <div class="ml-4">
+              <span class="menu-item-label">
+                <Translate>Select option2</Translate>
+              </span>
+            </div>
+          </li>
+        </ul>
+      </div>
+    </aside>
+  );
+}
diff --git a/packages/demobank-ui/src/components/menu/index.tsx 
b/packages/demobank-ui/src/components/menu/index.tsx
new file mode 100644
index 000000000..07e1c5265
--- /dev/null
+++ b/packages/demobank-ui/src/components/menu/index.tsx
@@ -0,0 +1,135 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+import { ComponentChildren, Fragment, h, VNode } from 'preact';
+import Match from 'preact-router/match';
+import { useEffect, useState } from 'preact/hooks';
+import { NavigationBar } from './NavigationBar';
+import { Sidebar } from './SideBar';
+
+interface MenuProps {
+  title: string;
+}
+
+function WithTitle({
+  title,
+  children,
+}: {
+  title: string;
+  children: ComponentChildren;
+}): VNode {
+  useEffect(() => {
+    document.title = `${title}`;
+  }, [title]);
+  return <Fragment>{children}</Fragment>;
+}
+
+export function Menu({ title }: MenuProps): VNode {
+  const [mobileOpen, setMobileOpen] = useState(false);
+
+  return (
+    <Match>
+      {({ path }: { path: string }) => {
+        const titleWithSubtitle = title; // title ? title : (!admin ? 
getInstanceTitle(path, instance) : getAdminTitle(path, instance))
+        return (
+          <WithTitle title={titleWithSubtitle}>
+            <div
+              class={mobileOpen ? 'has-aside-mobile-expanded' : ''}
+              onClick={() => setMobileOpen(false)}
+            >
+              <NavigationBar
+                onMobileMenu={() => setMobileOpen(!mobileOpen)}
+                title={titleWithSubtitle}
+              />
+
+              <Sidebar mobile={mobileOpen} />
+            </div>
+          </WithTitle>
+        );
+      }}
+    </Match>
+  );
+}
+
+interface NotYetReadyAppMenuProps {
+  title: string;
+  onLogout?: () => void;
+}
+
+interface NotifProps {
+  notification?: Notification;
+}
+export function NotificationCard({
+  notification: n,
+}: NotifProps): VNode | null {
+  if (!n) return null;
+  return (
+    <div class="notification">
+      <div class="columns is-vcentered">
+        <div class="column is-12">
+          <article
+            class={
+              n.type === 'ERROR'
+                ? 'message is-danger'
+                : n.type === 'WARN'
+                  ? 'message is-warning'
+                  : 'message is-info'
+            }
+          >
+            <div class="message-header">
+              <p>{n.message}</p>
+            </div>
+            {n.description && <div class="message-body">{n.description}</div>}
+          </article>
+        </div>
+      </div>
+    </div>
+  );
+}
+
+export function NotYetReadyAppMenu({
+  onLogout,
+  title,
+}: NotYetReadyAppMenuProps): VNode {
+  const [mobileOpen, setMobileOpen] = useState(false);
+
+  useEffect(() => {
+    document.title = `Taler Backoffice: ${title}`;
+  }, [title]);
+
+  return (
+    <div
+      class="has-aside-mobile-expanded"
+      // class={mobileOpen ? "has-aside-mobile-expanded" : ""}
+      onClick={() => setMobileOpen(false)}
+    >
+      <NavigationBar
+        onMobileMenu={() => setMobileOpen(!mobileOpen)}
+        title={title}
+      />
+      {onLogout && <Sidebar mobile={mobileOpen} />}
+    </div>
+  );
+}
+
+export interface Notification {
+  message: string;
+  description?: string | VNode;
+  type: MessageType;
+}
+
+export type ValueOrFunction<T> = T | ((p: T) => T);
+export type MessageType = 'INFO' | 'WARN' | 'ERROR' | 'SUCCESS';
diff --git a/packages/demobank-ui/src/components/picker/DatePicker.tsx 
b/packages/demobank-ui/src/components/picker/DatePicker.tsx
new file mode 100644
index 000000000..94dbc9458
--- /dev/null
+++ b/packages/demobank-ui/src/components/picker/DatePicker.tsx
@@ -0,0 +1,356 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { h, Component } from 'preact';
+
+interface Props {
+  closeFunction?: () => void;
+  dateReceiver?: (d: Date) => void;
+  initialDate?: Date;
+  years?: Array<number>;
+  opened?: boolean;
+}
+interface State {
+  displayedMonth: number;
+  displayedYear: number;
+  selectYearMode: boolean;
+  currentDate: Date;
+}
+const now = new Date();
+
+const monthArrShortFull = [
+  'January',
+  'February',
+  'March',
+  'April',
+  'May',
+  'June',
+  'July',
+  'August',
+  'September',
+  'October',
+  'November',
+  'December',
+];
+
+const monthArrShort = [
+  'Jan',
+  'Feb',
+  'Mar',
+  'Apr',
+  'May',
+  'Jun',
+  'Jul',
+  'Aug',
+  'Sep',
+  'Oct',
+  'Nov',
+  'Dec',
+];
+
+const dayArr = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
+
+const yearArr: number[] = [];
+
+// inspired by https://codepen.io/m4r1vs/pen/MOOxyE
+export class DatePicker extends Component<Props, State> {
+  closeDatePicker() {
+    this.props.closeFunction && this.props.closeFunction(); // Function gets 
passed by parent
+  }
+
+  /**
+   * Gets fired when a day gets clicked.
+   * @param {object} e The event thrown by the <span /> element clicked
+   */
+  dayClicked(e: any) {
+    const element = e.target; // the actual element clicked
+
+    if (element.innerHTML === '') return false; // don't continue if <span /> 
empty
+
+    // get date from clicked element (gets attached when rendered)
+    const date = new Date(element.getAttribute('data-value'));
+
+    // update the state
+    this.setState({ currentDate: date });
+    this.passDateToParent(date);
+  }
+
+  /**
+   * returns days in month as array
+   * @param {number} month the month to display
+   * @param {number} year the year to display
+   */
+  getDaysByMonth(month: number, year: number) {
+    const calendar = [];
+
+    const date = new Date(year, month, 1); // month to display
+
+    const firstDay = new Date(year, month, 1).getDay(); // first weekday of 
month
+    const lastDate = new Date(year, month + 1, 0).getDate(); // last date of 
month
+
+    let day: number | null = 0;
+
+    // the calendar is 7*6 fields big, so 42 loops
+    for (let i = 0; i < 42; i++) {
+      if (i >= firstDay && day !== null) day = day + 1;
+      if (day !== null && day > lastDate) day = null;
+
+      // append the calendar Array
+      calendar.push({
+        day: day === 0 || day === null ? null : day, // null or number
+        date: day === 0 || day === null ? null : new Date(year, month, day), 
// null or Date()
+        today:
+          day === now.getDate() &&
+          month === now.getMonth() &&
+          year === now.getFullYear(), // boolean
+      });
+    }
+
+    return calendar;
+  }
+
+  /**
+   * Display previous month by updating state
+   */
+  displayPrevMonth() {
+    if (this.state.displayedMonth <= 0) 
+      this.setState({
+        displayedMonth: 11,
+        displayedYear: this.state.displayedYear - 1,
+      });
+    else 
+      this.setState({
+        displayedMonth: this.state.displayedMonth - 1,
+      });
+    
+  }
+
+  /**
+   * Display next month by updating state
+   */
+  displayNextMonth() {
+    if (this.state.displayedMonth >= 11) 
+      this.setState({
+        displayedMonth: 0,
+        displayedYear: this.state.displayedYear + 1,
+      });
+    else 
+      this.setState({
+        displayedMonth: this.state.displayedMonth + 1,
+      });
+    
+  }
+
+  /**
+   * Display the selected month (gets fired when clicking on the date string)
+   */
+  displaySelectedMonth() {
+    if (this.state.selectYearMode) 
+      this.toggleYearSelector();
+    else {
+      if (!this.state.currentDate) return false;
+      this.setState({
+        displayedMonth: this.state.currentDate.getMonth(),
+        displayedYear: this.state.currentDate.getFullYear(),
+      });
+    }
+  }
+
+  toggleYearSelector() {
+    this.setState({ selectYearMode: !this.state.selectYearMode });
+  }
+
+  changeDisplayedYear(e: any) {
+    const element = e.target;
+    this.toggleYearSelector();
+    this.setState({
+      displayedYear: parseInt(element.innerHTML, 10),
+      displayedMonth: 0,
+    });
+  }
+
+  /**
+   * Pass the selected date to parent when 'OK' is clicked
+   */
+  passSavedDateDateToParent() {
+    this.passDateToParent(this.state.currentDate);
+  }
+  passDateToParent(date: Date) {
+    if (typeof this.props.dateReceiver === 'function')
+      this.props.dateReceiver(date);
+    this.closeDatePicker();
+  }
+
+  componentDidUpdate() {
+    // if (this.state.selectYearMode) {
+    //   document.getElementsByClassName('selected')[0].scrollIntoView(); // 
works in every browser incl. IE, replace with scrollIntoViewIfNeeded when 
browsers support it
+    // }
+  }
+
+  constructor(props: any) {
+    super(props);
+
+    this.closeDatePicker = this.closeDatePicker.bind(this);
+    this.dayClicked = this.dayClicked.bind(this);
+    this.displayNextMonth = this.displayNextMonth.bind(this);
+    this.displayPrevMonth = this.displayPrevMonth.bind(this);
+    this.getDaysByMonth = this.getDaysByMonth.bind(this);
+    this.changeDisplayedYear = this.changeDisplayedYear.bind(this);
+    this.passDateToParent = this.passDateToParent.bind(this);
+    this.toggleYearSelector = this.toggleYearSelector.bind(this);
+    this.displaySelectedMonth = this.displaySelectedMonth.bind(this);
+
+    const initial = props.initialDate || now;
+
+    this.state = {
+      currentDate: initial,
+      displayedMonth: initial.getMonth(),
+      displayedYear: initial.getFullYear(),
+      selectYearMode: false,
+    };
+  }
+
+  render() {
+    const {
+      currentDate,
+      displayedMonth,
+      displayedYear,
+      selectYearMode,
+    } = this.state;
+
+    return (
+      <div>
+        <div class={`datePicker ${this.props.opened && 'datePicker--opened'}`}>
+          <div class="datePicker--titles">
+            <h3
+              style={{
+                color: selectYearMode
+                  ? 'rgba(255,255,255,.87)'
+                  : 'rgba(255,255,255,.57)',
+              }}
+              onClick={this.toggleYearSelector}
+            >
+              {currentDate.getFullYear()}
+            </h3>
+            <h2
+              style={{
+                color: !selectYearMode
+                  ? 'rgba(255,255,255,.87)'
+                  : 'rgba(255,255,255,.57)',
+              }}
+              onClick={this.displaySelectedMonth}
+            >
+              {dayArr[currentDate.getDay()]},{' '}
+              {monthArrShort[currentDate.getMonth()]} {currentDate.getDate()}
+            </h2>
+          </div>
+
+          {!selectYearMode && (
+            <nav>
+              <span onClick={this.displayPrevMonth} class="icon">
+                <i
+                  style={{ transform: 'rotate(180deg)' }}
+                  class="mdi mdi-forward"
+                />
+              </span>
+              <h4>
+                {monthArrShortFull[displayedMonth]} {displayedYear}
+              </h4>
+              <span onClick={this.displayNextMonth} class="icon">
+                <i class="mdi mdi-forward" />
+              </span>
+            </nav>
+          )}
+
+          <div class="datePicker--scroll">
+            {!selectYearMode && (
+              <div class="datePicker--calendar">
+                <div class="datePicker--dayNames">
+                  {['S', 'M', 'T', 'W', 'T', 'F', 'S'].map((day, i) => (
+                    <span key={i}>{day}</span>
+                  ))}
+                </div>
+
+                <div onClick={this.dayClicked} class="datePicker--days">
+                  {/*
+                  Loop through the calendar object returned by 
getDaysByMonth().
+                */}
+
+                  {this.getDaysByMonth(
+                    this.state.displayedMonth,
+                    this.state.displayedYear,
+                  ).map((day) => {
+                    let selected = false;
+
+                    if (currentDate && day.date)
+                      selected =
+                        currentDate.toLocaleDateString() ===
+                        day.date.toLocaleDateString();
+
+                    return (
+                      <span
+                        key={day.day}
+                        class={
+                          (day.today ? 'datePicker--today ' : '') +
+                          (selected ? 'datePicker--selected' : '')
+                        }
+                        disabled={!day.date}
+                        data-value={day.date}
+                      >
+                        {day.day}
+                      </span>
+                    );
+                  })}
+                </div>
+              </div>
+            )}
+
+            {selectYearMode && (
+              <div class="datePicker--selectYear">
+                {(this.props.years || yearArr).map((year) => (
+                  <span
+                    key={year}
+                    class={year === displayedYear ? 'selected' : ''}
+                    onClick={this.changeDisplayedYear}
+                  >
+                    {year}
+                  </span>
+                ))}
+              </div>
+            )}
+          </div>
+        </div>
+
+        <div
+          class="datePicker--background"
+          onClick={this.closeDatePicker}
+          style={{
+            display: this.props.opened ? 'block' : 'none',
+          }}
+        />
+      </div>
+    );
+  }
+}
+
+for (let i = 2010; i <= now.getFullYear() + 10; i++) 
+  yearArr.push(i);
+
diff --git 
a/packages/demobank-ui/src/components/picker/DurationPicker.stories.tsx 
b/packages/demobank-ui/src/components/picker/DurationPicker.stories.tsx
new file mode 100644
index 000000000..5e9930522
--- /dev/null
+++ b/packages/demobank-ui/src/components/picker/DurationPicker.stories.tsx
@@ -0,0 +1,55 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { h, FunctionalComponent } from 'preact';
+import { useState } from 'preact/hooks';
+import { DurationPicker as TestedComponent } from './DurationPicker';
+
+export default {
+  title: 'Components/Picker/Duration',
+  component: TestedComponent,
+  argTypes: {
+    onCreate: { action: 'onCreate' },
+    goBack: { action: 'goBack' },
+  },
+};
+
+function createExample<Props>(
+  Component: FunctionalComponent<Props>,
+  props: Partial<Props>,
+) {
+  const r = (args: any) => <Component {...args} />;
+  r.args = props;
+  return r;
+}
+
+export const Example = createExample(TestedComponent, {
+  days: true,
+  minutes: true,
+  hours: true,
+  seconds: true,
+  value: 10000000,
+});
+
+export const WithState = () => {
+  const [v, s] = useState<number>(1000000);
+  return <TestedComponent value={v} onChange={s} days minutes hours seconds />;
+};
diff --git a/packages/demobank-ui/src/components/picker/DurationPicker.tsx 
b/packages/demobank-ui/src/components/picker/DurationPicker.tsx
new file mode 100644
index 000000000..542ff2f01
--- /dev/null
+++ b/packages/demobank-ui/src/components/picker/DurationPicker.tsx
@@ -0,0 +1,211 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { h, VNode } from 'preact';
+import { useState } from 'preact/hooks';
+import { useTranslator } from '../../i18n';
+import '../../scss/DurationPicker.scss';
+
+export interface Props {
+  hours?: boolean;
+  minutes?: boolean;
+  seconds?: boolean;
+  days?: boolean;
+  onChange: (value: number) => void;
+  value: number;
+}
+
+// inspiration taken from https://github.com/flurmbo/react-duration-picker
+export function DurationPicker({
+  days,
+  hours,
+  minutes,
+  seconds,
+  onChange,
+  value,
+}: Props): VNode {
+  const ss = 1000;
+  const ms = ss * 60;
+  const hs = ms * 60;
+  const ds = hs * 24;
+  const i18n = useTranslator();
+
+  return (
+    <div class="rdp-picker">
+      {days && (
+        <DurationColumn
+          unit={i18n`days`}
+          max={99}
+          value={Math.floor(value / ds)}
+          onDecrease={value >= ds ? () => onChange(value - ds) : undefined}
+          onIncrease={value < 99 * ds ? () => onChange(value + ds) : undefined}
+          onChange={(diff) => onChange(value + diff * ds)}
+        />
+      )}
+      {hours && (
+        <DurationColumn
+          unit={i18n`hours`}
+          max={23}
+          min={1}
+          value={Math.floor(value / hs) % 24}
+          onDecrease={value >= hs ? () => onChange(value - hs) : undefined}
+          onIncrease={value < 99 * ds ? () => onChange(value + hs) : undefined}
+          onChange={(diff) => onChange(value + diff * hs)}
+        />
+      )}
+      {minutes && (
+        <DurationColumn
+          unit={i18n`minutes`}
+          max={59}
+          min={1}
+          value={Math.floor(value / ms) % 60}
+          onDecrease={value >= ms ? () => onChange(value - ms) : undefined}
+          onIncrease={value < 99 * ds ? () => onChange(value + ms) : undefined}
+          onChange={(diff) => onChange(value + diff * ms)}
+        />
+      )}
+      {seconds && (
+        <DurationColumn
+          unit={i18n`seconds`}
+          max={59}
+          value={Math.floor(value / ss) % 60}
+          onDecrease={value >= ss ? () => onChange(value - ss) : undefined}
+          onIncrease={value < 99 * ds ? () => onChange(value + ss) : undefined}
+          onChange={(diff) => onChange(value + diff * ss)}
+        />
+      )}
+    </div>
+  );
+}
+
+interface ColProps {
+  unit: string;
+  min?: number;
+  max: number;
+  value: number;
+  onIncrease?: () => void;
+  onDecrease?: () => void;
+  onChange?: (diff: number) => void;
+}
+
+function InputNumber({
+  initial,
+  onChange,
+}: {
+  initial: number;
+  onChange: (n: number) => void;
+}) {
+  const [value, handler] = useState<{ v: string }>({
+    v: toTwoDigitString(initial),
+  });
+
+  return (
+    <input
+      value={value.v}
+      onBlur={(e) => onChange(parseInt(value.v, 10))}
+      onInput={(e) => {
+        e.preventDefault();
+        const n = Number.parseInt(e.currentTarget.value, 10);
+        if (isNaN(n)) return handler({ v: toTwoDigitString(initial) });
+        return handler({ v: toTwoDigitString(n) });
+      }}
+      style={{
+        width: 50,
+        border: 'none',
+        fontSize: 'inherit',
+        background: 'inherit',
+      }}
+    />
+  );
+}
+
+function DurationColumn({
+  unit,
+  min = 0,
+  max,
+  value,
+  onIncrease,
+  onDecrease,
+  onChange,
+}: ColProps): VNode {
+  const cellHeight = 35;
+  return (
+    <div class="rdp-column-container">
+      <div class="rdp-masked-div">
+        <hr class="rdp-reticule" style={{ top: cellHeight * 2 - 1 }} />
+        <hr class="rdp-reticule" style={{ top: cellHeight * 3 - 1 }} />
+
+        <div class="rdp-column" style={{ top: 0 }}>
+          <div class="rdp-cell" key={value - 2}>
+            {onDecrease && (
+              <button
+                style={{ width: '100%', textAlign: 'center', margin: 5 }}
+                onClick={onDecrease}
+              >
+                <span class="icon">
+                  <i class="mdi mdi-chevron-up" />
+                </span>
+              </button>
+            )}
+          </div>
+          <div class="rdp-cell" key={value - 1}>
+            {value > min ? toTwoDigitString(value - 1) : ''}
+          </div>
+          <div class="rdp-cell rdp-center" key={value}>
+            {onChange ? (
+              <InputNumber
+                initial={value}
+                onChange={(n) => onChange(n - value)}
+              />
+            ) : (
+              toTwoDigitString(value)
+            )}
+            <div>{unit}</div>
+          </div>
+
+          <div class="rdp-cell" key={value + 1}>
+            {value < max ? toTwoDigitString(value + 1) : ''}
+          </div>
+
+          <div class="rdp-cell" key={value + 2}>
+            {onIncrease && (
+              <button
+                style={{ width: '100%', textAlign: 'center', margin: 5 }}
+                onClick={onIncrease}
+              >
+                <span class="icon">
+                  <i class="mdi mdi-chevron-down" />
+                </span>
+              </button>
+            )}
+          </div>
+        </div>
+      </div>
+    </div>
+  );
+}
+
+function toTwoDigitString(n: number) {
+  if (n < 10) 
+    return `0${n}`;
+  
+  return `${n}`;
+}
diff --git a/packages/demobank-ui/src/context/translation.ts 
b/packages/demobank-ui/src/context/translation.ts
new file mode 100644
index 000000000..1879fe43e
--- /dev/null
+++ b/packages/demobank-ui/src/context/translation.ts
@@ -0,0 +1,73 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { createContext, h, VNode } from 'preact';
+import { useContext, useEffect } from 'preact/hooks';
+import { useLang } from '../hooks';
+import * as jedLib from 'jed';
+import { strings } from '../i18n/strings';
+
+interface Type {
+  lang: string;
+  handler: any;
+  changeLanguage: (l: string) => void;
+}
+const initial = {
+  lang: 'en',
+  handler: null,
+  changeLanguage: () => {
+    /**
+     * This function will be replaced by one with
+     * the same signature _but_ coming from the state.
+     * FIXME: clarify this design.
+     */
+  },
+};
+const Context = createContext<Type>(initial);
+
+interface Props {
+  initial?: string;
+  children: any;
+  forceLang?: string;
+}
+
+// Outmost UI wrapper.
+export const TranslationProvider = ({
+  initial,
+  children,
+  forceLang,
+}: Props): VNode => {
+
+  const [lang, changeLanguage] = useLang(initial);
+  useEffect(() => {
+    if (forceLang) 
+      changeLanguage(forceLang);
+    
+  });
+  console.log('lang store', strings);
+  const handler = new jedLib.Jed(strings[lang] || strings['en']);
+  return h(Context.Provider, {
+    value: { lang, handler, changeLanguage },
+    children,
+  });
+};
+
+export const useTranslationContext = (): Type => useContext(Context);
diff --git a/packages/demobank-ui/src/declaration.d.ts 
b/packages/demobank-ui/src/declaration.d.ts
new file mode 100644
index 000000000..73bccac71
--- /dev/null
+++ b/packages/demobank-ui/src/declaration.d.ts
@@ -0,0 +1,20 @@
+declare module '*.css' {
+  const mapping: Record<string, string>;
+  export default mapping;
+}
+declare module '*.svg' {
+  const content: any;
+  export default content;
+}
+declare module '*.jpeg' {
+  const content: any;
+  export default content;
+}
+declare module '*.png' {
+  const content: any;
+  export default content;
+}
+declare module 'jed' {
+  const x: any;
+  export = x;
+}
diff --git a/packages/demobank-ui/src/hooks/async.ts 
b/packages/demobank-ui/src/hooks/async.ts
new file mode 100644
index 000000000..be41b4e07
--- /dev/null
+++ b/packages/demobank-ui/src/hooks/async.ts
@@ -0,0 +1,80 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { useState } from 'preact/hooks';
+// import { cancelPendingRequest } from "./backend";
+
+export interface Options {
+  slowTolerance: number;
+}
+
+export interface AsyncOperationApi<T> {
+  request: (...a: any) => void;
+  cancel: () => void;
+  data: T | undefined;
+  isSlow: boolean;
+  isLoading: boolean;
+  error: string | undefined;
+}
+
+export function useAsync<T>(
+  fn?: (...args: any) => Promise<T>,
+  { slowTolerance: tooLong }: Options = { slowTolerance: 1000 },
+): AsyncOperationApi<T> {
+  const [data, setData] = useState<T | undefined>(undefined);
+  const [isLoading, setLoading] = useState<boolean>(false);
+  const [error, setError] = useState<any>(undefined);
+  const [isSlow, setSlow] = useState(false);
+
+  const request = async (...args: any) => {
+    if (!fn) return;
+    setLoading(true);
+    const handler = setTimeout(() => {
+      setSlow(true);
+    }, tooLong);
+
+    try {
+      console.log('calling async', args);
+      const result = await fn(...args);
+      console.log('async back', result);
+      setData(result);
+    } catch (error) {
+      setError(error);
+    }
+    setLoading(false);
+    setSlow(false);
+    clearTimeout(handler);
+  };
+
+  function cancel() {
+    // cancelPendingRequest()
+    setLoading(false);
+    setSlow(false);
+  }
+
+  return {
+    request,
+    cancel,
+    data,
+    isSlow,
+    isLoading,
+    error,
+  };
+}
diff --git a/packages/demobank-ui/src/hooks/index.ts 
b/packages/demobank-ui/src/hooks/index.ts
new file mode 100644
index 000000000..795df909d
--- /dev/null
+++ b/packages/demobank-ui/src/hooks/index.ts
@@ -0,0 +1,151 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { StateUpdater, useState } from 'preact/hooks';
+export type ValueOrFunction<T> = T | ((p: T) => T);
+
+const calculateRootPath = () => {
+  const rootPath =
+    typeof window !== undefined
+      ? window.location.origin + window.location.pathname
+      : '/';
+  return rootPath;
+};
+
+export function useBackendURL(
+  url?: string,
+): [string, boolean, StateUpdater<string>, () => void] {
+  const [value, setter] = useNotNullLocalStorage(
+    'backend-url',
+    url || calculateRootPath(),
+  );
+  const [triedToLog, setTriedToLog] = useLocalStorage('tried-login');
+
+  const checkedSetter = (v: ValueOrFunction<string>) => {
+    setTriedToLog('yes');
+    return setter((p) => (v instanceof Function ? v(p) : v).replace(/\/$/, 
''));
+  };
+
+  const resetBackend = () => {
+    setTriedToLog(undefined);
+  };
+  return [value, !!triedToLog, checkedSetter, resetBackend];
+}
+
+export function useBackendDefaultToken(): [
+  string | undefined,
+  StateUpdater<string | undefined>,
+  ] {
+  return useLocalStorage('backend-token');
+}
+
+export function useBackendInstanceToken(
+  id: string,
+): [string | undefined, StateUpdater<string | undefined>] {
+  const [token, setToken] = useLocalStorage(`backend-token-${id}`);
+  const [defaultToken, defaultSetToken] = useBackendDefaultToken();
+
+  // instance named 'default' use the default token
+  if (id === 'default')
+    return [defaultToken, defaultSetToken];
+
+  return [token, setToken];
+}
+
+export function useLang(initial?: string): [string, StateUpdater<string>] {
+  const browserLang =
+    typeof window !== 'undefined'
+      ? navigator.language || (navigator as any).userLanguage
+      : undefined;
+  const defaultLang = (browserLang || initial || 'en').substring(0, 2);
+  const [value, setValue] = useNotNullLocalStorage('lang-preference', 
defaultLang);
+  function updateValue(newValue: (string | ((v: string) => string))) {
+    if (document.body.parentElement) {
+      const htmlElement = document.body.parentElement
+      if (typeof newValue === 'string') {
+        htmlElement.lang = newValue;
+        setValue(newValue)
+      } else if (typeof newValue === 'function')
+        setValue((old) => {
+          const nv = newValue(old)
+          htmlElement.lang = nv;
+          return nv
+        })
+    } else setValue(newValue)
+  }
+  return [value, updateValue]
+}
+
+export function useLocalStorage(
+  key: string,
+  initialValue?: string,
+): [string | undefined, StateUpdater<string | undefined>] {
+  const [storedValue, setStoredValue] = useState<string | undefined>(():
+    | string
+    | undefined => {
+    return typeof window !== 'undefined'
+      ? window.localStorage.getItem(key) || initialValue
+      : initialValue;
+  });
+
+  const setValue = (
+    value?: string | ((val?: string) => string | undefined),
+  ) => {
+    setStoredValue((p) => {
+      const toStore = value instanceof Function ? value(p) : value;
+      if (typeof window !== 'undefined')
+        if (!toStore)
+          window.localStorage.removeItem(key);
+        else
+          window.localStorage.setItem(key, toStore);
+
+
+      return toStore;
+    });
+  };
+
+  return [storedValue, setValue];
+}
+
+export function useNotNullLocalStorage(
+  key: string,
+  initialValue: string,
+): [string, StateUpdater<string>] {
+  const [storedValue, setStoredValue] = useState<string>((): string => {
+    return typeof window !== 'undefined'
+      ? window.localStorage.getItem(key) || initialValue
+      : initialValue;
+  });
+
+  const setValue = (value: string | ((val: string) => string)) => {
+    const valueToStore = value instanceof Function ? value(storedValue) : 
value;
+    setStoredValue(valueToStore);
+    if (typeof window !== 'undefined')
+      if (!valueToStore)
+        window.localStorage.removeItem(key);
+      else
+        window.localStorage.setItem(key, valueToStore);
+
+
+  };
+
+  return [storedValue, setValue];
+}
diff --git a/packages/demobank-ui/src/i18n/bank.pot 
b/packages/demobank-ui/src/i18n/bank.pot
new file mode 100644
index 000000000..dcaba009d
--- /dev/null
+++ b/packages/demobank-ui/src/i18n/bank.pot
@@ -0,0 +1,258 @@
+#: 
/home/job/backoffice/packages/bank/src/components/picker/DurationPicker.tsx:55
+#, c-format
+msgid "days"
+msgstr ""
+
+#: 
/home/job/backoffice/packages/bank/src/components/picker/DurationPicker.tsx:65
+#, c-format
+msgid "hours"
+msgstr ""
+
+#: 
/home/job/backoffice/packages/bank/src/components/picker/DurationPicker.tsx:76
+#, c-format
+msgid "minutes"
+msgstr ""
+
+#: 
/home/job/backoffice/packages/bank/src/components/picker/DurationPicker.tsx:87
+#, c-format
+msgid "seconds"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:734
+#, c-format
+msgid "Clear"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:761
+#, c-format
+msgid "Logout"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:782
+#, c-format
+msgid "Demo Bank"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:837
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:840
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1189
+#, c-format
+msgid "Go back"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:845
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:906
+#, c-format
+msgid "Wire transfer"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:846
+#, c-format
+msgid "Transfer money to another account of this bank:"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:897
+#, c-format
+msgid "Want to try the raw payto://-format?"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:907
+#, c-format
+msgid "Transfer money via the Payto system:"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:916
+#, c-format
+msgid "payto address"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:926
+#, c-format
+msgid "Confirm"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:956
+#, c-format
+msgid "Confirm Withdrawal"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1026
+#, c-format
+msgid "Waiting the bank to create the operaion..."
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1044
+#, c-format
+msgid "This withdrawal was aborted!"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1051
+#, c-format
+msgid "Withdraw to a Taler Wallet"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1052
+#, c-format
+msgid "You can use this QR code to withdraw to your mobile wallet:"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1054
+#, c-format
+msgid "this link"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1060
+#, c-format
+msgid "Abort"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1084
+#, c-format
+msgid "Start withdrawal"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1101
+#, c-format
+msgid "Withdraw Money into a Taler wallet"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1105
+#, c-format
+msgid "Amount to withdraw"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1137
+#, c-format
+msgid "Please login!"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1169
+#, c-format
+msgid "Login"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1184
+#, c-format
+msgid "Register to the euFin bank!"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1194
+#, c-format
+msgid "Registration form"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1232
+#, c-format
+msgid "Register"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1272
+#, c-format
+msgid "Date"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1273
+#, c-format
+msgid "Amount"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1274
+#, c-format
+msgid "Counterpart"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1275
+#, c-format
+msgid "Subject"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1343
+#, c-format
+msgid "Username or account label '%1$s' not found.  Won't login."
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1365
+#, c-format
+msgid "Wrong credentials given."
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1374
+#, c-format
+msgid "Account information could not be retrieved."
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1394
+#, c-format
+msgid "Close wire transfer"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1412
+#, c-format
+msgid "Close Taler withdrawal"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1457
+#, c-format
+msgid "Bank account balance:"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1469
+#, c-format
+msgid "Latest transactions:"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1474
+#, c-format
+msgid "Transfer money manually"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1543
+#, c-format
+msgid "List of public accounts was not found."
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1552
+#, c-format
+msgid "List of public accounts could not be retrieved."
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1584
+#, c-format
+msgid "History of public accounts"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1643
+#, c-format
+msgid "Page has a problem: logged in but backend state is lost."
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1667
+#, c-format
+msgid "Welcome to the euFin bank!"
+msgstr ""
+
+#  This file is part of GNU Taler
+#  (C) 2021 Taler Systems S.A.
+#  GNU Taler is free software; you can redistribute it and/or modify it under 
the
+#  terms of the GNU General Public License as published by the Free Software
+#  Foundation; either version 3, or (at your option) any later version.
+#  GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+#  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+#  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#  You should have received a copy of the GNU General Public License along with
+#  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Taler Wallet\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2016-11-23 00:00+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
diff --git a/packages/demobank-ui/src/i18n/de.po 
b/packages/demobank-ui/src/i18n/de.po
new file mode 100644
index 000000000..bd4158037
--- /dev/null
+++ b/packages/demobank-ui/src/i18n/de.po
@@ -0,0 +1,257 @@
+#: 
/home/job/backoffice/packages/bank/src/components/picker/DurationPicker.tsx:55
+#, c-format
+msgid "days"
+msgstr ""
+
+#: 
/home/job/backoffice/packages/bank/src/components/picker/DurationPicker.tsx:65
+#, c-format
+msgid "hours"
+msgstr ""
+
+#: 
/home/job/backoffice/packages/bank/src/components/picker/DurationPicker.tsx:76
+#, c-format
+msgid "minutes"
+msgstr ""
+
+#: 
/home/job/backoffice/packages/bank/src/components/picker/DurationPicker.tsx:87
+#, c-format
+msgid "seconds"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:734
+#, c-format
+msgid "Clear"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:761
+#, c-format
+msgid "Logout"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:782
+#, c-format
+msgid "Demo Bank"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:837
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:840
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1189
+#, c-format
+msgid "Go back"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:845
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:906
+#, c-format
+msgid "Wire transfer"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:846
+#, c-format
+msgid "Transfer money to another account of this bank:"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:897
+#, c-format
+msgid "Want to try the raw payto://-format?"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:907
+#, c-format
+msgid "Transfer money via the Payto system:"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:916
+#, c-format
+msgid "payto address"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:926
+#, c-format
+msgid "Confirm"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:956
+#, c-format
+msgid "Confirm Withdrawal"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1026
+#, c-format
+msgid "Waiting the bank to create the operaion..."
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1044
+#, c-format
+msgid "This withdrawal was aborted!"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1051
+#, c-format
+msgid "Withdraw to a Taler Wallet"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1052
+#, c-format
+msgid "You can use this QR code to withdraw to your mobile wallet:"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1054
+#, c-format
+msgid "this link"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1060
+#, c-format
+msgid "Abort"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1084
+#, c-format
+msgid "Start withdrawal"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1101
+#, c-format
+msgid "Withdraw Money into a Taler wallet"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1105
+#, c-format
+msgid "Amount to withdraw"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1137
+#, c-format
+msgid "Please login!"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1169
+#, c-format
+msgid "Login"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1184
+#, c-format
+msgid "Register to the euFin bank!"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1194
+#, c-format
+msgid "Registration form"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1232
+#, c-format
+msgid "Register"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1272
+#, c-format
+msgid "Date"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1273
+#, c-format
+msgid "Amount"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1274
+#, c-format
+msgid "Counterpart"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1275
+#, c-format
+msgid "Subject"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1343
+#, c-format
+msgid "Username or account label '%1$s' not found.  Won't login."
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1365
+#, c-format
+msgid "Wrong credentials given."
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1374
+#, c-format
+msgid "Account information could not be retrieved."
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1394
+#, c-format
+msgid "Close wire transfer"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1412
+#, c-format
+msgid "Close Taler withdrawal"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1457
+#, c-format
+msgid "Bank account balance:"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1469
+#, c-format
+msgid "Latest transactions:"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1474
+#, c-format
+msgid "Transfer money manually"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1543
+#, c-format
+msgid "List of public accounts was not found."
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1552
+#, c-format
+msgid "List of public accounts could not be retrieved."
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1584
+#, c-format
+msgid "History of public accounts"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1643
+#, c-format
+msgid "Page has a problem: logged in but backend state is lost."
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1667
+#, c-format
+msgid "Welcome to the euFin bank!"
+msgstr ""
+
+#  This file is part of GNU Taler
+#  (C) 2021 Taler Systems S.A.
+#  GNU Taler is free software; you can redistribute it and/or modify it under 
the
+#  terms of the GNU General Public License as published by the Free Software
+#  Foundation; either version 3, or (at your option) any later version.
+#  GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+#  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+#  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#  You should have received a copy of the GNU General Public License along with
+#  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Taler Wallet\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2016-11-23 00:00+0100\n"
+"PO-Revision-Date: 2022-01-08 09:57+0100\n"
+"Last-Translator:  <translate@taler.net>\n"
+"Language-Team: German\n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
diff --git a/packages/demobank-ui/src/i18n/en.po 
b/packages/demobank-ui/src/i18n/en.po
new file mode 100644
index 000000000..4cbc9e74c
--- /dev/null
+++ b/packages/demobank-ui/src/i18n/en.po
@@ -0,0 +1,266 @@
+#: 
/home/job/backoffice/packages/bank/src/components/picker/DurationPicker.tsx:55
+#, c-format
+msgid "days"
+msgstr "days"
+
+#: 
/home/job/backoffice/packages/bank/src/components/picker/DurationPicker.tsx:65
+#, c-format
+msgid "hours"
+msgstr "hours"
+
+#: 
/home/job/backoffice/packages/bank/src/components/picker/DurationPicker.tsx:76
+#, c-format
+msgid "minutes"
+msgstr "minutes"
+
+#: 
/home/job/backoffice/packages/bank/src/components/picker/DurationPicker.tsx:87
+#, c-format
+msgid "seconds"
+msgstr "seconds"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:734
+#, c-format
+msgid "Clear"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:761
+#, c-format
+msgid "Logout"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:782
+#, c-format
+msgid "Demo Bank"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:837
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:840
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1189
+#, c-format
+msgid "Go back"
+msgstr "Go back"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:845
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:906
+#, c-format
+msgid "Wire transfer"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:846
+#, c-format
+msgid "Transfer money to another account of this bank:"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:897
+#, c-format
+msgid "Want to try the raw payto://-format?"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:907
+#, c-format
+msgid "Transfer money via the Payto system:"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:916
+#, c-format
+msgid "payto address"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:926
+#, c-format
+msgid "Confirm"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:956
+#, fuzzy, c-format
+msgid "Confirm Withdrawal"
+msgstr "Confirm withdrawal"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1026
+#, c-format
+msgid "Waiting the bank to create the operaion..."
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1044
+#, c-format
+msgid "This withdrawal was aborted!"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1051
+#, fuzzy, c-format
+msgid "Withdraw to a Taler Wallet"
+msgstr "Charge Taler wallet"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1052
+#, c-format
+msgid "You can use this QR code to withdraw to your mobile wallet:"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1054
+#, c-format
+msgid "this link"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1060
+#, c-format
+msgid "Abort"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1084
+#, fuzzy, c-format
+msgid "Start withdrawal"
+msgstr "Start withdrawal"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1101
+#, fuzzy, c-format
+msgid "Withdraw Money into a Taler wallet"
+msgstr "Charge Taler wallet"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1105
+#, fuzzy, c-format
+msgid "Amount to withdraw"
+msgstr "Amount to withdraw"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1137
+#, c-format
+msgid "Please login!"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1169
+#, c-format
+msgid "Login"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1184
+#, c-format
+msgid "Register to the euFin bank!"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1194
+#, c-format
+msgid "Registration form"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1232
+#, c-format
+msgid "Register"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1272
+#, c-format
+msgid "Date"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1273
+#, c-format
+msgid "Amount"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1274
+#, c-format
+msgid "Counterpart"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1275
+#, c-format
+msgid "Subject"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1343
+#, c-format
+msgid "Username or account label '%1$s' not found.  Won't login."
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1365
+#, c-format
+msgid "Wrong credentials given."
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1374
+#, c-format
+msgid "Account information could not be retrieved."
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1394
+#, c-format
+msgid "Close wire transfer"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1412
+#, fuzzy, c-format
+msgid "Close Taler withdrawal"
+msgstr "Close Taler withdrawal"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1457
+#, c-format
+msgid "Bank account balance:"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1469
+#, c-format
+msgid "Latest transactions:"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1474
+#, c-format
+msgid "Transfer money manually"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1543
+#, c-format
+msgid "List of public accounts was not found."
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1552
+#, c-format
+msgid "List of public accounts could not be retrieved."
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1584
+#, c-format
+msgid "History of public accounts"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1643
+#, c-format
+msgid "Page has a problem: logged in but backend state is lost."
+msgstr "Page has a problem: logged in but backend state is lost."
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1667
+#, fuzzy, c-format
+msgid "Welcome to the euFin bank!"
+msgstr "Welcome to euFin bank: Taler+IBAN now possible!"
+
+#  This file is part of GNU Taler
+#  (C) 2021 Taler Systems S.A.
+#  GNU Taler is free software; you can redistribute it and/or modify it under 
the
+#  terms of the GNU General Public License as published by the Free Software
+#  Foundation; either version 3, or (at your option) any later version.
+#  GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+#  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+#  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#  You should have received a copy of the GNU General Public License along with
+#  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Taler Wallet\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2016-11-23 00:00+0100\n"
+"PO-Revision-Date: 2022-01-08 09:57+0100\n"
+"Last-Translator:  <translate@taler.net>\n"
+"Language-Team: English\n"
+"Language: en\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#~ msgid "Page has a problem:"
+#~ msgstr "Page has a problem:"
+
+#~ msgid "Close"
+#~ msgstr "Close"
+
+#~ msgid "Sign in"
+#~ msgstr "Sign in"
diff --git a/packages/demobank-ui/src/i18n/index.tsx 
b/packages/demobank-ui/src/i18n/index.tsx
new file mode 100644
index 000000000..9882525a1
--- /dev/null
+++ b/packages/demobank-ui/src/i18n/index.tsx
@@ -0,0 +1,211 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ * Translation helpers for React components and template literals.
+ */
+
+/**
+ * Imports
+ */
+import { ComponentChild, ComponentChildren, h, Fragment, VNode } from 'preact';
+
+import { useTranslationContext } from '../context/translation';
+
+export function useTranslator() {
+  const ctx = useTranslationContext();
+  const jed = ctx.handler;
+  return function str(
+    stringSeq: TemplateStringsArray,
+    ...values: any[]
+  ): string {
+    const s = toI18nString(stringSeq);
+    if (!s) return s;
+    const tr = jed
+      .translate(s)
+      .ifPlural(1, s)
+      .fetch(...values);
+    return tr;
+  };
+}
+
+/**
+ * Convert template strings to a msgid
+ */
+function toI18nString(stringSeq: ReadonlyArray<string>): string {
+  let s = '';
+  for (let i = 0; i < stringSeq.length; i++) {
+    s += stringSeq[i];
+    if (i < stringSeq.length - 1) 
+      s += `%${i + 1}$s`;
+    
+  }
+  return s;
+}
+
+interface TranslateSwitchProps {
+  target: number;
+  children: ComponentChildren;
+}
+
+function stringifyChildren(children: ComponentChildren): string {
+  let n = 1;
+  const ss = (children instanceof Array ? children : [children]).map((c) => {
+    if (typeof c === 'string') 
+      return c;
+    
+    return `%${n++}$s`;
+  });
+  const s = ss.join('').replace(/ +/g, ' ').trim();
+  return s;
+}
+
+interface TranslateProps {
+  children: ComponentChildren;
+  /**
+   * Component that the translated element should be wrapped in.
+   * Defaults to "div".
+   */
+  wrap?: any;
+
+  /**
+   * Props to give to the wrapped component.
+   */
+  wrapProps?: any;
+}
+
+function getTranslatedChildren(
+  translation: string,
+  children: ComponentChildren,
+): ComponentChild[] {
+  const tr = translation.split(/%(\d+)\$s/);
+  const childArray = children instanceof Array ? children : [children];
+  // Merge consecutive string children.
+  const placeholderChildren = Array<ComponentChild>();
+  for (let i = 0; i < childArray.length; i++) {
+    const x = childArray[i];
+    if (x === undefined) 
+      continue;
+    else if (typeof x === 'string') 
+      continue;
+    else 
+      placeholderChildren.push(x);
+    
+  }
+  const result = Array<ComponentChild>();
+  for (let i = 0; i < tr.length; i++) 
+    if (i % 2 == 0) 
+      // Text
+      result.push(tr[i]);
+    else {
+      const childIdx = Number.parseInt(tr[i], 10) - 1;
+      result.push(placeholderChildren[childIdx]);
+    }
+  
+  return result;
+}
+
+/**
+ * Translate text node children of this component.
+ * If a child component might produce a text node, it must be wrapped
+ * in a another non-text element.
+ *
+ * Example:
+ * ```
+ * <Translate>
+ * Hello.  Your score is <span><PlayerScore player={player} /></span>
+ * </Translate>
+ * ```
+ */
+export function Translate({ children }: TranslateProps): VNode {
+  const s = stringifyChildren(children);
+  const ctx = useTranslationContext();
+  const translation: string = ctx.handler.ngettext(s, s, 1);
+  const result = getTranslatedChildren(translation, children);
+  return <Fragment>{result}</Fragment>;
+}
+
+/**
+ * Switch translation based on singular or plural based on the target prop.
+ * Should only contain TranslateSingular and TransplatePlural as children.
+ *
+ * Example:
+ * ```
+ * <TranslateSwitch target={n}>
+ *  <TranslateSingular>I have {n} apple.</TranslateSingular>
+ *  <TranslatePlural>I have {n} apples.</TranslatePlural>
+ * </TranslateSwitch>
+ * ```
+ */
+export function TranslateSwitch({ children, target }: TranslateSwitchProps) {
+  let singular: VNode<TranslationPluralProps> | undefined;
+  let plural: VNode<TranslationPluralProps> | undefined;
+  // const children = this.props.children;
+  if (children) 
+    (children instanceof Array ? children : [children]).forEach(
+      (child: any) => {
+        if (child.type === TranslatePlural) 
+          plural = child;
+        
+        if (child.type === TranslateSingular) 
+          singular = child;
+        
+      },
+    );
+  
+  if (!singular || !plural) {
+    console.error('translation not found');
+    return h('span', {}, ['translation not found']);
+  }
+  singular.props.target = target;
+  plural.props.target = target;
+  // We're looking up the translation based on the
+  // singular, even if we must use the plural form.
+  return singular;
+}
+
+interface TranslationPluralProps {
+  children: ComponentChildren;
+  target: number;
+}
+
+/**
+ * See [[TranslateSwitch]].
+ */
+export function TranslatePlural({
+  children,
+  target,
+}: TranslationPluralProps): VNode {
+  const s = stringifyChildren(children);
+  const ctx = useTranslationContext();
+  const translation = ctx.handler.ngettext(s, s, 1);
+  const result = getTranslatedChildren(translation, children);
+  return <Fragment>{result}</Fragment>;
+}
+
+/**
+ * See [[TranslateSwitch]].
+ */
+export function TranslateSingular({
+  children,
+  target,
+}: TranslationPluralProps): VNode {
+  const s = stringifyChildren(children);
+  const ctx = useTranslationContext();
+  const translation = ctx.handler.ngettext(s, s, target);
+  const result = getTranslatedChildren(translation, children);
+  return <Fragment>{result}</Fragment>;
+}
diff --git a/packages/demobank-ui/src/i18n/it.po 
b/packages/demobank-ui/src/i18n/it.po
new file mode 100644
index 000000000..91a30b947
--- /dev/null
+++ b/packages/demobank-ui/src/i18n/it.po
@@ -0,0 +1,258 @@
+#: 
/home/job/backoffice/packages/bank/src/components/picker/DurationPicker.tsx:55
+#, c-format
+msgid "days"
+msgstr ""
+
+#: 
/home/job/backoffice/packages/bank/src/components/picker/DurationPicker.tsx:65
+#, c-format
+msgid "hours"
+msgstr ""
+
+#: 
/home/job/backoffice/packages/bank/src/components/picker/DurationPicker.tsx:76
+#, c-format
+msgid "minutes"
+msgstr ""
+
+#: 
/home/job/backoffice/packages/bank/src/components/picker/DurationPicker.tsx:87
+#, c-format
+msgid "seconds"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:734
+#, c-format
+msgid "Clear"
+msgstr "Cancella"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:761
+#, c-format
+msgid "Logout"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:782
+#, c-format
+msgid "Demo Bank"
+msgstr "Banca 'demo'"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:837
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:840
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1189
+#, c-format
+msgid "Go back"
+msgstr "Indietro"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:845
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:906
+#, c-format
+msgid "Wire transfer"
+msgstr "Bonifico"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:846
+#, c-format
+msgid "Transfer money to another account of this bank:"
+msgstr "Trasferisci fondi a un altro conto di questa banca:"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:897
+#, c-format
+msgid "Want to try the raw payto://-format?"
+msgstr "Prova il trasferimento tramite il formato Payto!"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:907
+#, c-format
+msgid "Transfer money via the Payto system:"
+msgstr "Effettua un bonifico tramite il sistema Payto:"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:916
+#, c-format
+msgid "payto address"
+msgstr "indirizzo Payto"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:926
+#, c-format
+msgid "Confirm"
+msgstr "Conferma"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:956
+#, c-format
+msgid "Confirm Withdrawal"
+msgstr "Conferma il ritiro"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1026
+#, c-format
+msgid "Waiting the bank to create the operaion..."
+msgstr "La banca sta creando l'operazione..."
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1044
+#, c-format
+msgid "This withdrawal was aborted!"
+msgstr "Questo ritiro è stato annullato!"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1051
+#, c-format
+msgid "Withdraw to a Taler Wallet"
+msgstr "Ritira contante nel portafoglio Taler"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1052
+#, c-format
+msgid "You can use this QR code to withdraw to your mobile wallet:"
+msgstr "Usa questo codice QR per ritirare contante nel tuo wallet:"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1054
+#, c-format
+msgid "this link"
+msgstr "questo link"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1060
+#, c-format
+msgid "Abort"
+msgstr "Annulla"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1084
+#, c-format
+msgid "Start withdrawal"
+msgstr "Ritira contante"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1101
+#, c-format
+msgid "Withdraw Money into a Taler wallet"
+msgstr "Ritira contante nel portafoglio Taler"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1105
+#, c-format
+msgid "Amount to withdraw"
+msgstr "Somma da ritirare"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1137
+#, c-format
+msgid "Please login!"
+msgstr "Accedi!"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1169
+#, c-format
+msgid "Login"
+msgstr "Accedi"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1184
+#, c-format
+msgid "Register to the euFin bank!"
+msgstr "Apri un conto in banca euFin!"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1194
+#, c-format
+msgid "Registration form"
+msgstr "Registrazione"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1232
+#, c-format
+msgid "Register"
+msgstr "Registrati"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1272
+#, c-format
+msgid "Date"
+msgstr ""
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1273
+#, c-format
+msgid "Amount"
+msgstr "Somma"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1274
+#, c-format
+msgid "Counterpart"
+msgstr "Controparte"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1275
+#, c-format
+msgid "Subject"
+msgstr "Causale"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1343
+#, c-format
+msgid "Username or account label '%1$s' not found.  Won't login."
+msgstr "L'utente '%1$s' non esiste.  Login impossibile"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1365
+#, c-format
+msgid "Wrong credentials given."
+msgstr "Credenziali invalide."
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1374
+#, c-format
+msgid "Account information could not be retrieved."
+msgstr "Impossibile ricevere le informazioni relative al conto."
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1394
+#, c-format
+msgid "Close wire transfer"
+msgstr "Chiudi il bonifico"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1412
+#, c-format
+msgid "Close Taler withdrawal"
+msgstr "Chiudi il ritiro Taler"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1457
+#, c-format
+msgid "Bank account balance:"
+msgstr "Bilancio:"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1469
+#, c-format
+msgid "Latest transactions:"
+msgstr "Ultime transazioni:"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1474
+#, c-format
+msgid "Transfer money manually"
+msgstr "Effettua un bonifico"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1543
+#, c-format
+msgid "List of public accounts was not found."
+msgstr "Lista conti pubblici non trovata."
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1552
+#, c-format
+msgid "List of public accounts could not be retrieved."
+msgstr "Lista conti pubblici non pervenuta."
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1584
+#, c-format
+msgid "History of public accounts"
+msgstr "Storico dei conti pubblici"
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1643
+#, c-format
+msgid "Page has a problem: logged in but backend state is lost."
+msgstr ""
+"Stato inconsistente: accesso utente effettuato ma stato con server perso."
+
+#: /home/job/backoffice/packages/bank/src/pages/home/index.tsx:1667
+#, fuzzy, c-format
+msgid "Welcome to the euFin bank!"
+msgstr "Benvenuti in banca euFin!"
+
+#  This file is part of GNU Taler
+#  (C) 2021 Taler Systems S.A.
+#  GNU Taler is free software; you can redistribute it and/or modify it under 
the
+#  terms of the GNU General Public License as published by the Free Software
+#  Foundation; either version 3, or (at your option) any later version.
+#  GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+#  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+#  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#  You should have received a copy of the GNU General Public License along with
+#  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Taler Wallet\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2016-11-23 00:00+0100\n"
+"PO-Revision-Date: 2022-01-08 10:05+0100\n"
+"Last-Translator:  <translate@taler.net>\n"
+"Language-Team: Italian\n"
+"Language: it\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
diff --git a/packages/demobank-ui/src/i18n/poheader 
b/packages/demobank-ui/src/i18n/poheader
new file mode 100644
index 000000000..ee3fcd7be
--- /dev/null
+++ b/packages/demobank-ui/src/i18n/poheader
@@ -0,0 +1,27 @@
+#  This file is part of GNU Taler
+#  (C) 2021 Taler Systems S.A.
+
+#  GNU Taler is free software; you can redistribute it and/or modify it under 
the
+#  terms of the GNU General Public License as published by the Free Software
+#  Foundation; either version 3, or (at your option) any later version.
+
+#  GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+#  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+#  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+#  You should have received a copy of the GNU General Public License along with
+#  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Taler Wallet\n"
+"Report-Msgid-Bugs-To: taler@gnu.org\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
diff --git a/packages/demobank-ui/src/i18n/strings-prelude 
b/packages/demobank-ui/src/i18n/strings-prelude
new file mode 100644
index 000000000..cca13afad
--- /dev/null
+++ b/packages/demobank-ui/src/i18n/strings-prelude
@@ -0,0 +1,19 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/*eslint quote-props: ["error", "consistent"]*/
+export const strings: {[s: string]: any} = {};
+
diff --git a/packages/demobank-ui/src/i18n/strings.ts 
b/packages/demobank-ui/src/i18n/strings.ts
new file mode 100644
index 000000000..1a3c72f85
--- /dev/null
+++ b/packages/demobank-ui/src/i18n/strings.ts
@@ -0,0 +1,472 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/*eslint quote-props: ["error", "consistent"]*/
+export const strings: {[s: string]: any} = {};
+
+strings['de'] = {
+  'domain': 'messages',
+  'locale_data': {
+    'messages': {
+      'days': [
+        ''
+      ],
+      'hours': [
+        ''
+      ],
+      'minutes': [
+        ''
+      ],
+      'seconds': [
+        ''
+      ],
+      'Clear': [
+        ''
+      ],
+      'Logout': [
+        ''
+      ],
+      'Demo Bank': [
+        ''
+      ],
+      'Go back': [
+        ''
+      ],
+      'Wire transfer': [
+        ''
+      ],
+      'Transfer money to another account of this bank:': [
+        ''
+      ],
+      'Want to try the raw payto://-format?': [
+        ''
+      ],
+      'Transfer money via the Payto system:': [
+        ''
+      ],
+      'payto address': [
+        ''
+      ],
+      'Confirm': [
+        ''
+      ],
+      'Confirm Withdrawal': [
+        ''
+      ],
+      'Waiting the bank to create the operaion...': [
+        ''
+      ],
+      'This withdrawal was aborted!': [
+        ''
+      ],
+      'Withdraw to a Taler Wallet': [
+        ''
+      ],
+      'You can use this QR code to withdraw to your mobile wallet:': [
+        ''
+      ],
+      'this link': [
+        ''
+      ],
+      'Abort': [
+        ''
+      ],
+      'Start withdrawal': [
+        ''
+      ],
+      'Withdraw Money into a Taler wallet': [
+        ''
+      ],
+      'Amount to withdraw': [
+        ''
+      ],
+      'Please login!': [
+        ''
+      ],
+      'Login': [
+        ''
+      ],
+      'Register to the euFin bank!': [
+        ''
+      ],
+      'Registration form': [
+        ''
+      ],
+      'Register': [
+        ''
+      ],
+      'Date': [
+        ''
+      ],
+      'Amount': [
+        ''
+      ],
+      'Counterpart': [
+        ''
+      ],
+      'Subject': [
+        ''
+      ],
+      'Username or account label \'%1$s\' not found.  Won\'t login.': [
+        ''
+      ],
+      'Wrong credentials given.': [
+        ''
+      ],
+      'Account information could not be retrieved.': [
+        ''
+      ],
+      'Close wire transfer': [
+        ''
+      ],
+      'Close Taler withdrawal': [
+        ''
+      ],
+      'Bank account balance:': [
+        ''
+      ],
+      'Latest transactions:': [
+        ''
+      ],
+      'Transfer money manually': [
+        ''
+      ],
+      'List of public accounts was not found.': [
+        ''
+      ],
+      'List of public accounts could not be retrieved.': [
+        ''
+      ],
+      'History of public accounts': [
+        ''
+      ],
+      'Page has a problem: logged in but backend state is lost.': [
+        ''
+      ],
+      'Welcome to the euFin bank!': [
+        ''
+      ],
+      '': {
+        'domain': 'messages',
+        'plural_forms': 'nplurals=2; plural=(n != 1);',
+        'lang': 'de'
+      }
+    }
+  }
+};
+
+strings['en'] = {
+  'domain': 'messages',
+  'locale_data': {
+    'messages': {
+      'days': [
+        'days'
+      ],
+      'hours': [
+        'hours'
+      ],
+      'minutes': [
+        'minutes'
+      ],
+      'seconds': [
+        'seconds'
+      ],
+      'Clear': [
+        ''
+      ],
+      'Logout': [
+        ''
+      ],
+      'Demo Bank': [
+        ''
+      ],
+      'Go back': [
+        'Go back'
+      ],
+      'Wire transfer': [
+        ''
+      ],
+      'Transfer money to another account of this bank:': [
+        ''
+      ],
+      'Want to try the raw payto://-format?': [
+        ''
+      ],
+      'Transfer money via the Payto system:': [
+        ''
+      ],
+      'payto address': [
+        ''
+      ],
+      'Confirm': [
+        ''
+      ],
+      'Confirm Withdrawal': [
+        'Confirm withdrawal'
+      ],
+      'Waiting the bank to create the operaion...': [
+        ''
+      ],
+      'This withdrawal was aborted!': [
+        ''
+      ],
+      'Withdraw to a Taler Wallet': [
+        'Charge Taler wallet'
+      ],
+      'You can use this QR code to withdraw to your mobile wallet:': [
+        ''
+      ],
+      'this link': [
+        ''
+      ],
+      'Abort': [
+        ''
+      ],
+      'Start withdrawal': [
+        'Start withdrawal'
+      ],
+      'Withdraw Money into a Taler wallet': [
+        'Charge Taler wallet'
+      ],
+      'Amount to withdraw': [
+        'Amount to withdraw'
+      ],
+      'Please login!': [
+        ''
+      ],
+      'Login': [
+        ''
+      ],
+      'Register to the euFin bank!': [
+        ''
+      ],
+      'Registration form': [
+        ''
+      ],
+      'Register': [
+        ''
+      ],
+      'Date': [
+        ''
+      ],
+      'Amount': [
+        ''
+      ],
+      'Counterpart': [
+        ''
+      ],
+      'Subject': [
+        ''
+      ],
+      'Username or account label \'%1$s\' not found.  Won\'t login.': [
+        ''
+      ],
+      'Wrong credentials given.': [
+        ''
+      ],
+      'Account information could not be retrieved.': [
+        ''
+      ],
+      'Close wire transfer': [
+        ''
+      ],
+      'Close Taler withdrawal': [
+        'Close Taler withdrawal'
+      ],
+      'Bank account balance:': [
+        ''
+      ],
+      'Latest transactions:': [
+        ''
+      ],
+      'Transfer money manually': [
+        ''
+      ],
+      'List of public accounts was not found.': [
+        ''
+      ],
+      'List of public accounts could not be retrieved.': [
+        ''
+      ],
+      'History of public accounts': [
+        ''
+      ],
+      'Page has a problem: logged in but backend state is lost.': [
+        'Page has a problem: logged in but backend state is lost.'
+      ],
+      'Welcome to the euFin bank!': [
+        'Welcome to euFin bank: Taler+IBAN now possible!'
+      ],
+      '': {
+        'domain': 'messages',
+        'plural_forms': 'nplurals=2; plural=(n != 1);',
+        'lang': 'en'
+      }
+    }
+  }
+};
+
+strings['it'] = {
+  'domain': 'messages',
+  'locale_data': {
+    'messages': {
+      'days': [
+        ''
+      ],
+      'hours': [
+        ''
+      ],
+      'minutes': [
+        ''
+      ],
+      'seconds': [
+        ''
+      ],
+      'Clear': [
+        'Cancella'
+      ],
+      'Logout': [
+        ''
+      ],
+      'Demo Bank': [
+        'Banca \'demo\''
+      ],
+      'Go back': [
+        'Indietro'
+      ],
+      'Wire transfer': [
+        'Bonifico'
+      ],
+      'Transfer money to another account of this bank:': [
+        'Trasferisci fondi a un altro conto di questa banca:'
+      ],
+      'Want to try the raw payto://-format?': [
+        'Prova il trasferimento tramite il formato Payto!'
+      ],
+      'Transfer money via the Payto system:': [
+        'Effettua un bonifico tramite il sistema Payto:'
+      ],
+      'payto address': [
+        'indirizzo Payto'
+      ],
+      'Confirm': [
+        'Conferma'
+      ],
+      'Confirm Withdrawal': [
+        'Conferma il ritiro'
+      ],
+      'Waiting the bank to create the operaion...': [
+        'La banca sta creando l\'operazione...'
+      ],
+      'This withdrawal was aborted!': [
+        'Questo ritiro è stato annullato!'
+      ],
+      'Withdraw to a Taler Wallet': [
+        'Ritira contante nel portafoglio Taler'
+      ],
+      'You can use this QR code to withdraw to your mobile wallet:': [
+        'Usa questo codice QR per ritirare contante nel tuo wallet:'
+      ],
+      'this link': [
+        'questo link'
+      ],
+      'Abort': [
+        'Annulla'
+      ],
+      'Start withdrawal': [
+        'Ritira contante'
+      ],
+      'Withdraw Money into a Taler wallet': [
+        'Ritira contante nel portafoglio Taler'
+      ],
+      'Amount to withdraw': [
+        'Somma da ritirare'
+      ],
+      'Please login!': [
+        'Accedi!'
+      ],
+      'Login': [
+        'Accedi'
+      ],
+      'Register to the euFin bank!': [
+        'Apri un conto in banca euFin!'
+      ],
+      'Registration form': [
+        'Registrazione'
+      ],
+      'Register': [
+        'Registrati'
+      ],
+      'Date': [
+        ''
+      ],
+      'Amount': [
+        'Somma'
+      ],
+      'Counterpart': [
+        'Controparte'
+      ],
+      'Subject': [
+        'Causale'
+      ],
+      'Username or account label \'%1$s\' not found.  Won\'t login.': [
+        'L\'utente \'%1$s\' non esiste.  Login impossibile'
+      ],
+      'Wrong credentials given.': [
+        'Credenziali invalide.'
+      ],
+      'Account information could not be retrieved.': [
+        'Impossibile ricevere le informazioni relative al conto.'
+      ],
+      'Close wire transfer': [
+        'Chiudi il bonifico'
+      ],
+      'Close Taler withdrawal': [
+        'Chiudi il ritiro Taler'
+      ],
+      'Bank account balance:': [
+        'Bilancio:'
+      ],
+      'Latest transactions:': [
+        'Ultime transazioni:'
+      ],
+      'Transfer money manually': [
+        'Effettua un bonifico'
+      ],
+      'List of public accounts was not found.': [
+        'Lista conti pubblici non trovata.'
+      ],
+      'List of public accounts could not be retrieved.': [
+        'Lista conti pubblici non pervenuta.'
+      ],
+      'History of public accounts': [
+        'Storico dei conti pubblici'
+      ],
+      'Page has a problem: logged in but backend state is lost.': [
+        'Stato inconsistente: accesso utente effettuato ma stato con server 
perso.'
+      ],
+      'Welcome to the euFin bank!': [
+        'Benvenuti in banca euFin!'
+      ],
+      '': {
+        'domain': 'messages',
+        'plural_forms': 'nplurals=2; plural=(n != 1);',
+        'lang': 'it'
+      }
+    }
+  }
+};
+
diff --git a/packages/demobank-ui/src/index.tsx 
b/packages/demobank-ui/src/index.tsx
new file mode 100644
index 000000000..a2f7b30f8
--- /dev/null
+++ b/packages/demobank-ui/src/index.tsx
@@ -0,0 +1,3 @@
+import App from './components/app';
+
+export default App;
diff --git a/packages/demobank-ui/src/manifest.json 
b/packages/demobank-ui/src/manifest.json
new file mode 100644
index 000000000..feca12a0e
--- /dev/null
+++ b/packages/demobank-ui/src/manifest.json
@@ -0,0 +1,21 @@
+{
+  "name": "taler-bank",
+  "short_name": "taler-bank",
+  "start_url": "/",
+  "display": "standalone",
+  "orientation": "portrait",
+  "background_color": "#fff",
+  "theme_color": "#673ab8",
+  "icons": [
+    {
+      "src": "/assets/icons/android-chrome-192x192.png",
+      "type": "image/png",
+      "sizes": "192x192"
+    },
+    {
+      "src": "/assets/icons/android-chrome-512x512.png",
+      "type": "image/png",
+      "sizes": "512x512"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/packages/demobank-ui/src/pages/home/index.tsx 
b/packages/demobank-ui/src/pages/home/index.tsx
new file mode 100644
index 000000000..bf9764b78
--- /dev/null
+++ b/packages/demobank-ui/src/pages/home/index.tsx
@@ -0,0 +1,2018 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+import useSWR, { SWRConfig as _SWRConfig, useSWRConfig } from 'swr';
+import { h, Fragment, VNode, createContext } from 'preact';
+import { useRef, useState, useEffect, StateUpdater, useContext } from 
'preact/hooks';
+import { Buffer } from 'buffer';
+import { useTranslator, Translate } from '../../i18n';
+import { QR } from '../../components/QR';
+import { useNotNullLocalStorage, useLocalStorage } from '../../hooks';
+import '../../scss/main.scss';
+import talerLogo from '../../assets/logo-white.svg';
+import { LangSelectorLikePy as LangSelector } from 
'../../components/menu/LangSelector';
+
+// FIXME: Fix usages of SWRConfig, doing this isn't the best practice (but 
hey, it works for now)
+const SWRConfig = _SWRConfig as any;
+
+const UI_ALLOW_REGISTRATIONS = ('__LIBEUFIN_UI_ALLOW_REGISTRATIONS__') ?? 1;
+const UI_IS_DEMO = ('__LIBEUFIN_UI_IS_DEMO__') ?? 0;
+const UI_BANK_NAME = ('__LIBEUFIN_UI_BANK_NAME__') ?? 'Taler Bank';
+
+/**
+ * FIXME:
+ *
+ * - INPUT elements have their 'required' attribute ignored.
+ *
+ * - the page needs a "home" button that either redirects to
+ *   the profile page (when the user is logged in), or to
+ *   the very initial home page.
+ *
+ * - histories 'pages' are grouped in UL elements that cause
+ *   the rendering to visually separate each UL.  History elements
+ *   should instead line up without any separation caused by
+ *   a implementation detail.
+ *
+ * - Many strings need to be i18n-wrapped.
+ */
+
+/***********
+ * Globals *
+ **********/
+
+/************
+ * Contexts *
+ ***********/
+const CurrencyContext = createContext<any>(null);
+const PageContext = createContext<any>(null);
+
+/**********************************************
+ * Type definitions for states and API calls. *
+ *********************************************/
+
+/**
+ * Has the information to reach and
+ * authenticate at the bank's backend.
+ */
+interface BackendStateType {
+  url: string;
+  username: string;
+  password: string;
+}
+
+/**
+ * Request body of POST /transactions.
+ *
+ * If the amount appears twice: both as a Payto parameter and
+ * in the JSON dedicate field, the one on the Payto URI takes
+ * precedence.
+ */
+interface TransactionRequestType {
+  paytoUri: string;
+  amount?: string; // with currency.
+}
+
+/**
+ * Request body of /register.
+ */
+interface CredentialsRequestType {
+  username: string;
+  password: string;
+}
+
+/**
+ * Request body of /register.
+ */
+interface LoginRequestType {
+  username: string;
+  password: string;
+}
+
+interface WireTransferRequestType {
+  iban: string;
+  subject: string;
+  amount: string;
+}
+
+interface Amount {
+  value: string;
+  currency: string;
+}
+
+/**
+ * Track page state.
+ */
+interface PageStateType {
+  isLoggedIn: boolean;
+  isRawPayto: boolean;
+  tryRegister: boolean;
+  showPublicHistories: boolean;
+  hasError: boolean;
+  hasInfo: boolean;
+  withdrawalInProgress: boolean;
+  error?: string;
+  info?: string;
+  talerWithdrawUri?: string;
+  /**
+   * Not strictly a presentational value, could
+   * be moved in a future "withdrawal state" object.
+   */
+  withdrawalId?: string;
+}
+
+/**
+ * Bank account specific information.
+ */
+interface AccountStateType {
+  balance: string;
+  /* FIXME: Need history here.  */
+}
+
+/************
+ * Helpers. *
+ ***********/
+
+function maybeDemoContent(content: VNode) {
+  if (UI_IS_DEMO) return content;
+}
+
+async function fetcher(url: string) {
+  return fetch(url).then((r) => (r.json()));
+}
+
+function genCaptchaNumbers(): string {
+  return `${Math.floor(Math.random() * 10)} + ${Math.floor(Math.random() * 
10)}`;
+}
+/**
+ * Bring the state to show the public accounts page.
+ */
+function goPublicAccounts(pageStateSetter: StateUpdater<PageStateType>) {
+  return () => pageStateSetter((prevState) => ({ ...prevState, 
showPublicHistories: true }))
+}
+
+/**
+ * Validate (the number part of) an amount.  If needed,
+ * replace comma with a dot.  Returns 'false' whenever
+ * the input is invalid, the valid amount otherwise.
+ */
+function validateAmount(maybeAmount: string): any {
+  const amountRegex = '^[0-9]+(\.[0-9]+)?$';
+  if (!maybeAmount) {
+    console.log(`Entered amount (${maybeAmount}) mismatched <input> pattern.`);
+    return;
+  }
+  if (typeof maybeAmount !== 'undefined' || maybeAmount !== '') {
+    console.log(`Maybe valid amount: ${maybeAmount}`);
+    // tolerating comma instead of point.
+    const re = RegExp(amountRegex)
+    if (!re.test(maybeAmount)) {
+      console.log(`Not using invalid amount '${maybeAmount}'.`);
+      return false;
+    }
+  }
+  return maybeAmount;
+}
+
+/**
+ * Extract IBAN from a Payto URI.
+ */
+function getIbanFromPayto(url: string): string {
+  const pathSplit = new URL(url).pathname.split('/');
+  let lastIndex = pathSplit.length - 1;
+  // Happens if the path ends with "/".
+  if (pathSplit[lastIndex] === '') lastIndex--;
+  const iban = pathSplit[lastIndex];
+  return iban;
+}
+
+/**
+ * Extract value and currency from a $currency:x.y amount.
+ */
+function parseAmount(val: string): Amount {
+  const format = /^[A-Z]+:[0-9]+(\.[0-9]+)?$/;
+  if (!format.test(val))
+    throw Error(`Backend gave invalid amount: ${val}.`)
+  const amountSplit = val.split(':');
+  return { value: amountSplit[1], currency: amountSplit[0] }
+}
+
+/**
+ * Get username from the backend state, and throw
+ * exception if not found.
+ */
+function getUsername(backendState: BackendStateTypeOpt): string {
+  if (typeof backendState === 'undefined')
+    throw Error('Username can\'t be found in a undefined backend state.')
+
+  return backendState.username;
+}
+
+/**
+ * Helps extracting the credentials from the state
+ * and wraps the actual call to 'fetch'.  Should be
+ * enclosed in a try-catch block by the caller.
+ */
+async function postToBackend(
+  uri: string,
+  backendState: BackendStateTypeOpt,
+  body: string
+): Promise<any> {
+  if (typeof backendState === 'undefined')
+    throw Error('Credentials can\'t be found in a undefined backend state.')
+
+  const { username, password } = backendState;
+  const headers = prepareHeaders(username, password);
+  // Backend URL must have been stored _with_ a final slash.
+  const url = new URL(uri, backendState.url)
+  return await fetch(url.href, {
+    method: 'POST',
+    headers,
+    body,
+  }
+  );
+}
+
+function useTransactionPageNumber(): [number, StateUpdater<number>] {
+  const ret = useNotNullLocalStorage('transaction-page', '0');
+  const retObj = JSON.parse(ret[0]);
+  const retSetter: StateUpdater<number> = function (val) {
+    const newVal = val instanceof Function ? JSON.stringify(val(retObj)) : 
JSON.stringify(val)
+    ret[1](newVal)
+  }
+  return [retObj, retSetter];
+}
+
+/**
+ * Craft headers with Authorization and Content-Type.
+ */
+function prepareHeaders(username: string, password: string) {
+  const headers = new Headers();
+  headers.append(
+    'Authorization',
+    `Basic ${Buffer.from(`${username}:${password}`).toString('base64')}`
+  );
+  headers.append(
+    'Content-Type',
+    'application/json'
+  )
+  return headers;
+}
+
+// Window can be mocked this way:
+// 
https://gist.github.com/theKashey/07090691c0a4680ed773375d8dbeebc1#file-webpack-conf-js
+// That allows the app to be pointed to a arbitrary
+// euFin backend when launched via "pnpm dev".
+const getRootPath = () => {
+  const maybeRootPath = typeof window !== undefined
+    ? window.location.origin + window.location.pathname
+    : '/';
+  if (!maybeRootPath.endsWith('/')) return `${maybeRootPath}/`;
+  return maybeRootPath;
+};
+
+/*******************
+ * State managers. *
+ ******************/
+
+/**
+ * Stores in the state a object containing a 'username'
+ * and 'password' field, in order to avoid losing the
+ * handle of the data entered by the user in <input> fields.
+ */
+function useShowPublicAccount(
+  state?: string
+): [string | undefined, StateUpdater<string | undefined>] {
+
+  const ret = useLocalStorage('show-public-account', JSON.stringify(state));
+  const retObj: string | undefined = ret[0] ? JSON.parse(ret[0]) : ret[0];
+  const retSetter: StateUpdater<string | undefined> = function (val) {
+    const newVal = val instanceof Function ? JSON.stringify(val(retObj)) : 
JSON.stringify(val)
+    ret[1](newVal)
+  }
+  return [retObj, retSetter]
+}
+
+/**
+ * Stores the raw Payto value entered by the user in the state.
+ */
+type RawPaytoInputType = string;
+type RawPaytoInputTypeOpt = RawPaytoInputType | undefined;
+function useRawPaytoInputType(
+  state?: RawPaytoInputType
+): [RawPaytoInputTypeOpt, StateUpdater<RawPaytoInputTypeOpt>] {
+
+  const ret = useLocalStorage('raw-payto-input-state', state);
+  const retObj: RawPaytoInputTypeOpt = ret[0];
+  const retSetter: StateUpdater<RawPaytoInputTypeOpt> = function (val) {
+    const newVal = val instanceof Function ? val(retObj) : val
+    ret[1](newVal)
+  }
+  return [retObj, retSetter]
+}
+
+/**
+ * Stores in the state a object representing a wire transfer,
+ * in order to avoid losing the handle of the data entered by
+ * the user in <input> fields.  FIXME: name not matching the
+ * purpose, as this is not a HTTP request body but rather the
+ * state of the <input>-elements.
+ */
+type WireTransferRequestTypeOpt = WireTransferRequestType | undefined;
+function useWireTransferRequestType(
+  state?: WireTransferRequestType
+): [WireTransferRequestTypeOpt, StateUpdater<WireTransferRequestTypeOpt>] {
+
+  const ret = useLocalStorage('wire-transfer-request-state', 
JSON.stringify(state));
+  const retObj: WireTransferRequestTypeOpt = ret[0] ? JSON.parse(ret[0]) : 
ret[0];
+  const retSetter: StateUpdater<WireTransferRequestTypeOpt> = function (val) {
+    const newVal = val instanceof Function ? JSON.stringify(val(retObj)) : 
JSON.stringify(val)
+    ret[1](newVal)
+  }
+  return [retObj, retSetter]
+}
+
+/**
+ * Stores in the state a object containing a 'username'
+ * and 'password' field, in order to avoid losing the
+ * handle of the data entered by the user in <input> fields.
+ */
+type CredentialsRequestTypeOpt = CredentialsRequestType | undefined;
+function useCredentialsRequestType(
+  state?: CredentialsRequestType
+): [CredentialsRequestTypeOpt, StateUpdater<CredentialsRequestTypeOpt>] {
+
+  const ret = useLocalStorage('credentials-request-state', 
JSON.stringify(state));
+  const retObj: CredentialsRequestTypeOpt = ret[0] ? JSON.parse(ret[0]) : 
ret[0];
+  const retSetter: StateUpdater<CredentialsRequestTypeOpt> = function (val) {
+    const newVal = val instanceof Function ? JSON.stringify(val(retObj)) : 
JSON.stringify(val)
+    ret[1](newVal)
+  }
+  return [retObj, retSetter]
+}
+
+/**
+ * Return getters and setters for
+ * login credentials and backend's
+ * base URL.
+ */
+type BackendStateTypeOpt = BackendStateType | undefined;
+function useBackendState(
+  state?: BackendStateType
+): [BackendStateTypeOpt, StateUpdater<BackendStateTypeOpt>] {
+
+  const ret = useLocalStorage('backend-state', JSON.stringify(state));
+  const retObj: BackendStateTypeOpt = ret[0] ? JSON.parse(ret[0]) : ret[0];
+  const retSetter: StateUpdater<BackendStateTypeOpt> = function (val) {
+    const newVal = val instanceof Function ? JSON.stringify(val(retObj)) : 
JSON.stringify(val)
+    ret[1](newVal)
+  }
+  return [retObj, retSetter]
+}
+
+/**
+ * Keep mere business information, like account balance or
+ * transactions history.
+ */
+type AccountStateTypeOpt = AccountStateType | undefined;
+function useAccountState(
+  state?: AccountStateType
+): [AccountStateTypeOpt, StateUpdater<AccountStateTypeOpt>] {
+
+  const ret = useLocalStorage('account-state', JSON.stringify(state));
+  const retObj: AccountStateTypeOpt = ret[0] ? JSON.parse(ret[0]) : ret[0];
+  const retSetter: StateUpdater<AccountStateTypeOpt> = function (val) {
+    const newVal = val instanceof Function ? JSON.stringify(val(retObj)) : 
JSON.stringify(val)
+    ret[1](newVal)
+  }
+  return [retObj, retSetter]
+}
+
+/**
+ * Wrapper providing defaults.
+ */
+function usePageState(
+  state: PageStateType = {
+    isLoggedIn: false,
+    isRawPayto: false,
+    tryRegister: false,
+    showPublicHistories: false,
+    hasError: false,
+    hasInfo: false,
+    withdrawalInProgress: false,
+  }
+): [PageStateType, StateUpdater<PageStateType>] {
+  const ret = useNotNullLocalStorage('page-state', JSON.stringify(state));
+  const retObj: PageStateType = JSON.parse(ret[0]);
+  console.log('Current page state', retObj);
+  const retSetter: StateUpdater<PageStateType> = function (val) {
+    const newVal = val instanceof Function ? JSON.stringify(val(retObj)) : 
JSON.stringify(val)
+    console.log('Setting new page state', newVal)
+    ret[1](newVal)
+  }
+  return [retObj, retSetter];
+}
+
+/**
+ * Request preparators.
+ *
+ * These functions aim at sanitizing the input received
+ * from users - for example via a HTML form - and create
+ * a HTTP request object out of that.
+ */
+
+/******************
+ * HTTP wrappers. *
+ *****************/
+
+/**
+ * A 'wrapper' is typically a function that prepares one
+ * particular API call and updates the state accordingly.  */
+
+/**
+ * Abort a withdrawal operation via the Access API's /abort.
+ */
+async function abortWithdrawalCall(
+  backendState: BackendStateTypeOpt,
+  withdrawalId: string | undefined,
+  pageStateSetter: StateUpdater<PageStateType>
+) {
+  if (typeof backendState === 'undefined') {
+    console.log('No credentials found.');
+    pageStateSetter((prevState) => ({ ...prevState, hasError: true, error: 'No 
credentials found.' }))
+    return;
+  }
+  if (typeof withdrawalId === 'undefined') {
+    console.log('No withdrawal ID found.');
+    pageStateSetter((prevState) => ({ ...prevState, hasError: true, error: 'No 
withdrawal ID found.' }))
+    return;
+  }
+  let res:any;
+  try {
+    const { username, password } = backendState;
+    const headers = prepareHeaders(username, password);
+    /**
+     * NOTE: tests show that when a same object is being
+     * POSTed, caching might prevent same requests from being
+     * made.  Hence, trying to POST twice the same amount might
+     * get silently ignored.  Needs more observation!
+     *
+     * headers.append("cache-control", "no-store");
+     * headers.append("cache-control", "no-cache");
+     * headers.append("pragma", "no-cache");
+     * */
+
+    // Backend URL must have been stored _with_ a final slash.
+    const url = new URL(
+      
`access-api/accounts/${backendState.username}/withdrawals/${withdrawalId}/abort`,
+      backendState.url
+    )
+    res = await fetch(url.href, { method: 'POST', headers })
+  } catch (error) {
+    console.log('Could not abort the withdrawal', error);
+    pageStateSetter((prevState) => ({
+      ...prevState,
+      hasError: true,
+      error: `Could not abort the withdrawal: ${error}`
+    }))
+    return;
+  }
+  if (!res.ok) {
+    console.log(`Withdrawal abort gave response error (${res.status})`, 
res.statusText);
+    pageStateSetter((prevState) => ({
+      ...prevState,
+      hasError: true,
+      error: `Withdrawal abortion gave response error (${res.status})`
+    }))
+    return;
+  }
+  console.log('Withdrawal operation aborted!');
+  pageStateSetter((prevState) => {
+    const { ...rest } = prevState;
+    return {
+      ...rest,
+      info: 'Withdrawal aborted!'
+    }
+  })
+
+}
+
+/**
+ * This function confirms a withdrawal operation AFTER
+ * the wallet has given the exchange's payment details
+ * to the bank (via the Integration API).  Such details
+ * can be given by scanning a QR code or by passing the
+ * raw taler://withdraw-URI to the CLI wallet.
+ *
+ * This function will set the confirmation status in the
+ * 'page state' and let the related components refresh.
+ */
+async function confirmWithdrawalCall(
+  backendState: BackendStateTypeOpt,
+  withdrawalId: string | undefined,
+  pageStateSetter: StateUpdater<PageStateType>
+) {
+
+  if (typeof backendState === 'undefined') {
+    console.log('No credentials found.');
+    pageStateSetter((prevState) => ({ ...prevState, hasError: true, error: 'No 
credentials found.' }))
+    return;
+  }
+  if (typeof withdrawalId === 'undefined') {
+    console.log('No withdrawal ID found.');
+    pageStateSetter((prevState) => ({ ...prevState, hasError: true, error: 'No 
withdrawal ID found.' }))
+    return;
+  }
+  let res: Response;
+  try {
+    const { username, password } = backendState;
+    const headers = prepareHeaders(username, password);
+    /**
+     * NOTE: tests show that when a same object is being
+     * POSTed, caching might prevent same requests from being
+     * made.  Hence, trying to POST twice the same amount might
+     * get silently ignored.
+     *
+     * headers.append("cache-control", "no-store");
+     * headers.append("cache-control", "no-cache");
+     * headers.append("pragma", "no-cache");
+     * */
+
+    // Backend URL must have been stored _with_ a final slash.
+    const url = new URL(
+      
`access-api/accounts/${backendState.username}/withdrawals/${withdrawalId}/confirm`,
+      backendState.url
+    )
+    res = await fetch(url.href, {
+      method: 'POST',
+      headers
+    })
+  } catch (error) {
+    console.log('Could not POST withdrawal confirmation to the bank', error);
+    pageStateSetter((prevState) => ({
+      ...prevState,
+      hasError: true,
+      error: `Could not confirm the withdrawal: ${error}`
+    }))
+    return;
+  }
+  if (res ? !res.ok : true) { // assume not ok if res is null
+    console.log(`Withdrawal confirmation gave response error (${res.status})`, 
res.statusText);
+    pageStateSetter((prevState) => ({
+      ...prevState,
+      hasError: true,
+      error: `Withdrawal confirmation gave response error (${res.status})`
+    }))
+    return;
+  }
+  console.log('Withdrawal operation confirmed!');
+  pageStateSetter((prevState) => {
+    const { talerWithdrawUri, ...rest } = prevState;
+    return {
+      ...rest,
+      info: 'Withdrawal confirmed!'
+    }
+  })
+
+}
+
+/**
+ * This function creates a new transaction.  It reads a Payto
+ * address entered by the user and POSTs it to the bank.  No
+ * sanity-check of the input happens before the POST as this is
+ * already conducted by the backend.
+ */
+async function createTransactionCall(
+  req: TransactionRequestType,
+  backendState: BackendStateTypeOpt,
+  pageStateSetter: StateUpdater<PageStateType>,
+  /**
+   * Optional since the raw payto form doesn't have
+   * a stateful management of the input data yet.
+   */
+  cleanUpForm: () => void
+) {
+  let res:any;
+  try {
+    res = await postToBackend(
+      `access-api/accounts/${getUsername(backendState)}/transactions`,
+      backendState,
+      JSON.stringify(req)
+    )
+  }
+  catch (error) {
+    console.log('Could not POST transaction request to the bank', error);
+    pageStateSetter((prevState) => ({
+      ...prevState,
+      hasError: true,
+      error: `Could not create the wire transfer: ${error}`
+    }))
+    return;
+  }
+  // POST happened, status not sure yet.
+  if (!res.ok) {
+    const responseText = JSON.stringify(await res.json());
+    console.log(`Transfer creation gave response error: ${responseText} 
(${res.status})`);
+    pageStateSetter((prevState) => ({
+      ...prevState,
+      hasError: true,
+      error: `Transfer creation gave response error: ${responseText} 
(${res.status})`
+    }))
+    return;
+  }
+  // status is 200 OK here, tell the user.
+  console.log('Wire transfer created!');
+  pageStateSetter((prevState) => ({
+    ...prevState,
+    hasInfo: true,
+    info: 'Wire transfer created!'
+  }))
+
+  // Only at this point the input data can
+  // be discarded.
+  cleanUpForm();
+}
+
+/**
+ * This function creates a withdrawal operation via the Access API.
+ *
+ * After having successfully created the withdrawal operation, the
+ * user should receive a QR code of the "taler://withdraw/" type and
+ * supposed to scan it with their phone.
+ *
+ * TODO: (1) after the scan, the page should refresh itself and inform
+ * the user about the operation's outcome.  (2) use POST helper.  */
+async function createWithdrawalCall(
+  amount: string,
+  backendState: BackendStateTypeOpt,
+  pageStateSetter: StateUpdater<PageStateType>
+) {
+  if (typeof backendState === 'undefined') {
+    console.log('Page has a problem: no credentials found in the state.');
+    pageStateSetter((prevState) => ({ ...prevState, hasError: true, error: 'No 
credentials given.' }))
+    return;
+  }
+
+  let res:any;
+  try {
+    const { username, password } = backendState;
+    const headers = prepareHeaders(username, password);
+
+    // Let bank generate withdraw URI:
+    const url = new URL(
+      `access-api/accounts/${backendState.username}/withdrawals`,
+      backendState.url
+    )
+    res = await fetch(url.href, {
+      method: 'POST',
+      headers,
+      body: JSON.stringify({ amount }),
+    }
+    );
+  } catch (error) {
+    console.log('Could not POST withdrawal request to the bank', error);
+    pageStateSetter((prevState) => ({
+      ...prevState,
+      hasError: true,
+      error: `Could not create withdrawal operation: ${error}`
+    }))
+    return;
+  }
+  if (!res.ok) {
+    const responseText = await res.text();
+    console.log(`Withdrawal creation gave response error: ${responseText} 
(${res.status})`);
+    pageStateSetter((prevState) => ({
+      ...prevState,
+      hasError: true,
+      error: `Withdrawal creation gave response error: ${responseText} 
(${res.status})`
+    }))
+    return;
+  }
+
+  console.log('Withdrawal operation created!');
+  const resp = await res.json();
+  pageStateSetter((prevState: PageStateType) => ({
+    ...prevState,
+    withdrawalInProgress: true,
+    talerWithdrawUri: resp.taler_withdraw_uri,
+    withdrawalId: resp.withdrawal_id
+  }))
+}
+
+async function loginCall(
+  req: CredentialsRequestType,
+  /**
+   * FIXME: figure out if the two following
+   * functions can be retrieved from the state.
+   */
+  backendStateSetter: StateUpdater<BackendStateTypeOpt>,
+  pageStateSetter: StateUpdater<PageStateType>
+) {
+
+  /**
+   * Optimistically setting the state as 'logged in', and
+   * let the Account component request the balance to check
+   * whether the credentials are valid.  */
+  pageStateSetter((prevState) => ({ ...prevState, isLoggedIn: true }));
+  let baseUrl = getRootPath();
+  if (!baseUrl.endsWith('/'))
+    baseUrl += '/';
+
+  backendStateSetter((prevState) => ({
+    ...prevState,
+    url: baseUrl,
+    username: req.username,
+    password: req.password,
+  }));
+}
+
+
+/**
+ * This function requests /register.
+ *
+ * This function is responsible to change two states:
+ * the backend's (to store the login credentials) and
+ * the page's (to indicate a successful login or a problem).
+ */
+async function registrationCall(
+  req: CredentialsRequestType,
+  /**
+   * FIXME: figure out if the two following
+   * functions can be retrieved somewhat from
+   * the state.
+   */
+  backendStateSetter: StateUpdater<BackendStateTypeOpt>,
+  pageStateSetter: StateUpdater<PageStateType>
+) {
+
+  let baseUrl = getRootPath();
+  /**
+   * If the base URL doesn't end with slash and the path
+   * is not empty, then the concatenation made by URL()
+   * drops the last path element.
+   */
+  if (!baseUrl.endsWith('/'))
+    baseUrl += '/'
+
+  const headers = new Headers();
+  headers.append(
+    'Content-Type',
+    'application/json'
+  )
+  const url = new URL('access-api/testing/register', baseUrl)
+  let res:any;
+  try {
+    res = await fetch(url.href, {
+      method: 'POST',
+      body: JSON.stringify(req),
+      headers
+    });
+  } catch (error) {
+    console.log(`Could not POST new registration to the bank (${url.href})`, 
error);
+    pageStateSetter((prevState) => ({
+      ...prevState, hasError: true, error: 'Registration failed, please 
report.'
+    }));
+    return;
+  }
+  if (!res.ok) {
+    const errorRaw = await res.text();
+    console.log(`New registration gave response error (${res.status})`, 
errorRaw);
+    pageStateSetter((prevState) => ({
+      ...prevState,
+      hasError: true,
+      error: errorRaw
+    }));
+  } else {
+    pageStateSetter((prevState) => ({
+      ...prevState,
+      isLoggedIn: true,
+      tryRegister: false
+    }));
+    backendStateSetter((prevState) => ({
+      ...prevState,
+      url: baseUrl,
+      username: req.username,
+      password: req.password,
+    }));
+  }
+}
+
+/**************************
+ * Functional components. *
+ *************************/
+
+function Currency(): VNode {
+  const { data, error } = useSWR(`${getRootPath()}integration-api/config`, 
fetcher);
+  if (typeof error !== 'undefined')
+    return <b>error: currency could not be retrieved</b>;
+
+  if (typeof data === 'undefined') return <Fragment>"..."</Fragment>;
+  console.log('found bank config', data);
+  return data.currency;
+}
+
+function ErrorBanner(Props: any): VNode | null {
+  const [pageState, pageStateSetter] = Props.pageState;
+  const i18n = useTranslator();
+  if (!pageState.hasError) return null;
+
+  const rval = (
+    <p class="informational informational-fail">{pageState.error}
+    </p>);
+  delete pageState.error;
+  pageState.hasError = false;
+  return rval;
+}
+
+function StatusBanner(Props: any): VNode | null {
+  const [pageState, pageStateSetter] = Props.pageState;
+  const i18n = useTranslator();
+  if (!pageState.hasInfo) return null;
+
+  const rval = (
+    <p class="informational">{pageState.error}
+    </p>);
+  delete pageState.info_msg;
+  pageState.hasInfo = false;
+  return rval;
+}
+
+function BankFrame(Props: any): VNode {
+  const i18n = useTranslator();
+  const [pageState, pageStateSetter] = useContext(PageContext);
+  console.log('BankFrame state', pageState);
+  const logOut = (
+    <div class="logout">
+      <a
+        href="#"
+        class="pure-button logout-button"
+        onClick={() => {
+          pageStateSetter((prevState: PageStateType) => {
+            const {
+              talerWithdrawUri,
+              withdrawalId, ...rest } = prevState;
+            return {
+              ...rest,
+              isLoggedIn: false,
+              withdrawalInProgress: false,
+              hasInfo: false,
+              hasError: false,
+              isRawPayto: false
+            };
+          });
+        }}>{i18n`Logout`}</a></div>);
+
+  // Prepare demo sites links.
+  const DEMO_SITES = [
+    ['Landing', '__DEMO_SITE_LANDING_URL__'],
+    ['Bank', '__DEMO_SITE_BANK_URL__'],
+    ['Essay Shop', '__DEMO_SITE_BLOG_URL__'],
+    ['Donations', '__DEMO_SITE_DONATIONS_URL__'],
+    ['Survey', '__DEMO_SITE_SURVEY_URL__'],
+  ];
+  const demo_sites = [];
+  for (const i in DEMO_SITES)
+    demo_sites.push(<a href={DEMO_SITES[i][1]}>{DEMO_SITES[i][0]}</a>)
+
+  return (
+    <Fragment>
+      <header class="demobar" style="display: flex; flex-direction: row; 
justify-content: space-between;">
+        <a href="#main" class="skip">{i18n`Skip to main content`}</a>
+        <div style="max-width: 50em; margin-left: 2em;">
+          <h1>
+            <span class="it">
+              <a href="/">{
+                UI_BANK_NAME
+              }
+              </a>
+            </span>
+          </h1>{
+            maybeDemoContent(<p><Translate>
+              This part of the demo shows how a bank that supports
+              Taler directly would work. In addition to using your own
+              bank account, you can also see the transaction history of
+              some <a href="#" 
onClick={goPublicAccounts(pageStateSetter)}>Public Accounts</a>.
+            </Translate></p>
+            )
+          }
+        </div>
+        <a href="https://taler.net/";>
+          <img
+            src={talerLogo}
+            alt="{i18n`Taler logo`}"
+            height="100"
+            width="224"
+            style="margin: 2em 2em" />
+        </a>
+      </header>
+      <div style="display:flex; flex-direction: column;" class="navcontainer">
+        <nav class="demolist">
+          {maybeDemoContent(<Fragment>{demo_sites}</Fragment>)}
+          <div class="right">
+            <LangSelector />
+          </div>
+        </nav>
+      </div>
+      <section id="main" class="content">
+        <ErrorBanner pageState={[pageState, pageStateSetter]} />
+        <StatusBanner pageState={[pageState, pageStateSetter]} />
+        {pageState.isLoggedIn ? logOut : null}
+        {Props.children}
+      </section>
+      <section id="footer" class="footer">
+        <div class="footer">
+          <hr />
+          <div>
+            <p>You can learn more about GNU Taler on our <a 
href="https://taler.net";>main website</a>.</p>
+          </div>
+          <div style="flex-grow:1" />
+          <p>Copyright &copy; 2014&mdash;2022 Taler Systems SA</p>
+        </div>
+      </section>
+    </Fragment>);
+}
+
+
+function PaytoWireTransfer(Props: any): VNode {
+  const currency = useContext(CurrencyContext);
+  const [pageState, pageStateSetter] = useContext(PageContext); // NOTE: used 
for go-back button?
+  const [submitData, submitDataSetter] = useWireTransferRequestType();
+  const [rawPaytoInput, rawPaytoInputSetter] = useRawPaytoInputType();
+  const i18n = useTranslator();
+  const { focus, backendState } = Props
+  const amountRegex = '^[0-9]+(\.[0-9]+)?$';
+  const ibanRegex = '^[A-Z][A-Z][0-9]+$';
+  const receiverInput = '';
+  const subjectInput = '';
+  let transactionData: TransactionRequestType;
+  const ref = useRef<HTMLInputElement>(null)
+  useEffect(() => {
+    if (focus) ref.current?.focus();
+  }, [focus, pageState.isRawPayto]);
+
+  if (!pageState.isRawPayto)
+    return (
+      <div>
+        <div class="pure-form"
+          name="wire-transfer-form">
+          <p>
+            <label for="iban">{i18n`Receiver IBAN:`}</label>&nbsp;
+            <input
+              ref={ref}
+              type="text"
+              id="iban"
+              name="iban"
+              value={submitData?.iban}
+              placeholder="CC0123456789"
+              required
+              pattern={ibanRegex}
+              onInput={(e): void => {
+                submitDataSetter((submitData: any) => ({
+                  ...submitData,
+                  iban: e.currentTarget.value,
+                }))
+              }} /><br /><br />
+            <label for="subject">{i18n`Transfer subject:`}</label>&nbsp;
+            <input
+              type="text"
+              name="subject"
+              id="subject"
+              placeholder="subject"
+              value={submitData?.subject}
+              required
+              onInput={(e): void => {
+                submitDataSetter((submitData: any) => ({
+                  ...submitData,
+                  subject: e.currentTarget.value,
+                }))
+              }} /><br /><br />
+            <label for="amount">{i18n`Amount:`}</label>&nbsp;
+            <input
+              type="number"
+              name="amount"
+              id="amount"
+              placeholder="amount"
+              required
+              value={submitData?.amount}
+              pattern={amountRegex}
+              onInput={(e): void => {
+                submitDataSetter((submitData: any) => ({
+                  ...submitData,
+                  amount: e.currentTarget.value.replace(',', '.'),
+                }))
+              }} />
+            &nbsp;
+            <input
+              type="text"
+              readonly
+              class="currency-indicator"
+              size={currency.length}
+              maxLength={currency.length}
+              tabIndex={-1} value={currency} />
+          </p>
+          <p>
+            <input
+              type="submit"
+              class="pure-button pure-button-primary"
+              value="Send"
+              onClick={async () => {
+                if (
+                  typeof submitData === 'undefined'
+                  || (typeof submitData.iban === 'undefined'
+                    || submitData.iban === '')
+                  || (typeof submitData.subject === 'undefined'
+                    || submitData.subject === '')
+                  || (typeof submitData.amount === 'undefined'
+                    || submitData.amount === '')
+                ) {
+                  console.log('Not all the fields were given.');
+                  pageStateSetter((prevState: PageStateType) =>
+                    ({ ...prevState, hasError: true, error: i18n`Field(s) 
missing.` }))
+                  return;
+                }
+                transactionData = {
+                  paytoUri: 
`payto://iban/${submitData.iban}?message=${encodeURIComponent(submitData.subject)}`,
+                  amount: `${currency}:${submitData.amount}`
+                };
+                return await createTransactionCall(
+                  transactionData,
+                  backendState,
+                  pageStateSetter,
+                  () => submitDataSetter(p => ({
+                    amount: '',
+                    iban: '',
+                    subject: ''
+                  }))
+                );
+              }} />
+          </p>
+        </div>
+        <p><a
+          href="#"
+          onClick={() => {
+            console.log('switch to raw payto form');
+            pageStateSetter((prevState: any) => ({ ...prevState, isRawPayto: 
true }));
+          }}>{i18n`Want to try the raw payto://-format?`}
+        </a></p>
+      </div>
+    );
+
+  return (
+    <div>
+      <p>
+        {i18n`Transfer money to account identified by payto:// URI:`}
+      </p>
+      <div class="pure-form"
+        name="payto-form">
+        <p>
+          <label for="address">{i18n`payto URI:`}</label>&nbsp;
+          <input
+            name="address"
+            type="text"
+            size={90}
+            ref={ref}
+            id="address"
+            value={rawPaytoInput}
+            required
+            placeholder={i18n`payto address`}
+            pattern={`payto://iban/[A-Z][A-Z][0-9]+\?message=[a-zA-Z0-9 
]+&amount=${currency}:[0-9]+(\.[0-9]+)?`}
+            onInput={(e): void => {
+              rawPaytoInputSetter(e.currentTarget.value)
+            }} />
+          <br />
+          <div class="hint">
+            Hint:
+            <code>
+              
payto://iban/[receiver-iban]?message=[subject]&amount=[{currency}:X.Y]
+            </code>
+          </div>
+        </p>
+        <p>
+          <input class="pure-button pure-button-primary"
+            type="submit"
+            value={i18n`Send`}
+            onClick={async () => {
+              // empty string evaluates to false.
+              if (!rawPaytoInput) {
+                console.log('Didn\'t get any raw Payto string!');
+                return;
+              }
+              transactionData = { paytoUri: rawPaytoInput };
+              if (typeof transactionData.paytoUri === 'undefined' ||
+                transactionData.paytoUri.length === 0) return;
+
+              return await createTransactionCall(
+                transactionData,
+                backendState,
+                pageStateSetter,
+                () => rawPaytoInputSetter(p => '')
+              );
+            }} />
+        </p>
+        <p><a
+          href="#"
+          onClick={() => {
+            console.log('switch to wire-transfer-form');
+            pageStateSetter((prevState: any) => ({ ...prevState, isRawPayto: 
false }));
+          }}>{i18n`Use wire-transfer form?`}
+        </a></p>
+      </div>
+    </div>);
+}
+
+/**
+ * Additional authentication required to complete the operation.
+ * Not providing a back button, only abort.
+ */
+function TalerWithdrawalConfirmationQuestion(Props: any): VNode {
+  const [pageState, pageStateSetter] = useContext(PageContext);
+  const { backendState } = Props;
+  const i18n = useTranslator();
+  const captchaNumbers = {
+    a: Math.floor(Math.random() * 10),
+    b: Math.floor(Math.random() * 10)
+  }
+  let captchaAnswer = '';
+
+  return (<Fragment>
+    <h1 class="nav">{i18n`Confirm Withdrawal`}</h1>
+    <article>
+      <div class="challenge-div">
+        <form class="challenge-form">
+          <div class="pure-form"
+            id="captcha"
+            name="capcha-form">
+            <h2>{i18n`Authorize withdrawal by solving challenge`}</h2>
+            <p>
+              <label for="answer">{i18n`What 
is`}&nbsp;<em>{captchaNumbers.a}&nbsp;+&nbsp;{captchaNumbers.b}</em>?&nbsp;</label>&nbsp;
+              <input
+                name="answer"
+                id="answer"
+                type="text"
+                required
+                onInput={(e): void => {
+                  captchaAnswer = e.currentTarget.value;
+                }} />
+            </p>
+            <p>
+              <button
+                class="pure-button pure-button-primary btn-confirm"
+                onClick={() => {
+                  if (captchaAnswer == (captchaNumbers.a + 
captchaNumbers.b).toString()) {
+                    confirmWithdrawalCall(
+                      backendState,
+                      pageState.withdrawalId,
+                      pageStateSetter)
+                    return;
+                  }
+                  pageStateSetter((prevState: PageStateType) =>
+                    ({ ...prevState, hasError: true, error: i18n`Answer is 
wrong.` }))
+                }}>
+                {i18n`Confirm`}
+              </button>
+              &nbsp;
+              <button
+                class="pure-button pure-button-secondary btn-cancel"
+                onClick={() =>
+                  abortWithdrawalCall(
+                    backendState,
+                    pageState.withdrawalId,
+                    pageStateSetter
+                  )}>
+                {i18n`Cancel`}
+              </button>
+            </p>
+          </div>
+        </form>
+        <div class="hint">
+          <p><Translate>
+            A this point, a <b>real</b> bank would ask for an additional
+            authentication proof (PIN/TAN, one time password, ..), instead
+            of a simple calculation.
+          </Translate></p>
+        </div>
+      </div>
+    </article>
+  </Fragment>);
+}
+
+function QrCodeSection({ talerWithdrawUri, abortButton }: { talerWithdrawUri: 
string, abortButton: h.JSX.Element }) {
+  const i18n = useTranslator();
+  useEffect(() => {
+    //Taler Wallet WebExtension is listening to headers response and tab 
updates.
+    //In the SPA there is no header response with the Taler URI so
+    //this hack manually triggers the tab update after the QR is in the DOM.
+    window.location.href = `${window.location.href.split('#')[0]}#`
+  }, [])
+
+  return <section id="main" class="content">
+    <h1 class="nav">{i18n`Charge Taler Wallet`}</h1>
+    <p>{i18n`You can use this QR code to withdraw to your mobile wallet:`}</p>
+    {QR({ text: talerWithdrawUri })}
+    <p>Click <a id="linkqr" href={talerWithdrawUri}>{i18n`this link`}</a> to 
open your Taler wallet!</p>
+    <br />
+    {abortButton}
+  </section>
+}
+
+/**
+ * Offer the QR code (and a clickable taler://-link) to
+ * permit the passing of exchange and reserve details to
+ * the bank.  Poll the backend until such operation is done.
+ */
+function TalerWithdrawalQRCode(Props: any): VNode {
+  // turns true when the wallet POSTed the reserve details:
+  const [pageState, pageStateSetter] = useContext(PageContext);
+  const {
+    withdrawalId,
+    talerWithdrawUri,
+    accountLabel,
+    backendState } = Props;
+  const i18n = useTranslator();
+  const abortButton = <a class="pure-button" onClick={() => {
+    pageStateSetter((prevState: PageStateType) => {
+      const { withdrawalId, talerWithdrawUri, ...rest } = prevState;
+      return { ...rest, withdrawalInProgress: false };
+    })
+  }}>{i18n`Abort`}</a>
+
+  console.log(`Showing withdraw URI: ${talerWithdrawUri}`);
+  // waiting for the wallet:
+
+  const { data, error, mutate } = 
useSWR(`integration-api/withdrawal-operation/${withdrawalId}`);
+
+  if (typeof error !== 'undefined') {
+    console.log(`withdrawal (${withdrawalId}) was never (correctly) created at 
the bank...`, error);
+    pageStateSetter((prevState: PageStateType) => ({
+      ...prevState,
+      hasError: true,
+      error: i18n`withdrawal (${withdrawalId}) was never (correctly) created 
at the bank...`
+    }))
+    return (<Fragment><br /><br />{abortButton}</Fragment>);
+  }
+
+  // data didn't arrive yet and wallet didn't communicate:
+  if (typeof data === 'undefined')
+    return <p>{i18n`Waiting the bank to create the operaion...`}</p>
+
+
+  /**
+   * Wallet didn't communicate withdrawal details yet:
+   */
+  console.log('withdrawal status', data);
+  if (data.aborted)
+    pageStateSetter((prevState: PageStateType) => {
+      const {
+        withdrawalId,
+        talerWithdrawUri,
+        ...rest } = prevState;
+      return {
+        ...rest,
+        withdrawalInProgress: false,
+        hasError: true,
+        error: i18n`This withdrawal was aborted!`
+      };
+    })
+
+
+  if (!data.selection_done) {
+    setTimeout(() => mutate(), 1000); // check again after 1 second.
+    return (<QrCodeSection talerWithdrawUri={talerWithdrawUri} 
abortButton={abortButton} />);
+  }
+  /**
+   * Wallet POSTed the withdrawal details!  Ask the
+   * user to authorize the operation (here CAPTCHA).
+   */
+  return (<TalerWithdrawalConfirmationQuestion backendState={backendState} />);
+}
+
+
+
+function WalletWithdraw(Props: any): VNode {
+  const { backendState, pageStateSetter, focus } = Props;
+  const currency = useContext(CurrencyContext);
+  const i18n = useTranslator();
+  let submitAmount = '5.00';
+  const amountRegex = '^[0-9]+(\.[0-9]+)?$';
+
+  const ref = useRef<HTMLInputElement>(null)
+  useEffect(() => {
+    if (focus) ref.current?.focus();
+  }, [focus]);
+  return (
+    <div id="reserve-form"
+      class="pure-form"
+      name="tform">
+      <p>
+        <label for="withdraw-amount">{i18n`Amount to withdraw:`}</label>&nbsp;
+        <input
+          type="number"
+          ref={ref}
+          id="withdraw-amount"
+          name="withdraw-amount"
+          value={submitAmount}
+          pattern={amountRegex}
+          class="amount"
+          onChange={(e): void => {
+            // FIXME: validate using 'parseAmount()',
+            // deactivate submit button as long as
+            // amount is not valid
+            submitAmount = e.currentTarget.value;
+          }} />
+        &nbsp;
+        <input
+          type="text"
+          readonly
+          class="currency-indicator"
+          size={currency.length}
+          maxLength={currency.length}
+          tabIndex={-1} value={currency} />
+      </p>
+      <p>
+        <div>
+          <input
+            id="select-exchange"
+            class="pure-button pure-button-primary"
+            type="submit"
+            value={i18n`Withdraw`}
+            onClick={() => {
+              submitAmount = validateAmount(submitAmount);
+              /**
+               * By invalid amounts, the validator prints error messages
+               * on the console, and the browser colourizes the amount input
+               * box to indicate a error.
+               */
+              if (!submitAmount) return;
+              createWithdrawalCall(
+                `${currency}:${submitAmount}`,
+                backendState,
+                pageStateSetter
+              )
+            }} />
+        </div>
+      </p>
+    </div>
+  )
+}
+
+
+/**
+ * Let the user choose a payment option,
+ * then specify the details trigger the action.
+ */
+function PaymentOptions(Props: any): VNode {
+  const { backendState, pageStateSetter, focus } = Props;
+  const currency = useContext(CurrencyContext);
+  const i18n = useTranslator();
+
+  const [tab, setTab] = useState<'charge-wallet' | 
'wire-transfer'>('charge-wallet')
+
+
+  return (<article>
+    <div class="payments">
+      <div class="tab">
+        <button class={tab === 'charge-wallet' ? 'tablinks active' : 
'tablinks'}
+          onClick={(): void => { setTab('charge-wallet') }}>
+          {i18n`Charge Taler wallet`}
+        </button>
+        <button class={tab === 'wire-transfer' ? 'tablinks active' : 
'tablinks'}
+          onClick={(): void => { setTab('wire-transfer') }}>
+          {i18n`Wire to bank account`}
+        </button>
+      </div>
+      {tab === 'charge-wallet' &&
+        <div id='charge-wallet' class='tabcontent active'>
+          <h3>{i18n`Charge Taler wallet`}</h3>
+          <WalletWithdraw
+            backendState={backendState}
+            focus
+            pageStateSetter={pageStateSetter} />
+        </div>
+      }
+      {tab === 'wire-transfer' &&
+        <div id='wire-transfer' class='tabcontent active'>
+          <h3>{i18n`Wire to bank account`}</h3>
+          <PaytoWireTransfer
+            backendState={backendState}
+            focus
+            pageStateSetter={pageStateSetter} />
+        </div>
+      }
+    </div>
+  </article>);
+}
+
+function RegistrationButton(Props: any): VNode {
+  const { backendStateSetter, pageStateSetter } = Props;
+  const i18n = useTranslator();
+  if (UI_ALLOW_REGISTRATIONS) 
+    return (<button
+      class="pure-button pure-button-secondary btn-cancel"
+      onClick={() => {
+        pageStateSetter((prevState: PageStateType) => ({ ...prevState, 
tryRegister: true }))
+      }}>
+      {i18n`Register`}
+    </button>);
+  
+  
+  return (<span />);
+  
+}
+
+/**
+ * Collect and submit login data.
+ */
+function LoginForm(Props: any): VNode {
+  const { backendStateSetter, pageStateSetter } = Props;
+  const [submitData, submitDataSetter] = useCredentialsRequestType();
+  const i18n = useTranslator();
+  const ref = useRef<HTMLInputElement>(null)
+  useEffect(() => {
+    ref.current?.focus();
+  }, []);
+  return (<div class="login-div">
+    <form action="javascript:void(0);" class="login-form">
+      <div class="pure-form">
+        <h2>{i18n`Please login!`}</h2>
+        <p class="unameFieldLabel loginFieldLabel formFieldLabel"><label 
for="username">{i18n`Username:`}</label></p>
+        <input
+          ref={ref}
+          autoFocus
+          type="text"
+          name="username"
+          id="username"
+          value={submitData && submitData.username}
+          placeholder="Username"
+          required
+          onInput={(e): void => {
+            submitDataSetter((submitData: any) => ({
+              ...submitData,
+              username: e.currentTarget.value,
+            }))
+          }}
+        />
+        <p class="passFieldLabel loginFieldLabel formFieldLabel"><label 
for="password">{i18n`Password:`}</label></p>
+        <input
+          type="password"
+          name="password"
+          id="password"
+          value={submitData && submitData.password}
+          placeholder="Password"
+          required
+          onInput={(e): void => {
+            submitDataSetter((submitData: any) => ({
+              ...submitData,
+              password: e.currentTarget.value,
+            }))
+          }} />
+        <br />
+        <button
+          type="submit"
+          class="pure-button pure-button-primary"
+          onClick={() => {
+            if (typeof submitData === 'undefined') {
+              console.log('login data is undefined', submitData);
+              return;
+            }
+            if (submitData.password.length == 0 || submitData.username.length 
== 0) {
+              console.log('username or password is the empty string', 
submitData);
+              return;
+            }
+            loginCall(
+              // Deep copy, to avoid the cleanup
+              // below make data disappear.
+              { ...submitData },
+              backendStateSetter,
+              pageStateSetter
+            );
+            submitDataSetter(undefined);
+          }}>{i18n`Login`}
+        </button>
+        {RegistrationButton(Props)}
+      </div>
+    </form>
+  </div>);
+}
+
+/**
+ * Collect and submit registration data.
+ */
+function RegistrationForm(Props: any): VNode {
+  // eslint-disable-next-line @typescript-eslint/no-unused-vars
+  const [pageState, pageStateSetter] = useContext(PageContext);
+  const [submitData, submitDataSetter] = useCredentialsRequestType();
+  const i18n = useTranslator();
+  // 
https://stackoverflow.com/questions/36683770/how-to-get-the-value-of-an-input-field-using-reactjs
+  return (
+    <Fragment>
+      <h1 class="nav">
+        {
+          i18n`Welcome to ${UI_BANK_NAME}!`
+        }
+      </h1>
+      <article>
+        <div class="register-div">
+          <form action="javascript:void(0);" class="register-form">
+            <div class="pure-form">
+              <h2>{i18n`Please register!`}</h2>
+              <p class="unameFieldLabel registerFieldLabel 
formFieldLabel"><label for="register-un">{i18n`Username:`}</label></p>
+              <input
+                id="register-un"
+                name="register-un"
+                type="text"
+                placeholder="Username"
+                value={submitData && submitData.username}
+                required
+                onInput={(e): void => {
+                  submitDataSetter((submitData: any) => ({
+                    ...submitData,
+                    username: e.currentTarget.value,
+                  }))
+                }} />
+              <br />
+              <p class="unameFieldLabel registerFieldLabel 
formFieldLabel"><label for="register-pw">{i18n`Password:`}</label></p>
+              <input
+                type="password"
+                name="register-pw"
+                id="register-pw"
+                placeholder="Password"
+                value={submitData && submitData.password}
+                required
+                onInput={(e): void => {
+                  submitDataSetter((submitData: any) => ({
+                    ...submitData,
+                    password: e.currentTarget.value,
+                  }))
+                }} />
+              <br />
+              {/*
+              <label for="phone">{i18n`Phone number:`}</label>
+              // FIXME: add input validation (must start with +, otherwise 
only numbers)
+              <input
+                name="phone"
+                id="phone"
+                type="phone"
+                placeholder="+CC-123456789"
+                value={submitData && submitData.phone}
+                required
+                onInput={(e): void => {
+                 submitDataSetter((submitData: any) => ({
+                    ...submitData,
+                    phone: e.currentTarget.value,
+                  }))}} />
+              <br />
+              */}
+              <button
+                class="pure-button pure-button-primary btn-register"
+                onClick={() => {
+                  console.log('maybe submitting the registration..');
+                  console.log(submitData);
+                  if (typeof submitData === 'undefined') {
+                    console.log(`submit data ${submitData} is undefined`);
+                    return;
+                  }
+                  if ((typeof submitData.password === 'undefined') ||
+                    (typeof submitData.username === 'undefined')) {
+                    console.log('username or password is undefined');
+                    return;
+                  }
+                  if (submitData.password.length === 0 ||
+                    submitData.username.length === 0) {
+                    console.log('username or password are the empty string');
+                    return;
+                  }
+                  console.log('submitting the registration..');
+                  registrationCall(
+                    { ...submitData },
+                    Props.backendStateSetter, // will store BE URL, if OK.
+                    pageStateSetter
+                  );
+                  console.log('Clearing the input data');
+                  /**
+                     * FIXME: clearing the data should be done by setting
+                     * it to undefined, instead of the empty strings, just
+                     * like done in the login function.  Now set to the empty
+                     * strings due to a non lively update of the <input> fields
+                     * after setting to undefined.
+                     */
+                  submitDataSetter({ username: '', password: '' })
+                }}>
+                {i18n`Register`}
+              </button>
+              {/* FIXME: should use a different color */}
+              <button
+                class="pure-button pure-button-secondary btn-cancel"
+                onClick={() => {
+                  pageStateSetter((prevState: PageStateType) => ({ 
...prevState, tryRegister: false }))
+                }}>
+                {i18n`Cancel`}
+              </button>
+            </div>
+          </form>
+        </div>
+      </article>
+    </Fragment>
+  )
+}
+
+/**
+ * Show one page of transactions.
+ */
+function Transactions(Props: any): VNode {
+  const { pageNumber, accountLabel } = Props;
+  const i18n = useTranslator();
+  const { data, error } = useSWR(
+    `access-api/accounts/${accountLabel}/transactions?page=${pageNumber}`
+  );
+  if (typeof error !== 'undefined') {
+    console.log('transactions not found error', error);
+    switch (error.status) {
+    case 404: {
+      return <p>Transactions page {pageNumber} was not found.</p>
+    }
+    case 401: {
+      return <p>Wrong credentials given.</p>
+    }
+    default: {
+      return <p>Transaction page {pageNumber} could not be retrieved.</p>
+    }
+    }
+  }
+  if (!data) {
+    console.log(`History data of ${accountLabel} not arrived`);
+    return <p>"Transactions page loading..."</p>;
+  }
+  console.log(`History data of ${accountLabel}`, data);
+  return (<div class="results">
+    <table class="pure-table pure-table-striped">
+      <thead>
+        <tr>
+          <th>{i18n`Date`}</th>
+          <th>{i18n`Amount`}</th>
+          <th>{i18n`Counterpart`}</th>
+          <th>{i18n`Subject`}</th>
+        </tr>
+      </thead>
+      <tbody>
+        {data.transactions.map((item: any, idx: number) => {
+          const sign = item.direction == 'DBIT' ? '-' : '';
+          const counterpart = item.direction == 'DBIT' ? item.creditorIban : 
item.debtorIban;
+          // Pattern:
+          //
+          // DD/MM YYYY subject -5 EUR
+          // DD/MM YYYY subject 5 EUR
+          const dateRegex = /^([0-9]{4})-([0-9]{2})-([0-9]{1,2})/
+          const dateParse = dateRegex.exec(item.date)
+          const date = dateParse !== null ? `${dateParse[3]}/${dateParse[2]} 
${dateParse[1]}` : 'date not found'
+          return (<tr key={idx}>
+            <td>{date}</td>
+            <td>{sign}{item.amount} {item.currency}</td>
+            <td>{counterpart}</td>
+            <td>{item.subject}</td>
+          </tr>);
+        })}
+      </tbody>
+    </table>
+  </div>);
+}
+
+/**
+ * Show only the account's balance.  NOTE: the backend state
+ * is mostly needed to provide the user's credentials to POST
+ * to the bank.
+ */
+function Account(Props: any): VNode {
+  const { cache } = useSWRConfig();
+  const { accountLabel, backendState } = Props;
+  // Getting the bank account balance:
+  const endpoint = `access-api/accounts/${accountLabel}`;
+  const { data, error } = useSWR(endpoint);
+  const [pageState, pageStateSetter] = useContext(PageContext);
+  const {
+    withdrawalInProgress,
+    withdrawalId,
+    isLoggedIn,
+    talerWithdrawUri } = pageState;
+  const i18n = useTranslator();
+  /**
+   * This part shows a list of transactions: with 5 elements by
+   * default and offers a "load more" button.
+   */
+  const [txPageNumber, setTxPageNumber] = useTransactionPageNumber()
+  const txsPages = []
+  for (let i = 0; i <= txPageNumber; i++)
+    txsPages.push(<Transactions accountLabel={accountLabel} pageNumber={i} />)
+
+  if (typeof error !== 'undefined') {
+    console.log('account error', error);
+    /**
+     * FIXME: to minimize the code, try only one invocation
+     * of pageStateSetter, after having decided the error
+     * message in the case-branch.
+     */
+    switch (error.status) {
+    case 404: {
+      pageStateSetter((prevState: PageStateType) => ({
+        ...prevState,
+        hasError: true,
+        isLoggedIn: false,
+        error: i18n`Username or account label '${accountLabel}' not found.  
Won't login.`
+      }));
+
+      /**
+         * 404 should never stick to the cache, because they
+         * taint successful future registrations.  How?  After
+         * registering, the user gets navigated to this page,
+         * therefore a previous 404 on this SWR key (the requested
+         * resource) would still appear as valid and cause this
+         * page not to be shown! A typical case is an attempted
+         * login of a unregistered user X, and then a registration
+         * attempt of the same user X: in this case, the failed
+         * login would cache a 404 error to X's profile, resulting
+         * in the legitimate request after the registration to still
+         * be flagged as 404.  Clearing the cache should prevent
+         * this.  */
+      (cache as any).clear();
+      return <p>Profile not found...</p>;
+    }
+    case 401: {
+      pageStateSetter((prevState: PageStateType) => ({
+        ...prevState,
+        hasError: true,
+        isLoggedIn: false,
+        error: i18n`Wrong credentials given.`
+      }));
+      return <p>Wrong credentials...</p>;
+    }
+    default: {
+      pageStateSetter((prevState: PageStateType) => ({
+        ...prevState,
+        hasError: true,
+        isLoggedIn: false,
+        error: i18n`Account information could not be retrieved.`
+      }));
+      return <p>Unknown problem...</p>;
+    }
+    }
+  }
+  if (!data) return <p>Retrieving the profile page...</p>;
+
+  /**
+   * This block shows the withdrawal QR code.
+   *
+   * A withdrawal operation replaces everything in the page and
+   * (ToDo:) starts polling the backend until either the wallet
+   * selected a exchange and reserve public key, or a error / abort
+   * happened.
+   *
+   * After reaching one of the above states, the user should be
+   * brought to this ("Account") page where they get informed about
+   * the outcome.
+   */
+  console.log(`maybe new withdrawal ${talerWithdrawUri}`);
+  if (talerWithdrawUri) {
+    console.log('Bank created a new Taler withdrawal');
+    return (
+      <BankFrame>
+        <TalerWithdrawalQRCode
+          accountLabel={accountLabel}
+          backendState={backendState}
+          withdrawalId={withdrawalId}
+          talerWithdrawUri={talerWithdrawUri} />
+      </BankFrame>
+    );
+  }
+  const balance = parseAmount(data.balance.amount)
+
+  return (<BankFrame>
+    <div>
+      <h1 class="nav welcome-text">
+        <Translate>Welcome, {accountLabel} 
({getIbanFromPayto(data.paytoUri)})!</Translate>
+      </h1>
+    </div>
+    <section id="assets">
+      <div class="asset-summary">
+        <h2>{i18n`Bank account balance`}</h2>
+        {data.balance.credit_debit_indicator == 'debit' ? (<b>-</b>) : null}
+        <div class="large-amount amount"><span 
class="value">{`${balance.value}`}</span>&nbsp;<span 
class="currency">{`${balance.currency}`}</span></div>
+      </div>
+    </section>
+    <section id="payments">
+      <div class="payments">
+        <h2>{i18n`Payments`}</h2>
+        {/* FIXME: turn into button! */}
+        <CurrencyContext.Provider value={balance.currency}>
+          {Props.children}
+          <PaymentOptions
+            backendState={backendState}
+            pageStateSetter={pageStateSetter} />
+        </CurrencyContext.Provider>
+      </div>
+    </section>
+    <section id="main">
+      <article>
+        <h2>{i18n`Latest transactions:`}</h2>
+        <Transactions pageNumber="0" accountLabel={accountLabel} />
+      </article>
+    </section>
+  </BankFrame>);
+}
+
+/**
+ * Factor out login credentials.
+ */
+function SWRWithCredentials(props: any): VNode {
+  const { username, password, backendUrl } = props;
+  const headers = new Headers();
+  headers.append(
+    'Authorization',
+    `Basic ${Buffer.from(`${username}:${password}`).toString('base64')}`
+  );
+  console.log('Likely backend base URL', backendUrl);
+  return (
+    <SWRConfig
+      value={{
+        fetcher: (url: string) =>
+          fetch(backendUrl + url || '', { headers }).then(
+            (r) => {
+              if (!r.ok)
+                throw { status: r.status, json: r.json() };
+
+              return r.json()
+            }
+          ),
+      }}>{props.children}</SWRConfig>
+  );
+}
+
+function SWRWithoutCredentials(Props: any): VNode {
+  const { baseUrl } = Props;
+  console.log('Base URL', baseUrl);
+  return (
+    <SWRConfig
+      value={{
+        fetcher: (url: string) =>
+          fetch(baseUrl + url || '').then(
+            (r) => {
+              if (!r.ok)
+                throw { status: r.status, json: r.json() };
+
+              return r.json()
+            }
+          ),
+      }}>{Props.children}</SWRConfig>
+  );
+}
+
+/**
+ * Show histories of public accounts.
+ */
+function PublicHistories(Props: any): VNode {
+  const [showAccount, setShowAccount] = useShowPublicAccount();
+  const { data, error } = useSWR('access-api/public-accounts');
+  const i18n = useTranslator();
+
+  if (typeof error !== 'undefined') {
+    console.log('account error', error);
+    switch (error.status) {
+    case 404:
+      console.log('public accounts: 404', error);
+      Props.pageStateSetter((prevState: PageStateType) => ({
+        ...prevState,
+        hasError: true,
+        showPublicHistories: false,
+        error: i18n`List of public accounts was not found.`
+      }));
+      break;
+    default:
+      console.log('public accounts: non-404 error', error);
+      Props.pageStateSetter((prevState: PageStateType) => ({
+        ...prevState,
+        hasError: true,
+        showPublicHistories: false,
+        error: i18n`List of public accounts could not be retrieved.`
+      }));
+      break;
+    }
+  }
+  if (!data)
+    return (<p>Waiting public accounts list...</p>)
+  const txs: any = {};
+  const accountsBar = [];
+
+  /**
+   * Show the account specified in the props, or just one
+   * from the list if that's not given.
+   */
+  if (typeof showAccount === 'undefined' && data.publicAccounts.length > 0)
+    setShowAccount(data.publicAccounts[1].accountLabel);
+  console.log(`Public history tab: ${showAccount}`);
+
+  // Ask story of all the public accounts.
+  for (const account of data.publicAccounts) {
+    console.log('Asking transactions for', account.accountLabel)
+    const isSelected = account.accountLabel == showAccount;
+    accountsBar.push(
+      <li class={isSelected ? 'pure-menu-selected pure-menu-item' : 
'pure-menu-item pure-menu'}>
+        <a href="#"
+          class="pure-menu-link"
+          onClick={() => 
setShowAccount(account.accountLabel)}>{account.accountLabel}</a>
+      </li>
+    );
+    txs[account.accountLabel] = <Transactions 
accountLabel={account.accountLabel} pageNumber={0} />
+  }
+
+  return (<Fragment>
+    <h1 class="nav">{i18n`History of public accounts`}</h1>
+    <section id="main">
+      <article>
+        <div class="pure-menu pure-menu-horizontal" name="accountMenu">
+          <ul class="pure-menu-list">{accountsBar}</ul>
+          {typeof showAccount !== 'undefined' ? txs[showAccount] : <p>No 
public transactions found.</p>}
+          {Props.children}
+        </div>
+      </article>
+    </section>
+  </Fragment>);
+}
+
+/**
+ * If the user is logged in, it displays
+ * the balance, otherwise it offers to login.
+ */
+export function BankHome(): VNode {
+  const [backendState, backendStateSetter] = useBackendState();
+  const [pageState, pageStateSetter] = usePageState();
+  const [accountState, accountStateSetter] = useAccountState();
+  const setTxPageNumber = useTransactionPageNumber()[1];
+  const i18n = useTranslator();
+
+  if (pageState.showPublicHistories)
+    return (<SWRWithoutCredentials baseUrl={getRootPath()}>
+      <PageContext.Provider value={[pageState, pageStateSetter]}>
+        <BankFrame>
+          <PublicHistories pageStateSetter={pageStateSetter}>
+            <br />
+            <a class="pure-button" onClick={() => {
+              pageStateSetter((prevState: PageStateType) =>
+                ({ ...prevState, showPublicHistories: false }))
+            }}>Go back</a>
+          </PublicHistories>
+        </BankFrame>
+      </PageContext.Provider>
+    </SWRWithoutCredentials>);
+
+  if (pageState.tryRegister) {
+    console.log('allow registrations?', UI_ALLOW_REGISTRATIONS);
+    if (UI_ALLOW_REGISTRATIONS)
+      return (
+        <PageContext.Provider value={[pageState, pageStateSetter]}>
+          <BankFrame>
+            <RegistrationForm backendStateSetter={backendStateSetter} />
+          </BankFrame>
+        </PageContext.Provider>
+      );
+
+    return (
+      <PageContext.Provider value={[pageState, pageStateSetter]}>
+        <BankFrame>
+          <p>{i18n`Currently, the bank is not accepting new 
registrations!`}</p>
+        </BankFrame>
+      </PageContext.Provider>
+    );
+  }
+  if (pageState.isLoggedIn) {
+    if (typeof backendState === 'undefined') {
+      pageStateSetter((prevState) => ({
+        ...prevState,
+        hasError: true,
+        isLoggedIn: false,
+        error: i18n`Page has a problem: logged in but backend state is lost.`
+      }));
+      return (<p>Error: waiting for details...</p>);
+    }
+    console.log('Showing the profile page..');
+    return (
+      <SWRWithCredentials
+        username={backendState.username}
+        password={backendState.password}
+        backendUrl={backendState.url}>
+        <PageContext.Provider value={[pageState, pageStateSetter]}>
+          <Account accountLabel={backendState.username} 
backendState={backendState} />
+        </PageContext.Provider>
+      </SWRWithCredentials>
+    );
+  } // end of logged-in state.
+
+  return (
+    <PageContext.Provider value={[pageState, pageStateSetter]}>
+      <BankFrame>
+        <h1 class="nav">
+          {
+            i18n`Welcome to ${UI_BANK_NAME}!`
+          }
+        </h1>
+        <LoginForm
+          pageStateSetter={pageStateSetter}
+          backendStateSetter={backendStateSetter} />
+      </BankFrame>
+    </PageContext.Provider>
+  );
+}
diff --git a/packages/demobank-ui/src/pages/notfound/index.tsx 
b/packages/demobank-ui/src/pages/notfound/index.tsx
new file mode 100644
index 000000000..fd99259a1
--- /dev/null
+++ b/packages/demobank-ui/src/pages/notfound/index.tsx
@@ -0,0 +1,16 @@
+import { FunctionalComponent, h } from 'preact';
+import { Link } from 'preact-router/match';
+
+const Notfound: FunctionalComponent = () => {
+  return (
+    <div>
+      <h1>Error 404</h1>
+      <p>That page doesn&apos;t exist.</p>
+      <Link href="/">
+        <h4>Back to Home</h4>
+      </Link>
+    </div>
+  );
+};
+
+export default Notfound;
diff --git a/packages/pogen/example/proj1/src/sample.ts 
b/packages/demobank-ui/src/pages/notfound/style.css
similarity index 100%
copy from packages/pogen/example/proj1/src/sample.ts
copy to packages/demobank-ui/src/pages/notfound/style.css
diff --git a/packages/demobank-ui/src/pages/profile/index.stories.tsx 
b/packages/demobank-ui/src/pages/profile/index.stories.tsx
new file mode 100644
index 000000000..15fd7c7e5
--- /dev/null
+++ b/packages/demobank-ui/src/pages/profile/index.stories.tsx
@@ -0,0 +1,38 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h } from 'preact';
+import Profile from './index';
+
+
+export default {
+  title: 'Profile/View',
+  component: Profile,
+  argTypes: {
+    onSelect: { action: 'onSelect' },
+  },
+};
+
+export const Empty = (a: any) => <Profile {...a} />;
+Empty.args = {
+  instances: []
+}
+
diff --git a/packages/demobank-ui/src/pages/profile/index.tsx 
b/packages/demobank-ui/src/pages/profile/index.tsx
new file mode 100644
index 000000000..3b9824488
--- /dev/null
+++ b/packages/demobank-ui/src/pages/profile/index.tsx
@@ -0,0 +1,42 @@
+import { FunctionalComponent, h } from 'preact';
+import { useEffect, useState } from 'preact/hooks';
+
+interface Props {
+  user: string;
+}
+
+const Profile: FunctionalComponent<Props> = (props: Props) => {
+  const { user } = props;
+  const [time, setTime] = useState<number>(Date.now());
+  const [count, setCount] = useState<number>(0);
+
+  // gets called when this route is navigated to
+  useEffect(() => {
+    const timer = window.setInterval(() => setTime(Date.now()), 1000);
+
+    // gets called just before navigating away from the route
+    return (): void => {
+      clearInterval(timer);
+    };
+  }, []);
+
+  // update the current time
+  const increment = (): void => {
+    setCount(count + 1);
+  };
+
+  return (
+    <div>
+      <h1>Profile: {user}</h1>
+      <p>This is the user profile for a user named {user}.</p>
+
+      <div>Current time: {new Date(time).toLocaleString()}</div>
+
+      <p>
+        <button onClick={increment}>Click Me</button> Clicked {count} times.
+      </p>
+    </div>
+  );
+};
+
+export default Profile;
diff --git a/packages/pogen/example/proj1/src/sample.ts 
b/packages/demobank-ui/src/pages/profile/style.css
similarity index 100%
copy from packages/pogen/example/proj1/src/sample.ts
copy to packages/demobank-ui/src/pages/profile/style.css
diff --git a/packages/anastasis-webui/src/scss/DurationPicker.scss 
b/packages/demobank-ui/src/scss/DurationPicker.scss
similarity index 100%
copy from packages/anastasis-webui/src/scss/DurationPicker.scss
copy to packages/demobank-ui/src/scss/DurationPicker.scss
diff --git a/packages/demobank-ui/src/scss/_aside.scss 
b/packages/demobank-ui/src/scss/_aside.scss
new file mode 100644
index 000000000..11809990b
--- /dev/null
+++ b/packages/demobank-ui/src/scss/_aside.scss
@@ -0,0 +1,128 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+html {
+  &.has-aside-left {
+    &.has-aside-expanded {
+      nav.navbar,
+      body {
+        padding-left: $aside-width;
+      }
+    }
+    aside.is-placed-left {
+      display: block;
+    }
+  }
+}
+
+aside.aside.is-expanded {
+  width: $aside-width;
+
+  .menu-list {
+    @include icon-with-update-mark($aside-icon-width);
+
+    span.menu-item-label {
+      display: inline-block;
+    }
+
+    li.is-active {
+      ul {
+        display: block;
+      }
+      background-color: $body-background-color;
+    }
+  }
+}
+
+aside.aside {
+  display: none;
+  position: fixed;
+  top: 0;
+  left: 0;
+  z-index: 40;
+  height: 100vh;
+  padding: 0;
+  box-shadow: $aside-box-shadow;
+  background: $aside-background-color;
+
+  .aside-tools {
+    display: flex;
+    flex-direction: row;
+    width: 100%;
+    background-color: $aside-tools-background-color;
+    color: $aside-tools-color;
+    line-height: $navbar-height;
+    height: $navbar-height;
+    padding-left: $default-padding * 0.5;
+    flex: 1;
+
+    .icon {
+      margin-right: $default-padding * 0.5;
+    }
+  }
+
+  .menu-list {
+    li {
+      a {
+        &.has-dropdown-icon {
+          position: relative;
+          padding-right: $aside-icon-width;
+
+          .dropdown-icon {
+            position: absolute;
+            top: $size-base * 0.5;
+            right: 0;
+          }
+        }
+      }
+      ul {
+        display: none;
+        border-left: 0;
+        background-color: darken($base-color, 2.5%);
+        padding-left: 0;
+        margin: 0 0 $default-padding * 0.5;
+
+        li {
+          a {
+            padding: $default-padding * 0.5 0 $default-padding * 0.5
+              $default-padding * 0.5;
+            font-size: $aside-submenu-font-size;
+
+            &.has-icon {
+              padding-left: 0;
+            }
+            &.is-active {
+              &:not(:hover) {
+                background: transparent;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  .menu-label {
+    padding: 0 $default-padding * 0.5;
+    margin-top: $default-padding * 0.5;
+    margin-bottom: $default-padding * 0.5;
+  }
+}
diff --git a/packages/demobank-ui/src/scss/_card.scss 
b/packages/demobank-ui/src/scss/_card.scss
new file mode 100644
index 000000000..3f71aeb6a
--- /dev/null
+++ b/packages/demobank-ui/src/scss/_card.scss
@@ -0,0 +1,69 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+.card:not(:last-child) {
+  margin-bottom: $default-padding;
+}
+
+.card {
+  border-radius: $radius-large;
+  border: $card-border;
+
+  &.has-table {
+    .card-content {
+      padding: 0;
+    }
+    .b-table {
+      border-radius: $radius-large;
+      overflow: hidden;
+    }
+  }
+
+  &.is-card-widget {
+    .card-content {
+      padding: $default-padding * 0.5;
+    }
+  }
+
+  .card-header {
+    border-bottom: 1px solid $base-color-light;
+  }
+
+  .card-content {
+    hr {
+      margin-left: $card-content-padding * -1;
+      margin-right: $card-content-padding * -1;
+    }
+  }
+
+  .is-widget-icon {
+    .icon {
+      width: 5rem;
+      height: 5rem;
+    }
+  }
+
+  .is-widget-label {
+    .subtitle {
+      color: $grey;
+    }
+  }
+}
diff --git a/packages/demobank-ui/src/scss/_custom-calendar.scss 
b/packages/demobank-ui/src/scss/_custom-calendar.scss
new file mode 100644
index 000000000..e0334b62d
--- /dev/null
+++ b/packages/demobank-ui/src/scss/_custom-calendar.scss
@@ -0,0 +1,263 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+:root {
+  --primary-color: #3298dc;
+
+  --primary-text-color-dark: rgba(0, 0, 0, 0.87);
+  --secondary-text-color-dark: rgba(0, 0, 0, 0.57);
+  --disabled-text-color-dark: rgba(0, 0, 0, 0.13);
+
+  --primary-text-color-light: rgba(255, 255, 255, 0.87);
+  --secondary-text-color-light: rgba(255, 255, 255, 0.57);
+  --disabled-text-color-light: rgba(255, 255, 255, 0.13);
+
+  --font-stack: "Roboto", "Helvetica Neue", Helvetica, Arial, sans-serif;
+
+  --primary-card-color: #fff;
+  --primary-background-color: #f2f2f2;
+
+  --box-shadow-lvl-1: 0 1px 3px rgba(0, 0, 0, 0.12),
+    0 1px 2px rgba(0, 0, 0, 0.24);
+  --box-shadow-lvl-2: 0 3px 6px rgba(0, 0, 0, 0.16),
+    0 3px 6px rgba(0, 0, 0, 0.23);
+  --box-shadow-lvl-3: 0 10px 20px rgba(0, 0, 0, 0.19),
+    0 6px 6px rgba(0, 0, 0, 0.23);
+  --box-shadow-lvl-4: 0 14px 28px rgba(0, 0, 0, 0.25),
+    0 10px 10px rgba(0, 0, 0, 0.22);
+}
+
+.home .datePicker div {
+  margin-top: 0px;
+  margin-bottom: 0px;
+}
+.datePicker {
+  text-align: left;
+  background: var(--primary-card-color);
+  border-radius: 3px;
+  z-index: 200;
+  position: fixed;
+  height: auto;
+  max-height: 90vh;
+  width: 90vw;
+  max-width: 448px;
+  transform-origin: top left;
+  transition: transform 0.22s ease-in-out, opacity 0.22s ease-in-out;
+  top: 50%;
+  left: 50%;
+  opacity: 0;
+  transform: scale(0) translate(-50%, -50%);
+  user-select: none;
+
+  &.datePicker--opened {
+    opacity: 1;
+    transform: scale(1) translate(-50%, -50%);
+  }
+
+  .datePicker--titles {
+    border-top-left-radius: 3px;
+    border-top-right-radius: 3px;
+    padding: 24px;
+    height: 100px;
+    background: var(--primary-color);
+
+    h2,
+    h3 {
+      cursor: pointer;
+      color: #fff;
+      line-height: 1;
+      padding: 0;
+      margin: 0;
+      font-size: 32px;
+    }
+
+    h3 {
+      color: rgba(255, 255, 255, 0.57);
+      font-size: 18px;
+      padding-bottom: 2px;
+    }
+  }
+
+  nav {
+    padding: 20px;
+    height: 56px;
+
+    h4 {
+      width: calc(100% - 60px);
+      text-align: center;
+      display: inline-block;
+      padding: 0;
+      font-size: 14px;
+      line-height: 24px;
+      margin: 0;
+      position: relative;
+      top: -9px;
+      color: var(--primary-text-color);
+    }
+
+    i {
+      cursor: pointer;
+      color: var(--secondary-text-color);
+      font-size: 26px;
+      user-select: none;
+      border-radius: 50%;
+
+      &:hover {
+        background: var(--disabled-text-color-dark);
+      }
+    }
+  }
+
+  .datePicker--scroll {
+    overflow-y: auto;
+    max-height: calc(90vh - 56px - 100px);
+  }
+
+  .datePicker--calendar {
+    padding: 0 20px;
+
+    .datePicker--dayNames {
+      width: 100%;
+      display: grid;
+      text-align: center;
+
+      // there's probably a better way to do this, but wanted to try out CSS 
grid
+      grid-template-columns: calc(100% / 7) calc(100% / 7) calc(100% / 7) calc(
+          100% / 7
+        ) calc(100% / 7) calc(100% / 7) calc(100% / 7);
+
+      span {
+        color: var(--secondary-text-color-dark);
+        font-size: 14px;
+        line-height: 42px;
+        display: inline-grid;
+      }
+    }
+
+    .datePicker--days {
+      width: 100%;
+      display: grid;
+      text-align: center;
+      grid-template-columns: calc(100% / 7) calc(100% / 7) calc(100% / 7) calc(
+          100% / 7
+        ) calc(100% / 7) calc(100% / 7) calc(100% / 7);
+
+      span {
+        color: var(--primary-text-color-dark);
+        line-height: 42px;
+        font-size: 14px;
+        display: inline-grid;
+        transition: color 0.22s;
+        height: 42px;
+        position: relative;
+        cursor: pointer;
+        user-select: none;
+        border-radius: 50%;
+
+        &::before {
+          content: "";
+          position: absolute;
+          z-index: -1;
+          height: 42px;
+          width: 42px;
+          left: calc(50% - 21px);
+          background: var(--primary-color);
+          border-radius: 50%;
+          transition: transform 0.22s, opacity 0.22s;
+          transform: scale(0);
+          opacity: 0;
+        }
+
+        &[disabled="true"] {
+          cursor: unset;
+        }
+
+        &.datePicker--today {
+          font-weight: 700;
+        }
+
+        &.datePicker--selected {
+          color: rgba(255, 255, 255, 0.87);
+
+          &:before {
+            transform: scale(1);
+            opacity: 1;
+          }
+        }
+      }
+    }
+  }
+
+  .datePicker--selectYear {
+    padding: 0 20px;
+    display: block;
+    width: 100%;
+    text-align: center;
+    max-height: 362px;
+
+    span {
+      display: block;
+      width: 100%;
+      font-size: 24px;
+      margin: 20px auto;
+      cursor: pointer;
+
+      &.selected {
+        font-size: 42px;
+        color: var(--primary-color);
+      }
+    }
+  }
+
+  div.datePicker--actions {
+    width: 100%;
+    padding: 8px;
+    text-align: right;
+
+    button {
+      margin-bottom: 0;
+      font-size: 15px;
+      cursor: pointer;
+      color: var(--primary-text-color);
+      border: none;
+      margin-left: 8px;
+      min-width: 64px;
+      line-height: 36px;
+      background-color: transparent;
+      appearance: none;
+      padding: 0 16px;
+      border-radius: 3px;
+      transition: background-color 0.13s;
+
+      &:hover,
+      &:focus {
+        outline: none;
+        background-color: var(--disabled-text-color-dark);
+      }
+    }
+  }
+}
+
+.datePicker--background {
+  z-index: 199;
+  position: fixed;
+  top: 0;
+  left: 0;
+  bottom: 0;
+  right: 0;
+  background: rgba(0, 0, 0, 0.52);
+  animation: fadeIn 0.22s forwards;
+}
diff --git a/packages/demobank-ui/src/scss/_footer.scss 
b/packages/demobank-ui/src/scss/_footer.scss
new file mode 100644
index 000000000..112522ed8
--- /dev/null
+++ b/packages/demobank-ui/src/scss/_footer.scss
@@ -0,0 +1,35 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+footer.footer {
+  .logo {
+    img {
+      width: auto;
+      height: $footer-logo-height;
+    }
+  }
+}
+
+@include mobile {
+  .footer-copyright {
+    text-align: center;
+  }
+}
diff --git a/packages/demobank-ui/src/scss/_form.scss 
b/packages/demobank-ui/src/scss/_form.scss
new file mode 100644
index 000000000..786044eff
--- /dev/null
+++ b/packages/demobank-ui/src/scss/_form.scss
@@ -0,0 +1,71 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+.field {
+  &.has-check {
+    .field-body {
+      margin-top: $default-padding * 0.125;
+    }
+  }
+  .control {
+    .mdi-24px.mdi-set,
+    .mdi-24px.mdi:before {
+      font-size: inherit;
+    }
+  }
+}
+.upload {
+  .upload-draggable {
+    display: block;
+  }
+}
+
+.input,
+.textarea,
+select {
+  box-shadow: none;
+
+  &:focus,
+  &:active {
+    box-shadow: none !important;
+  }
+}
+
+.switch input[type="checkbox"] + .check:before {
+  box-shadow: none;
+}
+
+.switch,
+.b-checkbox.checkbox {
+  input[type="checkbox"] {
+    &:focus + .check,
+    &:focus:checked + .check {
+      box-shadow: none !important;
+    }
+  }
+}
+
+.b-checkbox.checkbox input[type="checkbox"],
+.b-radio.radio input[type="radio"] {
+  & + .check {
+    border: $checkbox-border;
+  }
+}
diff --git a/packages/demobank-ui/src/scss/_hero-bar.scss 
b/packages/demobank-ui/src/scss/_hero-bar.scss
new file mode 100644
index 000000000..31b7e623e
--- /dev/null
+++ b/packages/demobank-ui/src/scss/_hero-bar.scss
@@ -0,0 +1,55 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+section.hero.is-hero-bar {
+  background-color: $hero-bar-background;
+  border-bottom: $light-border;
+
+  .hero-body {
+    padding: $default-padding;
+
+    .level-item {
+      &.is-hero-avatar-item {
+        margin-right: $default-padding;
+      }
+
+      > div > .level {
+        margin-bottom: $default-padding * 0.5;
+      }
+
+      .subtitle + p {
+        margin-top: $default-padding * 0.5;
+      }
+    }
+
+    .button {
+      &.is-hero-button {
+        background-color: rgba($white, 0.5);
+        font-weight: 300;
+        @include transition(background-color);
+
+        &:hover {
+          background-color: $white;
+        }
+      }
+    }
+  }
+}
diff --git a/packages/demobank-ui/src/scss/_loading.scss 
b/packages/demobank-ui/src/scss/_loading.scss
new file mode 100644
index 000000000..d25bf8048
--- /dev/null
+++ b/packages/demobank-ui/src/scss/_loading.scss
@@ -0,0 +1,51 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+.lds-ring {
+  display: inline-block;
+  position: relative;
+  width: 80px;
+  height: 80px;
+}
+.lds-ring div {
+  box-sizing: border-box;
+  display: block;
+  position: absolute;
+  width: 64px;
+  height: 64px;
+  margin: 8px;
+  border: 8px solid black;
+  border-radius: 50%;
+  animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
+  border-color: black transparent transparent transparent;
+}
+.lds-ring div:nth-child(1) {
+  animation-delay: -0.45s;
+}
+.lds-ring div:nth-child(2) {
+  animation-delay: -0.3s;
+}
+.lds-ring div:nth-child(3) {
+  animation-delay: -0.15s;
+}
+@keyframes lds-ring {
+  0% {
+    transform: rotate(0deg);
+  }
+  100% {
+    transform: rotate(360deg);
+  }
+}
diff --git a/packages/demobank-ui/src/scss/_main-section.scss 
b/packages/demobank-ui/src/scss/_main-section.scss
new file mode 100644
index 000000000..01edc24bf
--- /dev/null
+++ b/packages/demobank-ui/src/scss/_main-section.scss
@@ -0,0 +1,24 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+section.section.is-main-section {
+  padding-top: $default-padding;
+}
diff --git a/packages/demobank-ui/src/scss/_misc.scss 
b/packages/demobank-ui/src/scss/_misc.scss
new file mode 100644
index 000000000..65bd28dbd
--- /dev/null
+++ b/packages/demobank-ui/src/scss/_misc.scss
@@ -0,0 +1,50 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+.is-user-avatar {
+  &.has-max-width {
+    max-width: $size-base * 7;
+  }
+
+  &.is-aligned-center {
+    margin: 0 auto;
+  }
+
+  img {
+    margin: 0 auto;
+    border-radius: $radius-rounded;
+  }
+}
+
+.icon.has-update-mark {
+  position: relative;
+
+  &:after {
+    content: "";
+    width: $icon-update-mark-size;
+    height: $icon-update-mark-size;
+    position: absolute;
+    top: 1px;
+    right: 1px;
+    background-color: $icon-update-mark-color;
+    border-radius: $radius-rounded;
+  }
+}
diff --git a/packages/demobank-ui/src/scss/_mixins.scss 
b/packages/demobank-ui/src/scss/_mixins.scss
new file mode 100644
index 000000000..b52e590e3
--- /dev/null
+++ b/packages/demobank-ui/src/scss/_mixins.scss
@@ -0,0 +1,34 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+@mixin transition($t) {
+  transition: $t 250ms ease-in-out 50ms;
+}
+
+@mixin icon-with-update-mark($icon-base-width) {
+  .icon {
+    width: $icon-base-width;
+
+    &.has-update-mark:after {
+      right: ($icon-base-width / 2) - 0.85;
+    }
+  }
+}
diff --git a/packages/demobank-ui/src/scss/_modal.scss 
b/packages/demobank-ui/src/scss/_modal.scss
new file mode 100644
index 000000000..b3a31ebf1
--- /dev/null
+++ b/packages/demobank-ui/src/scss/_modal.scss
@@ -0,0 +1,35 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+.modal-card {
+  width: $modal-card-width;
+}
+
+.modal-card-foot {
+  background-color: $modal-card-foot-background-color;
+}
+
+@include mobile {
+  .modal .animation-content .modal-card {
+    width: $modal-card-width-mobile;
+    margin: 0 auto;
+  }
+}
diff --git a/packages/demobank-ui/src/scss/_nav-bar.scss 
b/packages/demobank-ui/src/scss/_nav-bar.scss
new file mode 100644
index 000000000..c6dd04263
--- /dev/null
+++ b/packages/demobank-ui/src/scss/_nav-bar.scss
@@ -0,0 +1,144 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+nav.navbar {
+  box-shadow: $navbar-box-shadow;
+
+  .navbar-item {
+    &.has-user-avatar {
+      .is-user-avatar {
+        margin-right: $default-padding * 0.5;
+        display: inline-flex;
+        width: $navbar-avatar-size;
+        height: $navbar-avatar-size;
+      }
+    }
+
+    &.has-divider {
+      border-right: $navbar-divider-border;
+    }
+
+    &.no-left-space {
+      padding-left: 0;
+    }
+
+    &.has-dropdown {
+      padding-right: 0;
+      padding-left: 0;
+
+      .navbar-link {
+        padding-right: $navbar-item-h-padding;
+        padding-left: $navbar-item-h-padding;
+      }
+    }
+
+    &.has-control {
+      padding-top: 0;
+      padding-bottom: 0;
+    }
+
+    .control {
+      .input {
+        color: $navbar-input-color;
+        border: 0;
+        box-shadow: none;
+        background: transparent;
+
+        &::placeholder {
+          color: $navbar-input-placeholder-color;
+        }
+      }
+    }
+  }
+}
+
+@include touch {
+  nav.navbar {
+    display: flex;
+    padding-right: 0;
+
+    .navbar-brand {
+      flex: 1;
+
+      &.is-right {
+        flex: none;
+      }
+    }
+
+    .navbar-item {
+      &.no-left-space-touch {
+        padding-left: 0;
+      }
+    }
+
+    .navbar-menu {
+      position: absolute;
+      width: 100vw;
+      padding-top: 0;
+      top: $navbar-height;
+      left: 0;
+
+      .navbar-item {
+        .icon:first-child {
+          margin-right: $default-padding * 0.5;
+        }
+
+        &.has-dropdown {
+          > .navbar-link {
+            background-color: $white-ter;
+            .icon:last-child {
+              display: none;
+            }
+          }
+        }
+
+        &.has-user-avatar {
+          > .navbar-link {
+            display: flex;
+            align-items: center;
+            padding-top: $default-padding * 0.5;
+            padding-bottom: $default-padding * 0.5;
+          }
+        }
+      }
+    }
+  }
+}
+
+@include desktop {
+  nav.navbar {
+    .navbar-item {
+      padding-right: $navbar-item-h-padding;
+      padding-left: $navbar-item-h-padding;
+
+      &:not(.is-desktop-icon-only) {
+        .icon:first-child {
+          margin-right: $default-padding * 0.5;
+        }
+      }
+      &.is-desktop-icon-only {
+        span:not(.icon) {
+          display: none;
+        }
+      }
+    }
+  }
+}
diff --git a/packages/demobank-ui/src/scss/_table.scss 
b/packages/demobank-ui/src/scss/_table.scss
new file mode 100644
index 000000000..b68d50e4f
--- /dev/null
+++ b/packages/demobank-ui/src/scss/_table.scss
@@ -0,0 +1,179 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+table.table {
+  thead {
+    th {
+      border-bottom-width: 1px;
+    }
+  }
+
+  td,
+  th {
+    &.checkbox-cell {
+      .b-checkbox.checkbox:not(.button) {
+        margin-right: 0;
+        width: 20px;
+
+        .control-label {
+          display: none;
+          padding: 0;
+        }
+      }
+    }
+  }
+
+  td {
+    .image {
+      margin: 0 auto;
+      width: $table-avatar-size;
+      height: $table-avatar-size;
+    }
+
+    &.is-progress-col {
+      min-width: 5rem;
+      vertical-align: middle;
+    }
+  }
+}
+
+.b-table {
+  .table {
+    border: 0;
+    border-radius: 0;
+  }
+
+  /* This stylizes buefy's pagination */
+  .table-wrapper {
+    margin-bottom: 0;
+  }
+
+  .table-wrapper + .level {
+    padding: $notification-padding;
+    padding-left: $card-content-padding;
+    padding-right: $card-content-padding;
+    margin: 0;
+    border-top: $base-color-light;
+    background: $notification-background-color;
+
+    .pagination-link {
+      background: $button-background-color;
+      color: $button-color;
+      border-color: $button-border-color;
+
+      &.is-current {
+        border-color: $button-active-border-color;
+      }
+    }
+
+    .pagination-previous,
+    .pagination-next,
+    .pagination-link {
+      border-color: $button-border-color;
+      color: $base-color;
+
+      &[disabled] {
+        background-color: transparent;
+      }
+    }
+  }
+}
+
+@include mobile {
+  .card {
+    &.has-table {
+      .b-table {
+        .table-wrapper + .level {
+          .level-left + .level-right {
+            margin-top: 0;
+          }
+        }
+      }
+    }
+    &.has-mobile-sort-spaced {
+      .b-table {
+        .field.table-mobile-sort {
+          padding-top: $default-padding * 0.5;
+        }
+      }
+    }
+  }
+  .b-table {
+    .field.table-mobile-sort {
+      padding: 0 $default-padding * 0.5;
+    }
+
+    .table-wrapper.has-mobile-cards {
+      tr {
+        box-shadow: 0 2px 3px rgba(10, 10, 10, 0.1);
+        margin-bottom: 3px !important;
+      }
+      td {
+        &.is-progress-col {
+          span,
+          progress {
+            display: flex;
+            width: 45%;
+            align-items: center;
+            align-self: center;
+          }
+        }
+
+        &.checkbox-cell,
+        &.is-image-cell {
+          border-bottom: 0 !important;
+        }
+
+        &.checkbox-cell,
+        &.is-actions-cell {
+          &:before {
+            display: none;
+          }
+        }
+
+        &.has-no-head-mobile {
+          &:before {
+            display: none;
+          }
+
+          span {
+            display: block;
+            width: 100%;
+          }
+
+          &.is-progress-col {
+            progress {
+              width: 100%;
+            }
+          }
+
+          &.is-image-cell {
+            .image {
+              width: $table-avatar-size-mobile;
+              height: auto;
+              margin: 0 auto $default-padding * 0.25;
+            }
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/packages/demobank-ui/src/scss/_theme-default.scss 
b/packages/demobank-ui/src/scss/_theme-default.scss
new file mode 100644
index 000000000..538dfd4da
--- /dev/null
+++ b/packages/demobank-ui/src/scss/_theme-default.scss
@@ -0,0 +1,136 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+/* We'll need some initial vars to use here */
+@import "node_modules/bulma/sass/utilities/initial-variables";
+
+/* Base: Size  */
+$size-base: 1rem;
+$default-padding: $size-base * 1.5;
+
+/* Default font */
+$family-sans-serif: "Nunito", sans-serif;
+
+/* Base color */
+$base-color: #2e323a;
+$base-color-light: rgba(24, 28, 33, 0.06);
+
+/* General overrides */
+$primary: $turquoise;
+$body-background-color: #f8f8f8;
+$link: $blue;
+$link-visited: $purple;
+$light-border: 1px solid $base-color-light;
+$hr-height: 1px;
+
+/* NavBar: specifics */
+$navbar-input-color: $grey-darker;
+$navbar-input-placeholder-color: $grey-lighter;
+$navbar-box-shadow: 0 1px 0 rgba(24, 28, 33, 0.04);
+$navbar-divider-border: 1px solid rgba($grey-lighter, 0.25);
+$navbar-item-h-padding: $default-padding * 0.75;
+$navbar-avatar-size: 1.75rem;
+
+/* Aside: Bulma override */
+$menu-item-radius: 0;
+$menu-list-link-padding: $size-base * 0.5 0;
+$menu-label-color: lighten($base-color, 25%);
+$menu-item-color: lighten($base-color, 30%);
+$menu-item-hover-color: $white;
+$menu-item-hover-background-color: darken($base-color, 3.5%);
+$menu-item-active-color: $white;
+$menu-item-active-background-color: darken($base-color, 2.5%);
+
+/* Aside: specifics */
+$aside-width: $size-base * 14;
+$aside-mobile-width: $size-base * 15;
+$aside-icon-width: $size-base * 3;
+$aside-submenu-font-size: $size-base * 0.95;
+$aside-box-shadow: none;
+$aside-background-color: $base-color;
+$aside-tools-background-color: darken($aside-background-color, 10%);
+$aside-tools-color: $white;
+
+/* Title Bar: specifics */
+$title-bar-color: $grey;
+$title-bar-active-color: $black-ter;
+
+/* Hero Bar: specifics */
+$hero-bar-background: $white;
+
+/* Card: Bulma override */
+$card-shadow: none;
+$card-header-shadow: none;
+
+/* Card: specifics */
+$card-border: 1px solid $base-color-light;
+$card-header-border-bottom-color: $base-color-light;
+
+/* Table: Bulma override */
+$table-cell-border: 1px solid $white-bis;
+
+/* Table: specifics */
+$table-avatar-size: $size-base * 1.5;
+$table-avatar-size-mobile: 25vw;
+
+/* Form */
+$checkbox-border: 1px solid $base-color;
+
+/* Modal card: Bulma override */
+$modal-card-head-background-color: $white-ter;
+$modal-card-title-size: $size-base;
+$modal-card-body-padding: $default-padding 20px;
+$modal-card-head-border-bottom: 1px solid $white-ter;
+$modal-card-foot-border-top: 0;
+
+/* Modal card: specifics */
+$modal-card-width: 80vw;
+$modal-card-width-mobile: 90vw;
+$modal-card-foot-background-color: $white-ter;
+
+/* Notification: Bulma override */
+$notification-padding: $default-padding * 0.75 $default-padding;
+
+/* Footer: Bulma override */
+$footer-background-color: $white;
+$footer-padding: $default-padding * 0.33 $default-padding;
+
+/* Footer: specifics */
+$footer-logo-height: $size-base * 2;
+
+/* Progress: Bulma override */
+$progress-bar-background-color: $grey-lighter;
+
+/* Icon: specifics */
+$icon-update-mark-size: $size-base * 0.5;
+$icon-update-mark-color: $yellow;
+
+$input-disabled-border-color: $grey-lighter;
+$table-row-hover-background-color: hsl(0, 0%, 80%);
+
+.menu-list {
+  div {
+    border-radius: $menu-item-radius;
+    color: $menu-item-color;
+    display: block;
+    padding: $menu-list-link-padding;
+  }
+}
diff --git a/packages/demobank-ui/src/scss/_tiles.scss 
b/packages/demobank-ui/src/scss/_tiles.scss
new file mode 100644
index 000000000..e69d995f0
--- /dev/null
+++ b/packages/demobank-ui/src/scss/_tiles.scss
@@ -0,0 +1,24 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+.is-tiles-wrapper {
+  margin-bottom: $default-padding;
+}
diff --git a/packages/demobank-ui/src/scss/_title-bar.scss 
b/packages/demobank-ui/src/scss/_title-bar.scss
new file mode 100644
index 000000000..932f8e65d
--- /dev/null
+++ b/packages/demobank-ui/src/scss/_title-bar.scss
@@ -0,0 +1,50 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+section.section.is-title-bar {
+  padding: $default-padding;
+  border-bottom: $light-border;
+
+  ul {
+    li {
+      display: inline-block;
+      padding: 0 $default-padding * 0.5 0 0;
+      font-size: $default-padding;
+      color: $title-bar-color;
+
+      &:after {
+        display: inline-block;
+        content: "/";
+        padding-left: $default-padding * 0.5;
+      }
+
+      &:last-child {
+        padding-right: 0;
+        font-weight: 900;
+        color: $title-bar-active-color;
+
+        &:after {
+          display: none;
+        }
+      }
+    }
+  }
+}
diff --git a/packages/demobank-ui/src/scss/bank.scss 
b/packages/demobank-ui/src/scss/bank.scss
new file mode 100644
index 000000000..b524cfe29
--- /dev/null
+++ b/packages/demobank-ui/src/scss/bank.scss
@@ -0,0 +1,264 @@
+.navcontainer:not(.default-navcontainer) {
+    margin-bottom: 0 !important;
+}
+
+.abort-button {
+  margin-left: 2px;
+  border: 2px solid rgb(0, 120, 231);
+  color: rgb(0, 120, 231);
+  font-size: 87%;
+  margin-top: 1px;
+  background: white;
+}
+
+div.pages-list {
+  margin-top: 15px;
+}
+
+.login-div,
+.register-div {
+    display: block;
+    text-align: center;
+}
+
+a.page-number {
+  color: blue;
+}
+
+a.current-page-number {
+  color: inherit;
+  background-color: inherit;
+}
+
+.cancelled {
+  text-decoration: line-through;
+}
+
+input[type="number"]::-webkit-outer-spin-button,
+input[type="number"]::-webkit-inner-spin-button {
+  -webkit-appearance: none;
+  margin: 0;
+}
+
+/* This CSS code styles the tab */
+.tab {
+    overflow: hidden;
+}
+
+.logout {
+    float: right;
+    border: 20px;
+    margin-right: 15px;
+    margin-top: 15px;
+}
+
+.tab button {
+    background-color: lightgray;
+    color: black;
+    float: left;
+    border: none;
+    outline: none;
+    cursor: pointer;
+    padding: 18px 19px;
+    border: 2px solid #c1c1c1;
+    transition: 0.5s;
+    font-weight: bold;
+}
+
+.tab button:hover {
+    background-color: yellow;
+    border: 2px solid #c1c1c1;
+    color: black;
+}
+
+.tab button.active {
+    background-color: orange;
+    border: 2px solid #c1c1c1;
+    color: black;
+    font-weight: bold;
+}
+
+.tabcontent {
+    display: none;
+    padding: 8px 16px;
+    border: 2px solid #c1c1c1;
+    width: max-content;
+}
+
+.tabcontent.active {
+    display: block;
+}
+
+input[type="number"] {
+    -moz-appearance: textfield;
+}
+
+#transfer-fields {
+  display: flex;
+  flex-wrap: wrap;
+}
+
+#id_amount {
+  width: 6em;
+  display: inline-block;
+  border-radius: 4px 0px 0px 4px;
+}
+
+/**
+ * Amount without the currency,
+ * placed left to a .currency-indicator.
+ */
+#main .amount {
+  width: 6em;
+  display: inline-block;
+  border-radius: 4px 0px 0px 4px;
+}
+
+input {
+    background-color: inherit;
+}
+
+.large-amount {
+    font-weight: bold;
+    font-size: x-large;
+}
+
+.currency {
+    font-style: oblique;
+}
+
+/*
+ * Currency indicator to the right of input fields,
+ * with non-rounded corners to the left.
+ */
+#main .currency-indicator {
+  color: black;
+  border-radius: 0px 4px 4px 0px;
+  position: relative;
+}
+
+#main .fieldlabel {
+  display: block;
+  padding-bottom: 0.5em;
+}
+
+#main .fieldbox {
+  margin-right: 1em;
+  margin-bottom: 0.5em;
+}
+
+#logout-button {
+  display: block;
+  width: fit-content;
+}
+
+.register-form > .pure-form,
+.login-form > .pure-form {
+    background: #4a4a4a;
+    color: #ffffff;
+    display: inline-block;
+    text-align: left;
+    margin-left: auto;
+    margin-right: auto;
+    padding: 16px 16px;
+    border-radius: 8px;
+    width: max-content;
+    .formFieldLabel {
+        margin: 2px 2px;
+    }
+    input[type="text"],
+    input[type="password"] {
+        border: none;
+        border-radius: 4px;
+        background: #6a6a6a;
+        color: #fefefe;
+        box-shadow: none;
+    }
+    input[placeholder="Password"][type="password"] {
+        margin-bottom: 8px;
+    }
+    .btn-register,
+    .btn-login {
+        float: left;
+    }
+    .btn-cancel {
+        float: right;
+    }
+    h2 {
+        margin-top: 0;
+        margin-bottom: 10px;
+    }
+}
+
+
+.challenge-div {
+    display: block;
+    text-align: center;
+}
+
+.challenge-form > .pure-form {
+    background: #4a4a4a;
+    color: #ffffff;
+    display: inline-block;
+    text-align: left;
+    margin-left: auto;
+    margin-right: auto;
+    padding: 16px 16px;
+    border-radius: 8px;
+    width: max-content;
+    .formFieldLabel {
+        margin: 2px 2px;
+    }
+    input[type="text"] {
+        border: none;
+        border-radius: 4px;
+        background: #6a6a6a;
+        color: #fefefe;
+        box-shadow: none;
+    }
+    .btn-confirm {
+        float: left;
+    }
+    .btn-cancel {
+        float: right;
+    }
+    h2 {
+        margin-top: 0;
+        margin-bottom: 10px;
+    }
+}
+
+
+.wire-transfer-form > .pure-form,
+.payto-form > .pure-form,
+.reserve-form > .pure-form {
+    background: #4a4a4a;
+    color: #ffffff;
+    display: inline-block;
+    text-align: left;
+    margin-left: auto;
+    margin-right: auto;
+    padding: 16px 16px;
+    border-radius: 8px;
+    width: max-content;
+    .formFieldLabel {
+        margin: 2px 2px;
+    }
+    input[type="text"] {
+        border: none;
+        border-radius: 4px;
+        background: #6a6a6a;
+        color: #fefefe;
+        box-shadow: none;
+    }
+}
+
+
+html {
+    background: #ffffff;
+    color: #2a2a2a;
+}
+
+.hint {
+    scale: 0.7;
+}
diff --git a/packages/demobank-ui/src/scss/colors-bank.scss 
b/packages/demobank-ui/src/scss/colors-bank.scss
new file mode 100644
index 000000000..c34610948
--- /dev/null
+++ b/packages/demobank-ui/src/scss/colors-bank.scss
@@ -0,0 +1,31 @@
+nav,
+nav a,
+nav span,
+.navcontainer,
+nav button,
+.demobar,
+.navbtn {
+  color: white;
+  background: #a00000;
+}
+
+nav a.active,
+nav button,
+nav span.active,
+.navbtn.active {
+  background-color: #7a0606;
+}
+
+nav a.active:hover,
+nav span.active:hover,
+.navbtn.active:hover,
+nav button:hover,
+nav a:hover,
+nav span:hover,
+.navbtn:hover {
+  background: #df3d3d;
+}
+
+nav a.navbtn.langbtn:focus {
+  background-color: #df3d3d;
+}
\ No newline at end of file
diff --git a/packages/demobank-ui/src/scss/demo.scss 
b/packages/demobank-ui/src/scss/demo.scss
new file mode 100644
index 000000000..71db4b41e
--- /dev/null
+++ b/packages/demobank-ui/src/scss/demo.scss
@@ -0,0 +1,157 @@
+@charset "UTF-8";
+/*
+Style common to all demo pages.
+
+Colors:
+- #1e2739 (dark blue)
+- #0042b2 (default blue)
+- #3daee9 (highlight blue)
+*/
+
+.demobar h1 {
+  text-align: center;
+}
+
+.demobar > p {
+  padding: 0.5em;
+}
+
+.demobar a,
+.demobar a:visited {
+  color: inherit;
+  background-color: inherit;
+}
+
+.tt {
+  font-family: "Lucida Console", Monaco, monospace;
+}
+
+.informational-ok {
+  background: lightgreen;
+  border-radius: 1em;
+  padding: 0.5em;
+}
+
+.informational-fail {
+  background: lightpink;
+  border-radius: 1em;
+  padding: 0.5em;
+}
+
+.content {
+  margin-left: 2em;
+  overflow-x: auto;
+}
+
+.demobar {
+  overflow-x: auto;
+  background-color: #0042b2;
+  color: white;
+}
+
+body {
+  overflow-x: hidden;
+  overflow-y: auto;
+}
+
+.navcontainer {
+  background: #0042b2;
+  margin-bottom: 50px;
+  width: 100%;
+  color: white;
+  position: -webkit-sticky;
+  position: sticky;
+  top: 0px;
+  width: 100vw;
+  backdrop-filter: blur(10px);
+  opacity: 1;
+  z-index: 10000;
+}
+
+nav {
+  left: 1vw;
+  position: relative;
+  background: #0042b2;
+  z-index: 10000;
+}
+
+nav a,
+nav button,
+nav span,
+.navbtn {
+  border: none;
+  color: white;
+  text-align: center;
+  text-decoration: none;
+  display: inline-block;
+  font-size: 16px;
+  background: #0042b2;
+  height: inherit;
+}
+
+nav a,
+nav button,
+nav span,
+.navbtn {
+  padding: 15px 32px;
+}
+
+nav a:hover,
+nav span:hover,
+.navbtn:hover {
+  background: #3daee9;
+}
+
+nav a.active,
+nav span.active,
+.navbtn.active {
+  background-color: #1e2739;
+}
+
+nav a.active:hover,
+nav button.active:hover,
+nav span.active:hover,
+.navbtn.active:hover {
+  background: #3daee9;
+}
+
+nav a,
+nav span,
+.navbtn {
+  cursor: pointer;
+}
+
+nav .right {
+  float: right;
+  margin-right: 5vw;
+}
+nav .hide div.nav {
+  display: none;
+}
+// nav .right div.nav:hover {
+//   display: block;
+// }
+
+// nav .right:hover div.nav {
+//   display: block;
+// }
+
+.langbtn {
+  width: 100%;
+  text-align: left;
+}
+
+.skip {
+  position: absolute;
+  left: -10000px;
+  top: auto;
+  width: 1px;
+  height: 1px;
+  overflow: hidden;
+}
+
+.skip:focus {
+  position: static;
+  width: auto;
+  height: auto;
+}
diff --git a/packages/anastasis-webui/src/scss/fonts/XRXV3I6Li01BKofINeaE.ttf 
b/packages/demobank-ui/src/scss/fonts/XRXV3I6Li01BKofINeaE.ttf
similarity index 100%
copy from packages/anastasis-webui/src/scss/fonts/XRXV3I6Li01BKofINeaE.ttf
copy to packages/demobank-ui/src/scss/fonts/XRXV3I6Li01BKofINeaE.ttf
diff --git a/packages/demobank-ui/src/scss/fonts/nunito.css 
b/packages/demobank-ui/src/scss/fonts/nunito.css
new file mode 100644
index 000000000..ab30db36b
--- /dev/null
+++ b/packages/demobank-ui/src/scss/fonts/nunito.css
@@ -0,0 +1,22 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+@font-face {
+  font-family: 'Nunito';
+  font-style: normal;
+  font-weight: 400;
+  src: url(./XRXV3I6Li01BKofINeaE.ttf) format('truetype');
+}
diff --git 
a/packages/anastasis-webui/src/scss/fonts/materialdesignicons-webfont-4.9.95.eot
 
b/packages/demobank-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.eot
similarity index 100%
copy from 
packages/anastasis-webui/src/scss/fonts/materialdesignicons-webfont-4.9.95.eot
copy to 
packages/demobank-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.eot
diff --git 
a/packages/anastasis-webui/src/scss/fonts/materialdesignicons-webfont-4.9.95.ttf
 
b/packages/demobank-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.ttf
similarity index 100%
copy from 
packages/anastasis-webui/src/scss/fonts/materialdesignicons-webfont-4.9.95.ttf
copy to 
packages/demobank-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.ttf
diff --git 
a/packages/anastasis-webui/src/scss/fonts/materialdesignicons-webfont-4.9.95.woff
 
b/packages/demobank-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.woff
similarity index 100%
copy from 
packages/anastasis-webui/src/scss/fonts/materialdesignicons-webfont-4.9.95.woff
copy to 
packages/demobank-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.woff
diff --git 
a/packages/anastasis-webui/src/scss/fonts/materialdesignicons-webfont-4.9.95.woff2
 
b/packages/demobank-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.woff2
similarity index 100%
copy from 
packages/anastasis-webui/src/scss/fonts/materialdesignicons-webfont-4.9.95.woff2
copy to 
packages/demobank-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.woff2
diff --git 
a/packages/demobank-ui/src/scss/icons/materialdesignicons-4.9.95.min.css 
b/packages/demobank-ui/src/scss/icons/materialdesignicons-4.9.95.min.css
new file mode 100644
index 000000000..24a89d639
--- /dev/null
+++ b/packages/demobank-ui/src/scss/icons/materialdesignicons-4.9.95.min.css
@@ -0,0 +1,3 @@
+@font-face{font-family:"Material Design 
Icons";src:url("./fonts/materialdesignicons-webfont-4.9.95.eot");src:url("./fonts/materialdesignicons-webfont-4.9.95.woff2")
 format("woff2"),url("./fonts/materialdesignicons-webfont-4.9.95.woff") 
format("woff"),url("./fonts/materialdesignicons-webfont-4.9.95.ttf") 
format("truetype");font-weight:normal;font-style:normal}.mdi:before,.mdi-set{display:inline-block;font:normal
 normal normal 24px/1 "Material Design Icons";font-size:inherit;text-rendering 
[...]
+
+/*# sourceMappingURL=materialdesignicons.css.map */
diff --git a/packages/demobank-ui/src/scss/libs/_all.scss 
b/packages/demobank-ui/src/scss/libs/_all.scss
new file mode 100644
index 000000000..08bd76cd1
--- /dev/null
+++ b/packages/demobank-ui/src/scss/libs/_all.scss
@@ -0,0 +1,29 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+@import "node_modules/bulma-radio/bulma-radio";
+// @import "node_modules/bulma-responsive-tables/bulma-responsive-tables";
+@import "node_modules/bulma-checkbox/bulma-checkbox";
+// @import "node_modules/bulma-switch-control/bulma-switch-control";
+// @import "node_modules/bulma-upload-control/bulma-upload-control";
+
+/* Bulma */
+@import "node_modules/bulma/bulma";
diff --git a/packages/demobank-ui/src/scss/main.scss 
b/packages/demobank-ui/src/scss/main.scss
new file mode 100644
index 000000000..ebe36b9b4
--- /dev/null
+++ b/packages/demobank-ui/src/scss/main.scss
@@ -0,0 +1,4 @@
+@import "pure";
+@import "bank";
+@import "demo";
+@import "colors-bank";
diff --git a/packages/demobank-ui/src/scss/pure.scss 
b/packages/demobank-ui/src/scss/pure.scss
new file mode 100644
index 000000000..0d804d6bd
--- /dev/null
+++ b/packages/demobank-ui/src/scss/pure.scss
@@ -0,0 +1,1328 @@
+/*!
+Pure v0.6.2
+Copyright 2013 Yahoo!
+Licensed under the BSD License.
+https://github.com/yahoo/pure/blob/master/LICENSE.md
+*/
+/*!
+normalize.css v^3.0 | MIT License | git.io/normalize
+Copyright (c) Nicolas Gallagher and Jonathan Neal
+*/
+/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
+/**
+ * 1. Set default font family to sans-serif.
+ * 2. Prevent iOS and IE text size adjust after device orientation change,
+ *    without disabling user zoom.
+ */
+html {
+  font-family: sans-serif;
+  /* 1 */
+  -ms-text-size-adjust: 100%;
+  /* 2 */
+  -webkit-text-size-adjust: 100%;
+  /* 2 */ }
+
+/**
+ * Remove default margin.
+ */
+body {
+  margin: 0; }
+
+/* HTML5 display definitions
+   ========================================================================== 
*/
+/**
+ * Correct `block` display not defined for any HTML5 element in IE 8/9.
+ * Correct `block` display not defined for `details` or `summary` in IE 10/11
+ * and Firefox.
+ * Correct `block` display not defined for `main` in IE 11.
+ */
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+menu,
+nav,
+section,
+summary {
+  display: block; }
+
+/**
+ * 1. Correct `inline-block` display not defined in IE 8/9.
+ * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
+ */
+audio,
+canvas,
+progress,
+video {
+  display: inline-block;
+  /* 1 */
+  vertical-align: baseline;
+  /* 2 */ }
+
+/**
+ * Prevent modern browsers from displaying `audio` without controls.
+ * Remove excess height in iOS 5 devices.
+ */
+audio:not([controls]) {
+  display: none;
+  height: 0; }
+
+/**
+ * Address `[hidden]` styling not present in IE 8/9/10.
+ * Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.
+ */
+[hidden],
+template {
+  display: none; }
+
+/* Links
+   ========================================================================== 
*/
+/**
+ * Remove the gray background color from active links in IE 10.
+ */
+a {
+  background-color: transparent; }
+
+/**
+ * Improve readability of focused elements when they are also in an
+ * active/hover state.
+ */
+a:active,
+a:hover {
+  outline: 0; }
+
+/* Text-level semantics
+   ========================================================================== 
*/
+/**
+ * Address styling not present in IE 8/9/10/11, Safari, and Chrome.
+ */
+abbr[title] {
+  border-bottom: 1px dotted; }
+
+/**
+ * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
+ */
+b,
+strong {
+  font-weight: bold; }
+
+/**
+ * Address styling not present in Safari and Chrome.
+ */
+dfn {
+  font-style: italic; }
+
+/**
+ * Address variable `h1` font-size and margin within `section` and `article`
+ * contexts in Firefox 4+, Safari, and Chrome.
+ */
+h1 {
+  font-size: 2em;
+  margin: 0.67em 0; }
+
+/**
+ * Address styling not present in IE 8/9.
+ */
+mark {
+  background: #ff0;
+  color: #000; }
+
+/**
+ * Address inconsistent and variable font size in all browsers.
+ */
+small {
+  font-size: 80%; }
+
+/**
+ * Prevent `sub` and `sup` affecting `line-height` in all browsers.
+ */
+sub,
+sup {
+  font-size: 75%;
+  line-height: 0;
+  position: relative;
+  vertical-align: baseline; }
+
+sup {
+  top: -0.5em; }
+
+sub {
+  bottom: -0.25em; }
+
+/* Embedded content
+   ========================================================================== 
*/
+/**
+ * Remove border when inside `a` element in IE 8/9/10.
+ */
+img {
+  border: 0; }
+
+/**
+ * Correct overflow not hidden in IE 9/10/11.
+ */
+svg:not(:root) {
+  overflow: hidden; }
+
+/* Grouping content
+   ========================================================================== 
*/
+/**
+ * Address margin not present in IE 8/9 and Safari.
+ */
+figure {
+  margin: 1em 40px; }
+
+/**
+ * Address differences between Firefox and other browsers.
+ */
+hr {
+  box-sizing: content-box;
+  height: 0; }
+
+/**
+ * Contain overflow in all browsers.
+ */
+pre {
+  overflow: auto; }
+
+/**
+ * Address odd `em`-unit font size rendering in all browsers.
+ */
+code,
+kbd,
+pre,
+samp {
+  font-family: monospace, monospace;
+  font-size: 1em; }
+
+/* Forms
+   ========================================================================== 
*/
+/**
+ * Known limitation: by default, Chrome and Safari on OS X allow very limited
+ * styling of `select`, unless a `border` property is set.
+ */
+/**
+ * 1. Correct color not being inherited.
+ *    Known issue: affects color of disabled elements.
+ * 2. Correct font properties not being inherited.
+ * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
+ */
+button,
+input,
+optgroup,
+select,
+textarea {
+  color: inherit;
+  /* 1 */
+  font: inherit;
+  /* 2 */
+  margin: 0;
+  /* 3 */ }
+
+/**
+ * Address `overflow` set to `hidden` in IE 8/9/10/11.
+ */
+button {
+  overflow: visible; }
+
+/**
+ * Address inconsistent `text-transform` inheritance for `button` and `select`.
+ * All other form control elements do not inherit `text-transform` values.
+ * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
+ * Correct `select` style inheritance in Firefox.
+ */
+button,
+select {
+  text-transform: none; }
+
+/**
+ * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
+ *    and `video` controls.
+ * 2. Correct inability to style clickable `input` types in iOS.
+ * 3. Improve usability and consistency of cursor style between image-type
+ *    `input` and others.
+ */
+button,
+html input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+  -webkit-appearance: button;
+  /* 2 */
+  cursor: pointer;
+  /* 3 */ }
+
+/**
+ * Re-set default cursor for disabled elements.
+ */
+button[disabled],
+html input[disabled] {
+  cursor: default; }
+
+/**
+ * Remove inner padding and border in Firefox 4+.
+ */
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+  border: 0;
+  padding: 0; }
+
+/**
+ * Address Firefox 4+ setting `line-height` on `input` using `!important` in
+ * the UA stylesheet.
+ */
+input {
+  line-height: normal; }
+
+/**
+ * It's recommended that you don't attempt to style these elements.
+ * Firefox's implementation doesn't respect box-sizing, padding, or width.
+ *
+ * 1. Address box sizing set to `content-box` in IE 8/9/10.
+ * 2. Remove excess padding in IE 8/9/10.
+ */
+input[type="checkbox"],
+input[type="radio"] {
+  box-sizing: border-box;
+  /* 1 */
+  padding: 0;
+  /* 2 */ }
+
+/**
+ * Fix the cursor style for Chrome's increment/decrement buttons. For certain
+ * `font-size` values of the `input`, it causes the cursor style of the
+ * decrement button to change from `default` to `text`.
+ */
+input[type="number"]::-webkit-inner-spin-button,
+input[type="number"]::-webkit-outer-spin-button {
+  height: auto; }
+
+/**
+ * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
+ * 2. Address `box-sizing` set to `border-box` in Safari and Chrome.
+ */
+input[type="search"] {
+  -webkit-appearance: textfield;
+  /* 1 */
+  box-sizing: content-box;
+  /* 2 */ }
+
+/**
+ * Remove inner padding and search cancel button in Safari and Chrome on OS X.
+ * Safari (but not Chrome) clips the cancel button when the search input has
+ * padding (and `textfield` appearance).
+ */
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+  -webkit-appearance: none; }
+
+/**
+ * Define consistent border, margin, and padding.
+ */
+fieldset {
+  border: 1px solid #c0c0c0;
+  margin: 0 2px;
+  padding: 0.35em 0.625em 0.75em; }
+
+/**
+ * 1. Correct `color` not being inherited in IE 8/9/10/11.
+ * 2. Remove padding so people aren't caught out if they zero out fieldsets.
+ */
+legend {
+  border: 0;
+  /* 1 */
+  padding: 0;
+  /* 2 */ }
+
+/**
+ * Remove default vertical scrollbar in IE 8/9/10/11.
+ */
+textarea {
+  overflow: auto; }
+
+/**
+ * Don't inherit the `font-weight` (applied by a rule above).
+ * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
+ */
+optgroup {
+  font-weight: bold; }
+
+/* Tables
+   ========================================================================== 
*/
+/**
+ * Remove most spacing between table cells.
+ */
+table {
+  border-collapse: collapse;
+  border-spacing: 0; }
+
+td,
+th {
+  padding: 0; }
+
+/*csslint important:false*/
+/* ==========================================================================
+   Pure Base Extras
+   ========================================================================== 
*/
+/**
+ * Extra rules that Pure adds on top of Normalize.css
+ */
+/**
+ * Always hide an element when it has the `hidden` HTML attribute.
+ */
+.hidden,
+[hidden] {
+  display: none !important; }
+
+/**
+ * Add this class to an image to make it fit within it's fluid parent wrapper 
while maintaining
+ * aspect ratio.
+ */
+.pure-img {
+  max-width: 100%;
+  height: auto;
+  display: block; }
+
+/*csslint regex-selectors:false, known-properties:false, 
duplicate-properties:false*/
+.pure-g {
+  letter-spacing: -0.31em;
+  /* Webkit: collapse white-space between units */
+  *letter-spacing: normal;
+  /* reset IE < 8 */
+  *word-spacing: -0.43em;
+  /* IE < 8: collapse white-space between units */
+  text-rendering: optimizespeed;
+  /* Webkit: fixes text-rendering: optimizeLegibility */
+    /*
+    Sets the font stack to fonts known to work properly with the above letter
+    and word spacings. See: https://github.com/yahoo/pure/issues/41/
+
+    The following font stack makes Pure Grids work on all known environments.
+
+    * FreeSans: Ships with many Linux distros, including Ubuntu
+
+    * Arimo: Ships with Chrome OS. Arimo has to be defined before Helvetica and
+      Arial to get picked up by the browser, even though neither is available
+      in Chrome OS.
+
+    * Droid Sans: Ships with all versions of Android.
+
+    * Helvetica, Arial, sans-serif: Common font stack on OS X and Windows.
+    */
+  font-family: FreeSans, Arimo, "Droid Sans", Helvetica, Arial, sans-serif;
+  /* Use flexbox when possible to avoid `letter-spacing` side-effects. */
+  display: -webkit-box;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-flow: row wrap;
+  -ms-flex-flow: row wrap;
+  flex-flow: row wrap;
+  /* Prevents distributing space between rows */
+  -webkit-align-content: flex-start;
+  -ms-flex-line-pack: start;
+  align-content: flex-start; }
+
+/* IE10 display: -ms-flexbox (and display: flex in IE 11) does not work inside 
a table; fall back to block and rely on font hack */
+@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
+  table .pure-g {
+    display: block; } }
+/* Opera as of 12 on Windows needs word-spacing.
+   The ".opera-only" selector is used to prevent actual prefocus styling
+   and is not required in markup.
+*/
+.opera-only :-o-prefocus,
+.pure-g {
+  word-spacing: -0.43em; }
+
+.pure-u {
+  display: inline-block;
+  *display: inline;
+  /* IE < 8: fake inline-block */
+  zoom: 1;
+  letter-spacing: normal;
+  word-spacing: normal;
+  vertical-align: top;
+  text-rendering: auto; }
+
+/*
+Resets the font family back to the OS/browser's default sans-serif font,
+this the same font stack that Normalize.css sets for the `body`.
+*/
+.pure-g [class*="pure-u"] {
+  font-family: sans-serif; }
+
+.pure-u-1,
+.pure-u-1-1,
+.pure-u-1-2,
+.pure-u-1-3,
+.pure-u-2-3,
+.pure-u-1-4,
+.pure-u-3-4,
+.pure-u-1-5,
+.pure-u-2-5,
+.pure-u-3-5,
+.pure-u-4-5,
+.pure-u-5-5,
+.pure-u-1-6,
+.pure-u-5-6,
+.pure-u-1-8,
+.pure-u-3-8,
+.pure-u-5-8,
+.pure-u-7-8,
+.pure-u-1-12,
+.pure-u-5-12,
+.pure-u-7-12,
+.pure-u-11-12,
+.pure-u-1-24,
+.pure-u-2-24,
+.pure-u-3-24,
+.pure-u-4-24,
+.pure-u-5-24,
+.pure-u-6-24,
+.pure-u-7-24,
+.pure-u-8-24,
+.pure-u-9-24,
+.pure-u-10-24,
+.pure-u-11-24,
+.pure-u-12-24,
+.pure-u-13-24,
+.pure-u-14-24,
+.pure-u-15-24,
+.pure-u-16-24,
+.pure-u-17-24,
+.pure-u-18-24,
+.pure-u-19-24,
+.pure-u-20-24,
+.pure-u-21-24,
+.pure-u-22-24,
+.pure-u-23-24,
+.pure-u-24-24 {
+  display: inline-block;
+  *display: inline;
+  zoom: 1;
+  letter-spacing: normal;
+  word-spacing: normal;
+  vertical-align: top;
+  text-rendering: auto; }
+
+.pure-u-1-24 {
+  width: 4.1667%;
+  *width: 4.1357%; }
+
+.pure-u-1-12,
+.pure-u-2-24 {
+  width: 8.3333%;
+  *width: 8.3023%; }
+
+.pure-u-1-8,
+.pure-u-3-24 {
+  width: 12.5000%;
+  *width: 12.4690%; }
+
+.pure-u-1-6,
+.pure-u-4-24 {
+  width: 16.6667%;
+  *width: 16.6357%; }
+
+.pure-u-1-5 {
+  width: 20%;
+  *width: 19.9690%; }
+
+.pure-u-5-24 {
+  width: 20.8333%;
+  *width: 20.8023%; }
+
+.pure-u-1-4,
+.pure-u-6-24 {
+  width: 25%;
+  *width: 24.9690%; }
+
+.pure-u-7-24 {
+  width: 29.1667%;
+  *width: 29.1357%; }
+
+.pure-u-1-3,
+.pure-u-8-24 {
+  width: 33.3333%;
+  *width: 33.3023%; }
+
+.pure-u-3-8,
+.pure-u-9-24 {
+  width: 37.5000%;
+  *width: 37.4690%; }
+
+.pure-u-2-5 {
+  width: 40%;
+  *width: 39.9690%; }
+
+.pure-u-5-12,
+.pure-u-10-24 {
+  width: 41.6667%;
+  *width: 41.6357%; }
+
+.pure-u-11-24 {
+  width: 45.8333%;
+  *width: 45.8023%; }
+
+.pure-u-1-2,
+.pure-u-12-24 {
+  width: 50%;
+  *width: 49.9690%; }
+
+.pure-u-13-24 {
+  width: 54.1667%;
+  *width: 54.1357%; }
+
+.pure-u-7-12,
+.pure-u-14-24 {
+  width: 58.3333%;
+  *width: 58.3023%; }
+
+.pure-u-3-5 {
+  width: 60%;
+  *width: 59.9690%; }
+
+.pure-u-5-8,
+.pure-u-15-24 {
+  width: 62.5000%;
+  *width: 62.4690%; }
+
+.pure-u-2-3,
+.pure-u-16-24 {
+  width: 66.6667%;
+  *width: 66.6357%; }
+
+.pure-u-17-24 {
+  width: 70.8333%;
+  *width: 70.8023%; }
+
+.pure-u-3-4,
+.pure-u-18-24 {
+  width: 75%;
+  *width: 74.9690%; }
+
+.pure-u-19-24 {
+  width: 79.1667%;
+  *width: 79.1357%; }
+
+.pure-u-4-5 {
+  width: 80%;
+  *width: 79.9690%; }
+
+.pure-u-5-6,
+.pure-u-20-24 {
+  width: 83.3333%;
+  *width: 83.3023%; }
+
+.pure-u-7-8,
+.pure-u-21-24 {
+  width: 87.5000%;
+  *width: 87.4690%; }
+
+.pure-u-11-12,
+.pure-u-22-24 {
+  width: 91.6667%;
+  *width: 91.6357%; }
+
+.pure-u-23-24 {
+  width: 95.8333%;
+  *width: 95.8023%; }
+
+.pure-u-1,
+.pure-u-1-1,
+.pure-u-5-5,
+.pure-u-24-24 {
+  width: 100%; }
+
+.pure-button {
+  /* Structure */
+  display: inline-block;
+  zoom: 1;
+  line-height: normal;
+  white-space: nowrap;
+  vertical-align: middle;
+  text-align: center;
+  cursor: pointer;
+  -webkit-user-drag: none;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  box-sizing: border-box; }
+
+/* Firefox: Get rid of the inner focus border */
+.pure-button::-moz-focus-inner {
+  padding: 0;
+  border: 0; }
+
+/* Inherit .pure-g styles */
+.pure-button-group {
+  letter-spacing: -0.31em;
+  /* Webkit: collapse white-space between units */
+  *letter-spacing: normal;
+  /* reset IE < 8 */
+  *word-spacing: -0.43em;
+  /* IE < 8: collapse white-space between units */
+  text-rendering: optimizespeed;
+  /* Webkit: fixes text-rendering: optimizeLegibility */ }
+
+.opera-only :-o-prefocus,
+.pure-button-group {
+  word-spacing: -0.43em; }
+
+.pure-button-group .pure-button {
+  letter-spacing: normal;
+  word-spacing: normal;
+  vertical-align: top;
+  text-rendering: auto; }
+
+/*csslint outline-none:false*/
+.pure-button {
+  font-family: inherit;
+  font-size: 100%;
+  padding: 0.5em 1em;
+  color: #444;
+  /* rgba not supported (IE 8) */
+  color: rgba(0, 0, 0, 0.8);
+  /* rgba supported */
+  border: 1px solid #999;
+  /*IE 6/7/8*/
+  border: none rgba(0, 0, 0, 0);
+  /*IE9 + everything else*/
+  background-color: #E6E6E6;
+  text-decoration: none;
+  border-radius: 2px; }
+
+.pure-button-hover,
+.pure-button:hover,
+.pure-button:focus {
+  /* csslint ignore:start */
+  filter: alpha(opacity=90);
+  /* csslint ignore:end */
+  background-image: -webkit-linear-gradient(transparent, rgba(0, 0, 0, 0.05) 
40%, rgba(0, 0, 0, 0.1));
+  background-image: linear-gradient(transparent, rgba(0, 0, 0, 0.05) 40%, 
rgba(0, 0, 0, 0.1)); }
+
+.pure-button:focus {
+  outline: 0; }
+
+.pure-button-active,
+.pure-button:active {
+  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.15) inset, 0 0 6px rgba(0, 0, 0, 0.2) 
inset;
+  border-color: #000; }
+
+.pure-button[disabled],
+.pure-button-disabled,
+.pure-button-disabled:hover,
+.pure-button-disabled:focus,
+.pure-button-disabled:active {
+  border: none;
+  background-image: none;
+  /* csslint ignore:start */
+  filter: alpha(opacity=40);
+  /* csslint ignore:end */
+  opacity: 0.40;
+  cursor: not-allowed;
+  box-shadow: none;
+  pointer-events: none; }
+
+.pure-button-hidden {
+  display: none; }
+
+.pure-button-primary,
+.pure-button-selected,
+a.pure-button-primary,
+a.pure-button-selected {
+  background-color: #00509b;
+  color: #fff; }
+
+/* Button Groups */
+.pure-button-group .pure-button {
+  margin: 0;
+  border-radius: 0;
+  border-right: 1px solid #111;
+  /* fallback color for rgba() for IE7/8 */
+  border-right: 1px solid rgba(0, 0, 0, 0.2); }
+
+.pure-button-group .pure-button:first-child {
+  border-top-left-radius: 2px;
+  border-bottom-left-radius: 2px; }
+
+.pure-button-group .pure-button:last-child {
+  border-top-right-radius: 2px;
+  border-bottom-right-radius: 2px;
+  border-right: none; }
+
+/*csslint box-model:false*/
+/*
+Box-model set to false because we're setting a height on select elements, which
+also have border and padding. This is done because some browsers don't render
+the padding. We explicitly set the box-model for select elements to border-box,
+so we can ignore the csslint warning.
+*/
+.pure-form input[type="text"],
+.pure-form input[type="password"],
+.pure-form input[type="email"],
+.pure-form input[type="url"],
+.pure-form input[type="date"],
+.pure-form input[type="month"],
+.pure-form input[type="time"],
+.pure-form input[type="datetime"],
+.pure-form input[type="datetime-local"],
+.pure-form input[type="week"],
+.pure-form input[type="number"],
+.pure-form input[type="search"],
+.pure-form input[type="tel"],
+.pure-form input[type="color"],
+.pure-form select,
+.pure-form textarea {
+  padding: 0.5em 0.6em;
+  display: inline-block;
+  border: 1px solid #ccc;
+  box-shadow: inset 0 1px 3px #ddd;
+  border-radius: 4px;
+  vertical-align: middle;
+  box-sizing: border-box; }
+
+/*
+Need to separate out the :not() selector from the rest of the CSS 2.1 selectors
+since IE8 won't execute CSS that contains a CSS3 selector.
+*/
+.pure-form input:not([type]) {
+  padding: 0.5em 0.6em;
+  display: inline-block;
+  border: 1px solid #ccc;
+  box-shadow: inset 0 1px 3px #ddd;
+  border-radius: 4px;
+  box-sizing: border-box; }
+
+/* Chrome (as of v.32/34 on OS X) needs additional room for color to display. 
*/
+/* May be able to remove this tweak as color inputs become more standardized 
across browsers. */
+.pure-form input[type="color"] {
+  padding: 0.2em 0.5em; }
+
+.pure-form input[type="text"]:focus,
+.pure-form input[type="password"]:focus,
+.pure-form input[type="email"]:focus,
+.pure-form input[type="url"]:focus,
+.pure-form input[type="date"]:focus,
+.pure-form input[type="month"]:focus,
+.pure-form input[type="time"]:focus,
+.pure-form input[type="datetime"]:focus,
+.pure-form input[type="datetime-local"]:focus,
+.pure-form input[type="week"]:focus,
+.pure-form input[type="number"]:focus,
+.pure-form input[type="search"]:focus,
+.pure-form input[type="tel"]:focus,
+.pure-form input[type="color"]:focus,
+.pure-form select:focus,
+.pure-form textarea:focus {
+  outline: 0;
+  border-color: #129FEA; }
+
+/*
+Need to separate out the :not() selector from the rest of the CSS 2.1 selectors
+since IE8 won't execute CSS that contains a CSS3 selector.
+*/
+.pure-form input:not([type]):focus {
+  outline: 0;
+  border-color: #129FEA; }
+
+.pure-form input[type="file"]:focus,
+.pure-form input[type="radio"]:focus,
+.pure-form input[type="checkbox"]:focus {
+  outline: thin solid #129FEA;
+  outline: 1px auto #129FEA; }
+
+.pure-form .pure-checkbox,
+.pure-form .pure-radio {
+  margin: 0.5em 0;
+  display: block; }
+
+.pure-form input[type="text"][disabled],
+.pure-form input[type="password"][disabled],
+.pure-form input[type="email"][disabled],
+.pure-form input[type="url"][disabled],
+.pure-form input[type="date"][disabled],
+.pure-form input[type="month"][disabled],
+.pure-form input[type="time"][disabled],
+.pure-form input[type="datetime"][disabled],
+.pure-form input[type="datetime-local"][disabled],
+.pure-form input[type="week"][disabled],
+.pure-form input[type="number"][disabled],
+.pure-form input[type="search"][disabled],
+.pure-form input[type="tel"][disabled],
+.pure-form input[type="color"][disabled],
+.pure-form select[disabled],
+.pure-form textarea[disabled] {
+  cursor: not-allowed;
+  background-color: #eaeded;
+  color: #cad2d3; }
+
+/*
+Need to separate out the :not() selector from the rest of the CSS 2.1 selectors
+since IE8 won't execute CSS that contains a CSS3 selector.
+*/
+.pure-form input:not([type])[disabled] {
+  cursor: not-allowed;
+  background-color: #eaeded;
+  color: #cad2d3; }
+
+.pure-form input[readonly],
+.pure-form select[readonly],
+.pure-form textarea[readonly] {
+  background-color: #eee;
+  /* menu hover bg color */
+  color: #777;
+  /* menu text color */
+  border-color: #ccc; }
+
+.pure-form input:focus:invalid,
+.pure-form textarea:focus:invalid,
+.pure-form select:focus:invalid {
+  color: #b94a48;
+  border-color: #e9322d; }
+
+.pure-form input[type="file"]:focus:invalid:focus,
+.pure-form input[type="radio"]:focus:invalid:focus,
+.pure-form input[type="checkbox"]:focus:invalid:focus {
+  outline-color: #e9322d; }
+
+.pure-form select {
+  /* Normalizes the height; padding is not sufficient. */
+  height: 2.25em;
+  border: 1px solid #ccc;
+  background-color: white; }
+
+.pure-form select[multiple] {
+  height: auto; }
+
+.pure-form label {
+  margin: 0.5em 0 0.2em; }
+
+.pure-form fieldset {
+  margin: 0;
+  padding: 0.35em 0 0.75em;
+  border: 0; }
+
+.pure-form legend {
+  display: block;
+  width: 100%;
+  padding: 0.3em 0;
+  margin-bottom: 0.3em;
+  color: #333;
+  border-bottom: 1px solid #e5e5e5; }
+
+.pure-form-stacked input[type="text"],
+.pure-form-stacked input[type="password"],
+.pure-form-stacked input[type="email"],
+.pure-form-stacked input[type="url"],
+.pure-form-stacked input[type="date"],
+.pure-form-stacked input[type="month"],
+.pure-form-stacked input[type="time"],
+.pure-form-stacked input[type="datetime"],
+.pure-form-stacked input[type="datetime-local"],
+.pure-form-stacked input[type="week"],
+.pure-form-stacked input[type="number"],
+.pure-form-stacked input[type="search"],
+.pure-form-stacked input[type="tel"],
+.pure-form-stacked input[type="color"],
+.pure-form-stacked input[type="file"],
+.pure-form-stacked select,
+.pure-form-stacked label,
+.pure-form-stacked textarea {
+  display: block;
+  margin: 0.25em 0; }
+
+/*
+Need to separate out the :not() selector from the rest of the CSS 2.1 selectors
+since IE8 won't execute CSS that contains a CSS3 selector.
+*/
+.pure-form-stacked input:not([type]) {
+  display: block;
+  margin: 0.25em 0; }
+
+.pure-form-aligned input,
+.pure-form-aligned textarea,
+.pure-form-aligned select,
+.pure-form-aligned .pure-help-inline,
+.pure-form-message-inline {
+  display: inline-block;
+  *display: inline;
+  *zoom: 1;
+  vertical-align: middle; }
+
+.pure-form-aligned textarea {
+  vertical-align: top; }
+
+/* Aligned Forms */
+.pure-form-aligned .pure-control-group {
+  margin-bottom: 0.5em; }
+
+.pure-form-aligned .pure-control-group label {
+  text-align: right;
+  display: inline-block;
+  vertical-align: middle;
+  width: 10em;
+  margin: 0 1em 0 0; }
+
+.pure-form-aligned .pure-controls {
+  margin: 1.5em 0 0 11em; }
+
+/* Rounded Inputs */
+.pure-form input.pure-input-rounded,
+.pure-form .pure-input-rounded {
+  border-radius: 2em;
+  padding: 0.5em 1em; }
+
+/* Grouped Inputs */
+.pure-form .pure-group fieldset {
+  margin-bottom: 10px; }
+
+.pure-form .pure-group input,
+.pure-form .pure-group textarea {
+  display: block;
+  padding: 10px;
+  margin: 0 0 -1px;
+  border-radius: 0;
+  position: relative;
+  top: -1px; }
+
+.pure-form .pure-group input:focus,
+.pure-form .pure-group textarea:focus {
+  z-index: 3; }
+
+.pure-form .pure-group input:first-child,
+.pure-form .pure-group textarea:first-child {
+  top: 1px;
+  border-radius: 4px 4px 0 0;
+  margin: 0; }
+
+.pure-form .pure-group input:first-child:last-child,
+.pure-form .pure-group textarea:first-child:last-child {
+  top: 1px;
+  border-radius: 4px;
+  margin: 0; }
+
+.pure-form .pure-group input:last-child,
+.pure-form .pure-group textarea:last-child {
+  top: -2px;
+  border-radius: 0 0 4px 4px;
+  margin: 0; }
+
+.pure-form .pure-group button {
+  margin: 0.35em 0; }
+
+.pure-form .pure-input-1 {
+  width: 100%; }
+
+.pure-form .pure-input-3-4 {
+  width: 75%; }
+
+.pure-form .pure-input-2-3 {
+  width: 66%; }
+
+.pure-form .pure-input-1-2 {
+  width: 50%; }
+
+.pure-form .pure-input-1-3 {
+  width: 33%; }
+
+.pure-form .pure-input-1-4 {
+  width: 25%; }
+
+/* Inline help for forms */
+/* NOTE: pure-help-inline is deprecated. Use .pure-form-message-inline 
instead. */
+.pure-form .pure-help-inline,
+.pure-form-message-inline {
+  display: inline-block;
+  padding-left: 0.3em;
+  color: #666;
+  vertical-align: middle;
+  font-size: 0.875em; }
+
+/* Block help for forms */
+.pure-form-message {
+  display: block;
+  color: #666;
+  font-size: 0.875em; }
+
+@media only screen and (max-width: 480px) {
+  .pure-form button[type="submit"] {
+    margin: 0.7em 0 0; }
+
+  .pure-form input:not([type]),
+  .pure-form input[type="text"],
+  .pure-form input[type="password"],
+  .pure-form input[type="email"],
+  .pure-form input[type="url"],
+  .pure-form input[type="date"],
+  .pure-form input[type="month"],
+  .pure-form input[type="time"],
+  .pure-form input[type="datetime"],
+  .pure-form input[type="datetime-local"],
+  .pure-form input[type="week"],
+  .pure-form input[type="number"],
+  .pure-form input[type="search"],
+  .pure-form input[type="tel"],
+  .pure-form input[type="color"],
+  .pure-form label {
+    margin-bottom: 0.3em;
+    display: block; }
+
+  .pure-group input:not([type]),
+  .pure-group input[type="text"],
+  .pure-group input[type="password"],
+  .pure-group input[type="email"],
+  .pure-group input[type="url"],
+  .pure-group input[type="date"],
+  .pure-group input[type="month"],
+  .pure-group input[type="time"],
+  .pure-group input[type="datetime"],
+  .pure-group input[type="datetime-local"],
+  .pure-group input[type="week"],
+  .pure-group input[type="number"],
+  .pure-group input[type="search"],
+  .pure-group input[type="tel"],
+  .pure-group input[type="color"] {
+    margin-bottom: 0; }
+
+  .pure-form-aligned .pure-control-group label {
+    margin-bottom: 0.3em;
+    text-align: left;
+    display: block;
+    width: 100%; }
+
+  .pure-form-aligned .pure-controls {
+    margin: 1.5em 0 0 0; }
+
+  /* NOTE: pure-help-inline is deprecated. Use .pure-form-message-inline 
instead. */
+  .pure-form .pure-help-inline,
+  .pure-form-message-inline,
+  .pure-form-message {
+    display: block;
+    font-size: 0.75em;
+    /* Increased bottom padding to make it group with its related input 
element. */
+    padding: 0.2em 0 0.8em; } }
+/*csslint adjoining-classes: false, box-model:false*/
+.pure-menu {
+  box-sizing: border-box; }
+
+.pure-menu-fixed {
+  position: fixed;
+  left: 0;
+  top: 0;
+  z-index: 3; }
+
+.pure-menu-list,
+.pure-menu-item {
+  position: relative; }
+
+.pure-menu-list {
+  list-style: none;
+  margin: 0;
+  padding: 0; }
+
+.pure-menu-item {
+  padding: 0;
+  margin: 0;
+  height: 100%; }
+
+.pure-menu-link,
+.pure-menu-heading {
+  display: block;
+  text-decoration: none;
+  white-space: nowrap; }
+
+/* HORIZONTAL MENU */
+.pure-menu-horizontal {
+  width: 100%;
+  white-space: nowrap; }
+
+.pure-menu-horizontal .pure-menu-list {
+  display: inline-block; }
+
+/* Initial menus should be inline-block so that they are horizontal */
+.pure-menu-horizontal .pure-menu-item,
+.pure-menu-horizontal .pure-menu-heading,
+.pure-menu-horizontal .pure-menu-separator {
+  display: inline-block;
+  *display: inline;
+  zoom: 1;
+  vertical-align: middle; }
+
+/* Submenus should still be display: block; */
+.pure-menu-item .pure-menu-item {
+  display: block; }
+
+.pure-menu-children {
+  display: none;
+  position: absolute;
+  left: 100%;
+  top: 0;
+  margin: 0;
+  padding: 0;
+  z-index: 3; }
+
+.pure-menu-horizontal .pure-menu-children {
+  left: 0;
+  top: auto;
+  width: inherit; }
+
+.pure-menu-allow-hover:hover > .pure-menu-children,
+.pure-menu-active > .pure-menu-children {
+  display: block;
+  position: absolute; }
+
+/* Vertical Menus - show the dropdown arrow */
+.pure-menu-has-children > .pure-menu-link:after {
+  padding-left: 0.5em;
+  content: "\25B8";
+  font-size: small; }
+
+/* Horizontal Menus - show the dropdown arrow */
+.pure-menu-horizontal .pure-menu-has-children > .pure-menu-link:after {
+  content: "\25BE"; }
+
+/* scrollable menus */
+.pure-menu-scrollable {
+  overflow-y: scroll;
+  overflow-x: hidden; }
+
+.pure-menu-scrollable .pure-menu-list {
+  display: block; }
+
+.pure-menu-horizontal.pure-menu-scrollable .pure-menu-list {
+  display: inline-block; }
+
+.pure-menu-horizontal.pure-menu-scrollable {
+  white-space: nowrap;
+  overflow-y: hidden;
+  overflow-x: auto;
+  -ms-overflow-style: none;
+  -webkit-overflow-scrolling: touch;
+  /* a little extra padding for this style to allow for scrollbars */
+  padding: .5em 0; }
+
+.pure-menu-horizontal.pure-menu-scrollable::-webkit-scrollbar {
+  display: none; }
+
+/* misc default styling */
+.pure-menu-separator,
+.pure-menu-horizontal .pure-menu-children .pure-menu-separator {
+  background-color: #ccc;
+  height: 1px;
+  margin: .3em 0; }
+
+.pure-menu-horizontal .pure-menu-separator {
+  width: 1px;
+  height: 1.3em;
+  margin: 0 0.3em; }
+
+/* Need to reset the separator since submenu is vertical */
+.pure-menu-horizontal .pure-menu-children .pure-menu-separator {
+  display: block;
+  width: auto; }
+
+.pure-menu-heading {
+  text-transform: uppercase;
+  color: #565d64; }
+
+.pure-menu-link {
+  color: #777; }
+
+.pure-menu-children {
+  background-color: #fff; }
+
+.pure-menu-link,
+.pure-menu-disabled,
+.pure-menu-heading {
+  padding: .5em 1em; }
+
+.pure-menu-disabled {
+  opacity: .5; }
+
+.pure-menu-disabled .pure-menu-link:hover {
+  background-color: transparent; }
+
+.pure-menu-active > .pure-menu-link,
+.pure-menu-link:hover,
+.pure-menu-link:focus {
+  background-color: #eee; }
+
+.pure-menu-selected .pure-menu-link,
+.pure-menu-selected .pure-menu-link:visited {
+  color: #000; }
+
+.pure-table {
+  /* Remove spacing between table cells (from Normalize.css) */
+  border-collapse: collapse;
+  border-spacing: 0;
+  empty-cells: show;
+  border: 1px solid #cbcbcb; }
+
+.pure-table caption {
+  color: #000;
+  font: italic 85%/1 arial, sans-serif;
+  padding: 1em 0;
+  text-align: center; }
+
+.pure-table td,
+.pure-table th {
+  border-left: 1px solid #cbcbcb;
+  /*  inner column border */
+  border-width: 0 0 0 1px;
+  font-size: inherit;
+  margin: 0;
+  overflow: visible;
+  /*to make ths where the title is really long work*/
+  padding: 0.5em 1em;
+  /* cell padding */ }
+
+/* Consider removing this next declaration block, as it causes problems when
+there's a rowspan on the first cell. Case added to the tests. issue#432 */
+.pure-table td:first-child,
+.pure-table th:first-child {
+  border-left-width: 0; }
+
+.pure-table thead {
+  background-color: #e0e0e0;
+  color: #000;
+  text-align: left;
+  vertical-align: bottom; }
+
+/*
+striping:
+   even - #fff (white)
+   odd  - #f2f2f2 (light gray)
+*/
+.pure-table td {
+  background-color: transparent; }
+
+.pure-table-odd td {
+  background-color: #f2f2f2; }
+
+/* nth-child selector for modern browsers */
+.pure-table-striped tr:nth-child(2n-1) td {
+  background-color: #f2f2f2; }
+
+/* BORDERED TABLES */
+.pure-table-bordered td {
+  border-bottom: 1px solid #cbcbcb; }
+
+.pure-table-bordered tbody > tr:last-child > td {
+  border-bottom-width: 0; }
+
+/* HORIZONTAL BORDERED TABLES */
+.pure-table-horizontal td,
+.pure-table-horizontal th {
+  border-width: 0 0 1px 0;
+  border-bottom: 1px solid #cbcbcb; }
+
+.pure-table-horizontal tbody > tr:last-child > td {
+  border-bottom-width: 0; }
+
+/*# sourceMappingURL=pure.css.map */
diff --git a/packages/pogen/example/proj1/src/sample.ts 
b/packages/demobank-ui/src/style/index.css
similarity index 100%
copy from packages/pogen/example/proj1/src/sample.ts
copy to packages/demobank-ui/src/style/index.css
diff --git a/packages/demobank-ui/src/template.html 
b/packages/demobank-ui/src/template.html
new file mode 100644
index 000000000..6d8443130
--- /dev/null
+++ b/packages/demobank-ui/src/template.html
@@ -0,0 +1,52 @@
+<!--
+ This file is part of GNU Taler
+ (C) 2021--2022 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+
+ @author Sebastian Javier Marchano
+-->
+<!DOCTYPE html>
+<html lang="en" class="has-aside-left has-aside-mobile-transition 
has-navbar-fixed-top has-aside-expanded">
+       <head>
+               <meta charset="utf-8">
+               <title><%= htmlWebpackPlugin.options.title %></title>
+               <meta name="viewport" 
content="width=device-width,initial-scale=1">
+               <meta name="mobile-web-app-capable" content="yes">
+               <meta name="apple-mobile-web-app-capable" content="yes">
+
+               <link rel="icon" 
href="data:;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAD///////////////////////////////////////////////////////////////////////////////////////////////////7//v38//78/P/+/fz//vz7///+/v/+/f3//vz7///+/v/+/fz//v38///////////////////////+/v3///7+/////////////////////////////////////////////////////////v3//v79///////+/v3///////r28v/ct5//06SG/9Gffv/Xqo7/7N/V/9e2nf/bsJb/6uDW/9Sskf/euKH/+/j2///////+/v3//////+3azv+/eE3/2rWd/9Kkhv/Vr5
 [...]
+               <link rel="shortcut icon" href="data:image/x-icon;," 
type="image/x-icon" />
+
+               <% if (htmlWebpackPlugin.options.manifest.theme_color) { %>
+                       <meta name="theme-color" content="<%= 
htmlWebpackPlugin.options.manifest.theme_color %>">
+               <% } %>
+
+               <% for (const index in htmlWebpackPlugin.files.css) { %>
+                       <% const file = htmlWebpackPlugin.files.css[index] %>
+                       <style data-href='<%= file %>' >
+                               <%= 
compilation.assets[file.substr(htmlWebpackPlugin.files.publicPath.length)].source()
 %>
+                       </style>
+               <% } %>
+
+       </head>
+       <body>
+
+               <script>
+                       <%= 
compilation.assets[htmlWebpackPlugin.files.chunks["polyfills"].entry.substr(htmlWebpackPlugin.files.publicPath.length)].source()
 %>
+               </script>
+               <script>
+                       <%= 
compilation.assets[htmlWebpackPlugin.files.chunks["bundle"].entry.substr(htmlWebpackPlugin.files.publicPath.length)].source()
 %>
+               </script>
+
+       </body>
+</html>
diff --git a/packages/demobank-ui/tests/__mocks__/browserMocks.ts 
b/packages/demobank-ui/tests/__mocks__/browserMocks.ts
new file mode 100644
index 000000000..5be8c3ce6
--- /dev/null
+++ b/packages/demobank-ui/tests/__mocks__/browserMocks.ts
@@ -0,0 +1,21 @@
+// Mock Browser API's which are not supported by JSDOM, e.g. ServiceWorker, 
LocalStorage
+/**
+ * An example how to mock localStorage is given below 👇
+ */
+
+/* 
+// Mocks localStorage
+const localStorageMock = (function() {
+       let store = {};
+
+       return {
+               getItem: (key) => store[key] || null,
+               setItem: (key, value) => store[key] = value.toString(),
+               clear: () => store = {}
+       };
+
+})();
+
+Object.defineProperty(window, 'localStorage', {
+       value: localStorageMock
+}); */
diff --git a/packages/demobank-ui/tests/__mocks__/fileMocks.ts 
b/packages/demobank-ui/tests/__mocks__/fileMocks.ts
new file mode 100644
index 000000000..87109e355
--- /dev/null
+++ b/packages/demobank-ui/tests/__mocks__/fileMocks.ts
@@ -0,0 +1,3 @@
+// This fixed an error related to the CSS and loading gif breaking my Jest test
+// See 
https://facebook.github.io/jest/docs/en/webpack.html#handling-static-assets
+export default 'test-file-stub';
diff --git a/packages/demobank-ui/tests/__mocks__/setupTests.ts 
b/packages/demobank-ui/tests/__mocks__/setupTests.ts
new file mode 100644
index 000000000..b0bebb589
--- /dev/null
+++ b/packages/demobank-ui/tests/__mocks__/setupTests.ts
@@ -0,0 +1,6 @@
+import { configure } from 'enzyme';
+import Adapter from 'enzyme-adapter-preact-pure';
+
+configure({
+  adapter: new Adapter() as any
+});
diff --git a/packages/demobank-ui/tests/__tests__/homepage.js 
b/packages/demobank-ui/tests/__tests__/homepage.js
new file mode 100644
index 000000000..9ea0ed410
--- /dev/null
+++ b/packages/demobank-ui/tests/__tests__/homepage.js
@@ -0,0 +1,466 @@
+import "core-js/stable";
+import "regenerator-runtime/runtime";
+import "@testing-library/jest-dom";
+import { BankHome } from '../../src/pages/home';
+import { h } from 'preact';
+import { waitFor, cleanup, render, fireEvent, screen } from 
'@testing-library/preact';
+import expect from 'expect';
+import fetchMock from "jest-fetch-mock";
+
+/**
+ * This mock makes the translator always return the
+ * english string.  It didn't work within the 'beforeAll'
+ * function...
+ */
+jest.mock("../../src/i18n")
+const i18n = require("../../src/i18n")
+i18n.useTranslator.mockImplementation(() => function(arg) {return arg})
+
+beforeAll(() => {
+  Object.defineProperty(window, 'location', {
+    value: {
+      origin: "http://localhost";,
+      pathname: "/demobanks/default"
+    }
+  })
+  global.Storage.prototype.setItem = jest.fn((key, value) => {})
+})
+
+function fillCredentialsForm() {
+  const username = Math.random().toString().substring(2);
+  const u = screen.getByPlaceholderText("username");
+  const p = screen.getByPlaceholderText("password");
+  fireEvent.input(u, {target: {value: username}})
+  fireEvent.input(p, {target: {value: "bar"}})
+  const signinButton = screen.getByText("Login");
+  return {
+    username: username,
+    signinButton: signinButton
+  };
+}
+fetchMock.enableMocks();
+
+function mockSuccessLoginOrRegistration() {
+  fetch.once("{}", {
+    status: 200
+  }).once(JSON.stringify({
+    balance: {
+      amount: "EUR:10",
+      credit_debit_indicator: "credit"
+    },
+    paytoUri: "payto://iban/123/ABC"
+  }))
+}
+
+/**
+ * Render homepage -> navigate to register page -> submit registration.
+ * 'webMock' is called before submission to mock the server response
+ */
+function signUp(context, webMock) {
+  render(<BankHome />);
+  const registerPage = screen.getByText("Register!");
+  fireEvent.click(registerPage);
+  const username = Math.random().toString().substring(2);
+  const u = screen.getByPlaceholderText("username");
+  const p = screen.getByPlaceholderText("password");
+  fireEvent.input(u, {target: {value: username}})
+  fireEvent.input(p, {target: {value: "bar"}})
+  const registerButton = screen.getByText("Register");
+  webMock();
+  fireEvent.click(registerButton);
+  context.username = username;
+  return context;
+}
+
+describe("wire transfer", () => {
+  beforeEach(() => {
+    signUp({}, mockSuccessLoginOrRegistration); // context unused
+  })
+  test("Wire transfer success", async () => {
+    const transferButton = screen.getByText("Create wire transfer");
+    const payto = screen.getByPlaceholderText("payto address");
+    fireEvent.input(payto, {target: {value: 
"payto://only-checked-by-the-backend!"}})
+    fetch.once("{}"); // 200 OK
+    fireEvent.click(transferButton);
+    await screen.findByText("wire transfer created", {exact: false})
+  })
+  test("Wire transfer fail", async () => {
+    const transferButton = screen.getByText("Create wire transfer");
+    const payto = screen.getByPlaceholderText("payto address");
+    fireEvent.input(payto, {target: {value: 
"payto://only-checked-by-the-backend!"}})
+    fetch.once("{}", {status: 400});
+    fireEvent.click(transferButton);
+    // assert this below does NOT appear.
+    await waitFor(() => expect(
+      screen.queryByText("wire transfer created", {exact: 
false})).not.toBeInTheDocument());
+  })
+})
+
+describe("withdraw", () => {
+  afterEach(() => {
+    fetch.resetMocks();
+    cleanup();
+  })
+
+
+  let context = {};
+  // Register and land on the profile page.
+  beforeEach(() => {
+    context = signUp(context, mockSuccessLoginOrRegistration); 
+  })
+
+  test("network failure before withdrawal creation", async () => {
+    const a = screen.getAllByPlaceholderText("amount")[0];
+    fireEvent.input(a, {target: {value: "10"}});
+    let withdrawButton = screen.getByText("Charge Taler wallet");
+    // mock network failure.
+    fetch.mockReject("API is down");
+    fireEvent.click(withdrawButton);
+    await screen.findByText("could not create withdrawal operation", {exact: 
false})
+  })
+
+  test("HTTP response error upon withdrawal creation", async () => {
+    const a = screen.getAllByPlaceholderText("amount")[0];
+    fireEvent.input(a, {target: {value: "10,0"}});
+    let withdrawButton = screen.getByText("Charge Taler wallet");
+    fetch.once("{}", {status: 404});
+    fireEvent.click(withdrawButton);
+    await screen.findByText("gave response error", {exact: false})
+  })
+
+  test("Abort withdrawal", async () => {
+    const a = screen.getAllByPlaceholderText("amount")[0];
+    fireEvent.input(a, {target: {value: "10,0"}});
+    let withdrawButton = screen.getByText("Charge Taler wallet");
+    fetch.once(JSON.stringify({
+      taler_withdraw_uri: "taler://withdraw/foo",
+      withdrawal_id: "foo"
+    }));
+    /**
+     * After triggering a withdrawal, check if the taler://withdraw URI
+     * rendered, and confirm if so.  Lastly, check that a success message
+     * appeared on the screen.
+     */
+    fireEvent.click(withdrawButton);
+    const abortButton = await screen.findByText("abort withdrawal", {exact: 
false})
+    fireEvent.click(abortButton);
+    expect(fetch).toHaveBeenLastCalledWith(
+    
`http://localhost/demobanks/default/access-api/accounts/${context.username}/withdrawals/foo/abort`,
+    expect.anything()
+    )
+    await waitFor(() => expect(
+      screen.queryByText("abort withdrawal", {exact: 
false})).not.toBeInTheDocument());
+  })
+
+  test("Successful withdrawal creation and confirmation", async () => {
+    const a = screen.getAllByPlaceholderText("amount")[0];
+    fireEvent.input(a, {target: {value: "10,0"}});
+    let withdrawButton = await screen.findByText("Charge Taler wallet");
+    fetch.once(JSON.stringify({
+      taler_withdraw_uri: "taler://withdraw/foo",
+      withdrawal_id: "foo"
+    }));
+    /**
+     * After triggering a withdrawal, check if the taler://withdraw URI
+     * rendered, and confirm if so.  Lastly, check that a success message
+     * appeared on the screen.  */
+    fireEvent.click(withdrawButton);
+    expect(fetch).toHaveBeenCalledWith(
+      
`http://localhost/demobanks/default/access-api/accounts/${context.username}/withdrawals`,
+      expect.objectContaining({body: JSON.stringify({amount: "EUR:10.0"})})
+    )
+    // assume wallet POSTed the payment details.
+    const confirmButton = await screen.findByText("confirm withdrawal", 
{exact: false})
+    /**
+     * Not expecting a new withdrawal possibility while one is being processed.
+     */
+    await waitFor(() => expect(
+      screen.queryByText("charge taler wallet", {exact: 
false})).not.toBeInTheDocument());
+    fetch.once("{}")
+    // Confirm currently processed withdrawal.
+    fireEvent.click(confirmButton);
+    /**
+     * After having confirmed above, wait that the
+     * pre-withdrawal elements disappears and a success
+     * message appears.
+     */
+    await waitFor(() => expect(
+      screen.queryByText(
+        "confirm withdrawal",
+       {exact: false})).not.toBeInTheDocument()
+    );
+    await waitFor(() => expect(
+      screen.queryByText(
+        "give this address to the taler wallet",
+        {exact: false})).not.toBeInTheDocument()
+    );
+    expect(fetch).toHaveBeenLastCalledWith(
+    
`http://localhost/demobanks/default/access-api/accounts/${context.username}/withdrawals/foo/confirm`,
+    expect.anything())
+    // success message
+    await screen.findByText("withdrawal confirmed", {exact: false})
+
+    /**
+     * Click on a "return to homepage / close" button, and
+     * check that the withdrawal confirmation is gone, and
+     * the option to withdraw again reappeared.
+     */
+    const closeButton = await screen.findByText("close", {exact: false})
+    fireEvent.click(closeButton);
+
+    /**
+     * After closing the operation, the confirmation message is not expected.
+     */
+    await waitFor(() => expect(
+      screen.queryByText("withdrawal confirmed", {exact: 
false})).not.toBeInTheDocument()
+    );
+
+    /**
+     * After closing the operation, the possibility to withdraw again should 
be offered.
+     */
+    await waitFor(() => expect(
+      screen.queryByText(
+        "charge taler wallet",
+        {exact: false})).toBeInTheDocument()
+    );
+  })
+})
+
+describe("home page", () => {
+  afterEach(() => {
+    fetch.resetMocks();
+    cleanup();
+  })
+  test("public histories", async () => {
+    render(<BankHome />);
+    /**
+     * Mock list of public accounts.  'bar' is
+     * the shown account, since it occupies the last
+     * position (and SPA picks it via the 'pop()' method) */
+    fetch.once(JSON.stringify({
+      "publicAccounts" : [ {
+        "balance" : "EUR:1",
+        "iban" : "XXX",
+        "accountLabel" : "foo"
+      }, {
+        "balance" : "EUR:2",
+        "iban" : "YYY",
+        "accountLabel" : "bar"
+      }]
+    })).once(JSON.stringify({
+      transactions: [{
+        debtorIban: "XXX",
+        debtorBic: "YYY",
+        debtorName: "Foo",
+        creditorIban: "AAA",
+        creditorBic: "BBB",
+        creditorName: "Bar",
+       direction: "DBIT",
+        amount: "EUR:5",
+       subject: "Reimbursement",
+       date: "1970-01-01"
+      }, {
+        debtorIban: "XXX",
+        debtorBic: "YYY",
+        debtorName: "Foo",
+        creditorIban: "AAA",
+        creditorBic: "BBB",
+        creditorName: "Bar",
+       direction: "CRDT",
+        amount: "EUR:5",
+       subject: "Bonus",
+       date: "2000-01-01"
+      }]
+    })).once(JSON.stringify({ 
+      transactions: [{
+        debtorIban: "XXX",
+        debtorBic: "YYY",
+        debtorName: "Foo",
+        creditorIban: "AAA",
+        creditorBic: "BBB",
+        creditorName: "Bar",
+       direction: "DBIT",
+        amount: "EUR:5",
+       subject: "Donation",
+       date: "1970-01-01"
+      }, {
+        debtorIban: "XXX",
+        debtorBic: "YYY",
+        debtorName: "Foo",
+        creditorIban: "AAA",
+        creditorBic: "BBB",
+        creditorName: "Bar",
+       direction: "CRDT",
+        amount: "EUR:5",
+       subject: "Refund",
+       date: "2000-01-01"
+      }]
+    }))
+
+    // Navigate to dedicate public histories page.
+    const publicTxsPage = screen.getByText("transactions");
+    fireEvent.click(publicTxsPage);
+
+    /**
+     * Check that transactions data appears on the page.
+     */
+    await screen.findByText("reimbursement", {exact: false});
+    await screen.findByText("bonus", {exact: false});
+    /**
+     * The transactions below should not appear, because only
+     * one public account renders.
+     */
+    await waitFor(() => expect(
+      screen.queryByText("refund", {exact: false})).not.toBeInTheDocument());
+    await waitFor(() => expect(
+      screen.queryByText("donation", {exact: false})).not.toBeInTheDocument());
+    /**
+     * First HTTP mock:
+     */
+    await expect(fetch).toHaveBeenCalledWith(
+      "http://localhost/demobanks/default/access-api/public-accounts";
+    )
+    /**
+     * Only expecting this request (second mock), as SWR doesn't let
+     * the unshown history request to the backend:
+     */
+    await expect(fetch).toHaveBeenCalledWith(
+      
"http://localhost/demobanks/default/access-api/accounts/bar/transactions?page=0";
+    )
+    /**
+     * Switch tab:
+     */
+    let fooTab = await screen.findByText("foo", {exact: false});
+    fireEvent.click(fooTab);
+    /**
+     * Last two HTTP mocks should render now:
+     */
+    await screen.findByText("refund", {exact: false});
+    await screen.findByText("donation", {exact: false});
+
+    // Expect SWR to have requested 'foo' history
+    // (consuming the last HTTP mock):
+    await expect(fetch).toHaveBeenCalledWith(
+      
"http://localhost/demobanks/default/access-api/accounts/foo/transactions?page=0";
+    )
+    let backButton = await screen.findByText("Go back", {exact: false});
+    fireEvent.click(backButton);
+    await waitFor(() => expect(
+      screen.queryByText("donation", {exact: false})).not.toBeInTheDocument());
+    await screen.findByText("welcome to eufin bank", {exact: false})
+  })
+
+  // check page informs about the current balance
+  // after a successful registration.
+
+  test("new registration response error 404", async () => {
+    var context = signUp({}, () => fetch.mockResponseOnce("Not found", 
{status: 404}));
+    await screen.findByText("has a problem", {exact: false});
+    expect(fetch).toHaveBeenCalledWith(
+      "http://localhost/demobanks/default/access-api/testing/register";,
+      expect.objectContaining(
+        {body: JSON.stringify({username: context.username, password: "bar"}), 
method: "POST"},
+    ))
+  })
+
+  test("registration network failure", async () => {
+    let context = signUp({}, ()=>fetch.mockReject("API is down"));
+    await screen.findByText("has a problem", {exact: false});
+    expect(fetch).toHaveBeenCalledWith(
+      "http://localhost/demobanks/default/access-api/testing/register";,
+      expect.objectContaining(
+        {body: JSON.stringify({username: context.username, password: "bar"}), 
method: "POST"}
+      ))
+  })
+  
+  test("login non existent user", async () => {
+    render(<BankHome />);
+    const { username, signinButton } = fillCredentialsForm();
+    fetch.once("{}", {status: 404});
+    fireEvent.click(signinButton);
+    await screen.findByText("username or account label not found", {exact: 
false})
+  })
+  test("login wrong credentials", async () => {
+    render(<BankHome />);
+    const { username, signinButton } = fillCredentialsForm();
+    fetch.once("{}", {status: 401});
+    fireEvent.click(signinButton);
+    await screen.findByText("wrong credentials given", {exact: false})
+  })
+
+  /**
+   * Test that balance and last transactions get shown
+   * after a successful login.
+   */
+  test("login success", async () => {
+    render(<BankHome />);
+    const { username, signinButton } = fillCredentialsForm();
+    
+    // Response to balance request.
+    fetch.once(JSON.stringify({
+      balance: {
+        amount: "EUR:10",
+       credit_debit_indicator: "credit"
+      },
+      paytoUri: "payto://iban/123/ABC"
+    })).once(JSON.stringify({ // Response to history request.
+      transactions: [{
+        debtorIban: "XXX",
+        debtorBic: "YYY",
+        debtorName: "Foo",
+        creditorIban: "AAA",
+        creditorBic: "BBB",
+        creditorName: "Bar",
+       direction: "DBIT",
+        amount: "EUR:5",
+       subject: "Donation",
+       date: "01-01-1970"
+      }, {
+        debtorIban: "XXX",
+        debtorBic: "YYY",
+        debtorName: "Foo",
+        creditorIban: "AAA",
+        creditorBic: "BBB",
+        creditorName: "Bar",
+       direction: "CRDT",
+        amount: "EUR:5",
+       subject: "Refund",
+       date: "01-01-2000"
+      }]
+    }))
+    fireEvent.click(signinButton);
+    expect(fetch).toHaveBeenCalledWith(
+      `http://localhost/demobanks/default/access-api/accounts/${username}`,
+      expect.anything()
+    )
+    await screen.findByText("balance is 10 EUR", {exact: false})
+    // The two transactions in the history mocked above.
+    await screen.findByText("refund", {exact: false})
+    await screen.findByText("donation", {exact: false})
+    expect(fetch).toHaveBeenCalledWith(
+      
`http://localhost/demobanks/default/access-api/accounts/${username}/transactions?page=0`,
+      expect.anything()
+    )
+  })
+
+  test("registration success", async () => {
+    let context = signUp({}, mockSuccessLoginOrRegistration);
+    /**
+     * Tests that a balance is shown after the successful
+     * registration.
+     */
+    await screen.findByText("balance is 10 EUR", {exact: false})
+    /**
+     * The expectation below tests whether the account
+     * balance was requested after the successful registration.
+     */
+    expect(fetch).toHaveBeenCalledWith(
+      "http://localhost/demobanks/default/access-api/testing/register";,
+      expect.anything() // no need to match auth headers.
+    )
+    expect(fetch).toHaveBeenCalledWith(
+      
`http://localhost/demobanks/default/access-api/accounts/${context.username}`,
+      expect.anything() // no need to match auth headers.
+    )
+  })
+})
diff --git a/packages/demobank-ui/tests/declarations.d.ts 
b/packages/demobank-ui/tests/declarations.d.ts
new file mode 100644
index 000000000..67e940277
--- /dev/null
+++ b/packages/demobank-ui/tests/declarations.d.ts
@@ -0,0 +1,3 @@
+// Enable enzyme adapter's integration with TypeScript
+// See: 
https://github.com/preactjs/enzyme-adapter-preact-pure#usage-with-typescript
+/// <reference types="enzyme-adapter-preact-pure" />
diff --git a/packages/demobank-ui/tsconfig.json 
b/packages/demobank-ui/tsconfig.json
new file mode 100644
index 000000000..d04c5b964
--- /dev/null
+++ b/packages/demobank-ui/tsconfig.json
@@ -0,0 +1,60 @@
+{
+  "compilerOptions": {
+    /* Basic Options */
+    "target": "ES5" /* Specify ECMAScript target version: 'ES3' (default), 
'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */,
+    "module": "ESNext" /* Specify module code generation: 'none', commonjs', 
'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
+    // "lib": [],                             /* Specify library files to be 
included in the compilation:  */
+    "allowJs": true /* Allow javascript files to be compiled. */,
+    // "checkJs": true,                       /* Report errors in .js files. */
+    "jsx": "react" /* Specify JSX code generation: 'preserve', 'react-native', 
or 'react'. */,
+    "jsxFactory": "h" /* Specify the JSX factory function to use when 
targeting react JSX emit, e.g. React.createElement or h. */,
+    // "declaration": true,                   /* Generates corresponding 
'.d.ts' file. */
+    // "sourceMap": true,                     /* Generates corresponding 
'.map' file. */
+    // "outFile": "./",                       /* Concatenate and emit output 
to single file. */
+    // "outDir": "./",                        /* Redirect output structure to 
the directory. */
+    // "rootDir": "./",                       /* Specify the root directory of 
input files. Use to control the output directory structure with --outDir. */
+    // "removeComments": true,                /* Do not emit comments to 
output. */
+    "noEmit": true /* Do not emit outputs. */,
+    // "importHelpers": true,                 /* Import emit helpers from 
'tslib'. */
+    // "downlevelIteration": true,            /* Provide full support for 
iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. 
*/
+    // "isolatedModules": true,               /* Transpile each file as a 
separate module (similar to 'ts.transpileModule'). */
+
+    /* Strict Type-Checking Options */
+    "strict": true /* Enable all strict type-checking options. */,
+    // "noImplicitAny": true,                 /* Raise error on expressions 
and declarations with an implied 'any' type. */
+    // "strictNullChecks": true,              /* Enable strict null checks. */
+    // "noImplicitThis": true,                /* Raise error on 'this' 
expressions with an implied 'any' type. */
+    // "alwaysStrict": true,                  /* Parse in strict mode and emit 
"use strict" for each source file. */
+
+    /* Additional Checks */
+    // "noUnusedLocals": true,                /* Report errors on unused 
locals. */
+    // "noUnusedParameters": true,            /* Report errors on unused 
parameters. */
+    // "noImplicitReturns": true,             /* Report error when not all 
code paths in function return a value. */
+    // "noFallthroughCasesInSwitch": true,    /* Report errors for fallthrough 
cases in switch statement. */
+
+    /* Module Resolution Options */
+    "moduleResolution": "node" /* Specify module resolution strategy: 'node' 
(Node.js) or 'classic' (TypeScript pre-1.6). */,
+    "esModuleInterop": true /* */,
+    // "baseUrl": "./",                       /* Base directory to resolve 
non-absolute module names. */
+    // "paths": {},                           /* A series of entries which 
re-map imports to lookup locations relative to the 'baseUrl'. */
+    // "rootDirs": [],                        /* List of root folders whose 
combined content represents the structure of the project at runtime. */
+    // "typeRoots": [],                       /* List of folders to include 
type definitions from. */
+    // "types": [],                           /* Type declaration files to be 
included in compilation. */
+    // "allowSyntheticDefaultImports": true,  /* Allow default imports from 
modules with no default export. This does not affect code emit, just 
typechecking. */
+    // "preserveSymlinks": true,              /* Do not resolve the real path 
of symlinks. */
+
+    /* Source Map Options */
+    // "sourceRoot": "./",                    /* Specify the location where 
debugger should locate TypeScript files instead of source locations. */
+    // "mapRoot": "./",                       /* Specify the location where 
debugger should locate map files instead of generated locations. */
+    // "inlineSourceMap": true,               /* Emit a single file with 
source maps instead of having a separate file. */
+    // "inlineSources": true,                 /* Emit the source alongside the 
sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' 
to be set. */
+
+    /* Experimental Options */
+    // "experimentalDecorators": true,        /* Enables experimental support 
for ES7 decorators. */
+    // "emitDecoratorMetadata": true,         /* Enables experimental support 
for emitting type metadata for decorators. */
+
+    /* Advanced Options */
+    "skipLibCheck": true /* Skip type checking of declaration files. */
+  },
+  "include": ["src/**/*", "tests/**/*"]
+}
diff --git a/packages/merchant-backend-ui/.gitignore 
b/packages/merchant-backend-ui/.gitignore
new file mode 100644
index 000000000..a6ee22df2
--- /dev/null
+++ b/packages/merchant-backend-ui/.gitignore
@@ -0,0 +1,9 @@
+/build
+/size-plugin.json
+/storybook-static
+/docs
+/single
+/coverage
+/dist
+/.rollup.cache
+/.linaria-cache
diff --git a/packages/merchant-backend-ui/.storybook/.babelrc 
b/packages/merchant-backend-ui/.storybook/.babelrc
new file mode 100644
index 000000000..610b6f339
--- /dev/null
+++ b/packages/merchant-backend-ui/.storybook/.babelrc
@@ -0,0 +1,25 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+{
+    "presets": [
+        "preact-cli/babel"
+    ]
+}
\ No newline at end of file
diff --git a/packages/merchant-backend-ui/.storybook/main.js 
b/packages/merchant-backend-ui/.storybook/main.js
new file mode 100644
index 000000000..5497a6510
--- /dev/null
+++ b/packages/merchant-backend-ui/.storybook/main.js
@@ -0,0 +1,82 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+
+module.exports = {
+  "stories": [
+    "../src/**/*.stories.mdx",
+    "../src/**/*.stories.@(js|jsx|ts|tsx)"
+  ],
+  "addons": [
+    "@storybook/preset-scss",
+    "@storybook/addon-a11y",
+    "@storybook/addon-essentials" //docs, control, actions, viewpot, toolbar, 
background
+  ],
+  // sb does not yet support new jsx transform by default
+  // https://github.com/storybookjs/storybook/issues/12881
+  // https://github.com/storybookjs/storybook/issues/12952
+  babel: async (options) => ({
+    ...options,
+    presets: [
+      ...options.presets,
+      [
+        '@babel/preset-react', {
+          runtime: 'automatic',
+        },
+        'preset-react-jsx-transform' 
+      ],
+      "@linaria",
+    ],
+  }),
+  webpackFinal: (config) => {
+    // should be removed after storybook 6.3
+    // 
https://github.com/storybookjs/storybook/issues/12853#issuecomment-821576113
+    config.resolve.alias = {
+      react: "preact/compat",
+      "react-dom": "preact/compat",
+    };
+
+    // we need to add @linaria loader AFTER the babel-loader
+    // 
https://github.com/callstack/linaria/blob/master/docs/BUNDLERS_INTEGRATION.md#webpack
  
+    config.module.rules[0] = {
+      ...(config.module.rules[0]),
+      loader: undefined, // Disable the predefined babel-loader on the rule
+      use: [
+        {
+          ...(config.module.rules[0].use[0]),
+          loader: 'babel-loader',          
+        },
+        {
+          loader: '@linaria/webpack-loader',
+          options: {
+            sourceMap: true, //always true since this is dev
+            babelOptions: {
+              presets: config.module.rules[0].use[0].options.presets,
+            }
+             // Pass the current babel options to linaria's babel instance
+          }
+        }
+      ]
+    };
+
+    return config;
+  },
+}
\ No newline at end of file
diff --git a/packages/merchant-backend-ui/.storybook/preview.js 
b/packages/merchant-backend-ui/.storybook/preview.js
new file mode 100644
index 000000000..a9cc4c39a
--- /dev/null
+++ b/packages/merchant-backend-ui/.storybook/preview.js
@@ -0,0 +1,73 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+import { ConfigContextProvider } from '../src/context/config'
+import { InstanceContextProvider } from '../src/context/instance'
+import { TranslationProvider } from '../src/context/translation'
+import { BackendContextProvider } from '../src/context/backend'
+import { h } from 'preact';
+
+const mockConfig = {
+  backendURL: 'http://demo.taler.net',
+  currency: 'TESTKUDOS'
+}
+
+const mockInstance = {
+  id: 'instance-id',
+  token: 'instance-token',
+  admin: false,
+}
+
+const mockBackend = {
+  url: 'http://merchant.url',
+  token: 'default-token',
+  triedToLog: false,
+}
+
+export const parameters = {
+  controls: { expanded: true },
+  // actions: { argTypesRegex: "^on.*" },
+}
+
+export const globalTypes = {
+  locale: {
+    name: 'Locale',
+    description: 'Internationalization locale',
+    defaultValue: 'en',
+    toolbar: {
+      icon: 'globe',
+      items: [
+        { value: 'en', right: '🇺🇸', title: 'English' },
+        { value: 'es', right: '🇪🇸', title: 'Spanish' },
+      ],
+    },
+  },
+};
+
+export const decorators = [
+  (Story, { globals }) => <TranslationProvider initial='en' 
forceLang={globals.locale}>
+    <Story />
+  </TranslationProvider>,
+  (Story) => <ConfigContextProvider value={mockConfig}>
+    <Story />
+  </ConfigContextProvider>,
+  (Story) => <InstanceContextProvider value={mockInstance}>
+    <Story />
+  </InstanceContextProvider>,
+  (Story) => <BackendContextProvider defaultUrl={mockBackend.url}>
+    <Story />
+  </BackendContextProvider>,
+];
diff --git a/packages/merchant-backend-ui/README.md 
b/packages/merchant-backend-ui/README.md
new file mode 100644
index 000000000..16cbd0b9a
--- /dev/null
+++ b/packages/merchant-backend-ui/README.md
@@ -0,0 +1,30 @@
+Merchant Backend pages
+
+# Description
+
+This project generate 5 templates for the merchant backend:
+
+ * DepletedTip
+ * OfferRefund
+ * OfferTip
+ * RequestPayment
+ * ShowOrderDetails
+
+This pages are to be serve from the merchant-backend service and will be 
queried for browser that may or may not have javascript enabled, so we are 
going to do server side rendering.
+The merchant-backend service is currently supporting mustache library for 
server side rendering. 
+We also want the be able to create a more interactive design if the browser 
have javascript enabled, so the pages will be serve with all the infromation in 
the html but also in javascript.
+
+In this scenario, we are using jsx to build the template of the page that will 
be build-time rendered into the mustache template. This template can the be 
deployed into a merchant-backend that will complete the information before send 
it to the browser.
+
+# Building
+
+The building process can be executed with `pnpm build`
+
+# Testing
+
+This project is using a javascript implementation of mustache that can be 
executed with the command `pnpm render-examples`.
+This script will take the pages previously built in `dist/pages` directory and 
the examples definition in the `src/pages/[exampleName].examples.ts` files and 
render a to-be-sent-to-the-user page like the merchant would do.
+This examples will be saved invidivualy into directory `dist/examples` and 
should be opened with your testing browser.
+Testing should be done with javascript enabled and javascript disabled, both 
should look ok. 
+
+
diff --git a/contrib/po2ts b/packages/merchant-backend-ui/contrib/po2ts
similarity index 100%
copy from contrib/po2ts
copy to packages/merchant-backend-ui/contrib/po2ts
diff --git a/packages/merchant-backend-ui/copyleft-header.js 
b/packages/merchant-backend-ui/copyleft-header.js
new file mode 100644
index 000000000..0794cb839
--- /dev/null
+++ b/packages/merchant-backend-ui/copyleft-header.js
@@ -0,0 +1,15 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
diff --git a/packages/merchant-backend-ui/package.json 
b/packages/merchant-backend-ui/package.json
new file mode 100644
index 000000000..4a30def96
--- /dev/null
+++ b/packages/merchant-backend-ui/package.json
@@ -0,0 +1,144 @@
+{
+  "private": true,
+  "name": "merchant-backend",
+  "version": "0.0.4",
+  "license": "MIT",
+  "scripts": {
+    "build": "rollup -c",
+    "dev": "rollup -c -w",
+    "render-examples": "ts-node -O '{\"module\": \"commonjs\"}' -T 
render-examples.ts dist/pages dist/examples",
+    "lint-check": "eslint '{src,tests}/**/*.{js,jsx,ts,tsx}'",
+    "lint-fix": "eslint --fix '{src,tests}/**/*.{js,jsx,ts,tsx}'",
+    "test": "jest ./tests",
+    "dev-test": "jest ./tests --watch",
+    "typedoc": "typedoc src",
+    "clean": "rimraf build storybook-static docs single dist",
+    "serve-dist": "sirv --port ${PORT:=8080} --cors --single dist",
+    "build-storybook": "build-storybook",
+    "storybook": "start-storybook -p 6006"
+  },
+  "engines": {
+    "node": ">=12",
+    "pnpm": ">=5"
+  },
+  "eslintConfig": {
+    "parser": "@typescript-eslint/parser",
+    "extends": [
+      "preact",
+      "plugin:@typescript-eslint/recommended"
+    ],
+    "plugins": [
+      "header"
+    ],
+    "rules": {
+      "header/header": [
+        2,
+        "copyleft-header.js"
+      ]
+    },
+    "ignorePatterns": [
+      "build/"
+    ]
+  },
+  "dependencies": {
+    "@gnu-taler/taler-util": "workspace:*",
+    "axios": "^0.21.1",
+    "date-fns": "^2.21.1",
+    "history": "4.10.1",
+    "jed": "^1.1.1",
+    "preact": "^10.5.13",
+    "preact-router": "^3.2.1",
+    "qrcode-generator": "^1.4.4",
+    "swr": "^0.5.5",
+    "yup": "^0.32.9"
+  },
+  "devDependencies": {
+    "@babel/core": "^7.13.16",
+    "@babel/plugin-transform-react-jsx-source": "^7.12.13",
+    "@creativebulma/bulma-tooltip": "^1.2.0",
+    "@gnu-taler/pogen": "^0.0.5",
+    "@linaria/babel-preset": "^3.0.0-beta.4",
+    "@linaria/core": "^3.0.0-beta.4",
+    "@linaria/react": "^3.0.0-beta.7",
+    "@linaria/rollup": "^3.0.0-beta.7",
+    "@linaria/shaker": "^3.0.0-beta.7",
+    "@linaria/webpack-loader": "^3.0.0-beta.7",
+    "@rollup/plugin-alias": "^3.1.5",
+    "@rollup/plugin-babel": "^5.3.0",
+    "@rollup/plugin-commonjs": "^20.0.0",
+    "@rollup/plugin-html": "^0.2.3",
+    "@rollup/plugin-image": "^2.1.1",
+    "@rollup/plugin-json": "^4.1.0",
+    "@rollup/plugin-replace": "^3.0.0",
+    "@rollup/plugin-typescript": "^8.2.5",
+    "@storybook/addon-a11y": "^6.2.9",
+    "@storybook/addon-actions": "^6.2.9",
+    "@storybook/addon-essentials": "^6.2.9",
+    "@storybook/addon-links": "^6.2.9",
+    "@storybook/preact": "^6.2.9",
+    "@storybook/preset-scss": "^1.0.3",
+    "@testing-library/preact": "^2.0.1",
+    "@testing-library/preact-hooks": "^1.1.0",
+    "@types/enzyme": "^3.10.8",
+    "@types/history": "^4.7.8",
+    "@types/jest": "^26.0.23",
+    "@types/mocha": "^8.2.2",
+    "@types/mustache": "^4.1.2",
+    "@typescript-eslint/eslint-plugin": "^4.22.0",
+    "@typescript-eslint/parser": "^4.22.0",
+    "babel-loader": "^8.2.2",
+    "base64-inline-loader": "^1.1.1",
+    "bulma": "^0.9.2",
+    "bulma-checkbox": "^1.1.1",
+    "bulma-radio": "^1.1.1",
+    "bulma-responsive-tables": "^1.2.3",
+    "bulma-switch-control": "^1.1.1",
+    "bulma-timeline": "^3.0.4",
+    "bulma-upload-control": "^1.2.0",
+    "dotenv": "^8.2.0",
+    "enzyme": "^3.11.0",
+    "enzyme-adapter-preact-pure": "^3.1.0",
+    "eslint": "^7.25.0",
+    "eslint-config-preact": "^1.1.4",
+    "eslint-plugin-header": "^3.1.1",
+    "html-webpack-inline-chunk-plugin": "^1.1.1",
+    "html-webpack-inline-source-plugin": "0.0.10",
+    "html-webpack-skip-assets-plugin": "^1.0.1",
+    "inline-chunk-html-plugin": "^1.1.1",
+    "jest": "^26.6.3",
+    "jest-preset-preact": "^4.0.2",
+    "mustache": "^4.2.0",
+    "po2json": "^0.4.5",
+    "preact-cli": "^3.0.5",
+    "preact-render-to-json": "^3.6.6",
+    "preact-render-to-string": "^5.1.19",
+    "rimraf": "^3.0.2",
+    "rollup": "^2.56.3",
+    "rollup-plugin-bundle-html": "^0.2.2",
+    "rollup-plugin-css-only": "^3.1.0",
+    "sass": "^1.32.13",
+    "sass-loader": "10.1.1",
+    "script-ext-html-webpack-plugin": "^2.1.5",
+    "sirv-cli": "^1.0.11",
+    "tslib": "^2.3.1",
+    "typedoc": "^0.20.36",
+    "typescript": "^4.2.4"
+  },
+  "jest": {
+    "preset": "jest-preset-preact",
+    "transformIgnorePatterns": [
+      "node_modules/.pnpm/(?!(@gnu-taler\\+taler-util))",
+      "\\.pnp\\.[^\\/]+$"
+    ],
+    "setupFiles": [
+      "<rootDir>/tests/__mocks__/browserMocks.ts",
+      "<rootDir>/tests/__mocks__/setupTests.ts"
+    ],
+    "moduleNameMapper": {
+      "\\.(css|less)$": "identity-obj-proxy"
+    },
+    "transform": {
+      
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga|po)$":
 "<rootDir>/tests/__mocks__/fileTransformer.js"
+    }
+  }
+}
diff --git a/packages/merchant-backend-ui/render-examples.ts 
b/packages/merchant-backend-ui/render-examples.ts
new file mode 100644
index 000000000..47300ab8f
--- /dev/null
+++ b/packages/merchant-backend-ui/render-examples.ts
@@ -0,0 +1,83 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import mustache from "mustache";
+import fs from "fs";
+import { format, formatDuration, intervalToDuration } from "date-fns";
+
+/**
+ * This script will emulate what the merchant backend will do when being 
requested
+ * 
+*/
+
+const sourceDirectory = process.argv[2]
+const destDirectory = process.argv[3]
+
+if (!sourceDirectory || !destDirectory) {
+       console.log('usage: render-mustache <source-directory> 
<dest-directory>')
+       process.exit(1);
+}
+
+if (!fs.existsSync(destDirectory)) {
+       fs.mkdirSync(destDirectory);
+}
+
+/**
+ * Load all the html files
+ */
+const files = fs.readdirSync(sourceDirectory).filter(f => /.html/.test(f))
+
+files.forEach(file => {
+       const html = fs.readFileSync(`${sourceDirectory}/${file}`, 'utf8')
+
+       const testName = file.replace('.html', '')
+       if (testName !== 'ShowOrderDetails') return;
+       // eslint-disable-next-line @typescript-eslint/no-var-requires
+       const { exampleData } = require(`./src/pages/${testName}.examples`)
+
+       Object.keys(exampleData).forEach(exampleName => {
+               const example = exampleData[exampleName]
+
+               //enhance the example with more information
+               example.contract_terms_json = () => 
JSON.stringify(example.contract_terms);
+               example.contract_terms.timestamp_str = () => 
example.contract_terms.timestamp && 
format(example.contract_terms.timestamp.t_s, 'dd MMM yyyy HH:mm:ss');
+
+               example.contract_terms.hasProducts = () => 
example.contract_terms.products?.length > 0;
+               example.contract_terms.hasAuditors = () => 
example.contract_terms.auditors?.length > 0;
+               example.contract_terms.hasExchanges = () => 
example.contract_terms.exchanges?.length > 0;
+
+               example.contract_terms.products.forEach(p => {
+                       p.delivery_date_str = () => p.delivery_date && 
format(p.delivery_date.t_s, 'dd MM yyyy HH:mm:ss')
+                       p.hasTaxes = () => p.taxes?.length > 0
+               })
+               example.contract_terms.has_delivery_info = () => 
example.contract_terms.delivery_date || example.contract_terms.delivery_location
+
+               example.contract_terms.delivery_date_str = () => 
example.contract_terms.delivery_date && 
format(example.contract_terms.delivery_date.t_s, 'dd MM yyyy HH:mm:ss')
+               example.contract_terms.pay_deadline_str = () => 
example.contract_terms.pay_deadline && 
format(example.contract_terms.pay_deadline.t_s, 'dd MM yyyy HH:mm:ss')
+               example.contract_terms.wire_transfer_deadline_str = () => 
example.contract_terms.wire_transfer_deadline && 
format(example.contract_terms.wire_transfer_deadline.t_s, 'dd MM yyyy HH:mm:ss')
+               example.contract_terms.refund_deadline_str = () => 
example.contract_terms.refund_deadline && 
format(example.contract_terms.refund_deadline.t_s, 'dd MM yyyy HH:mm:ss')
+               example.contract_terms.auto_refund_str = () => 
example.contract_terms.auto_refund && formatDuration(intervalToDuration({ 
start: 0, end: example.contract_terms.auto_refund.d_us }))
+
+               const output = mustache.render(html, example);
+
+               
fs.writeFileSync(`${destDirectory}/${testName}.${exampleName}.html`, output)
+       })
+})
diff --git a/packages/merchant-backend-ui/rollup.config.js 
b/packages/merchant-backend-ui/rollup.config.js
new file mode 100644
index 000000000..f5227ba74
--- /dev/null
+++ b/packages/merchant-backend-ui/rollup.config.js
@@ -0,0 +1,112 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+// rollup.config.js
+import linaria from '@linaria/rollup';
+import nodeResolve from "@rollup/plugin-node-resolve";
+import alias from "@rollup/plugin-alias";
+import image from '@rollup/plugin-image';
+import json from "@rollup/plugin-json";
+import ts from "@rollup/plugin-typescript";
+import replace from "@rollup/plugin-replace";
+import css from 'rollup-plugin-css-only';
+import html from '@rollup/plugin-html';
+import commonjs from "@rollup/plugin-commonjs";
+
+
+
+const template = async ({
+  files,
+}) => {
+  const scripts = (files.js || []).map(({ code }) => 
`<script>${code}</script>`).join('\n');
+  const css = (files.css || []).map(({ source }) => 
`<style>${source}</style>`).join('\n');
+  const ssr = (files.js || []).map(({ code }) => code).join('\n');
+  const page = new Function(`${ssr}; return page.buildTimeRendering();`)()
+  return `
+<!doctype html>
+<html>
+  <head>
+    ${page.head}
+    ${css}
+  </head>
+  <script id="built_time_data">
+  </script>
+  <body>
+    ${page.body}
+    ${scripts}
+    <script>page.mount()</script>
+  </body>
+</html>`;
+};
+
+const makePlugins = (name) => [
+  alias({
+    entries: [
+      { find: 'react', replacement: 'preact/compat' },
+      { find: 'react-dom', replacement: 'preact/compat' }
+    ]
+  }),
+
+  replace({
+    "process.env.NODE_ENV": JSON.stringify("production"),
+    preventAssignment: true,
+  }),
+
+  commonjs({
+    include: [/node_modules/, /dist/],
+    extensions: [".js"],
+    ignoreGlobal: true,
+    sourceMap: true,
+  }),
+
+  nodeResolve({
+    browser: true,
+    preferBuiltins: true,
+  }),
+
+  json(),
+  image(),
+
+  linaria({
+    sourceMap: process.env.NODE_ENV !== 'production',
+  }),
+  css(),
+  ts({
+    sourceMap: false,
+    outputToFilesystem: false,
+  }),
+  html({ template, fileName: name }),
+];
+
+
+const pageDefinition = (name) => ({
+  input: `src/pages/${name}.tsx`,
+  output: {
+    file: `dist/pages/${name}.js`,
+    format: "iife",
+    exports: 'named',
+    name: 'page',
+  },
+  plugins: makePlugins(`${name}.html`),
+});
+
+export default [
+  pageDefinition("OfferTip"),
+  pageDefinition("OfferRefund"),
+  pageDefinition("DepletedTip"),
+  pageDefinition("RequestPayment"),
+  pageDefinition("ShowOrderDetails"),
+]
diff --git a/packages/anastasis-webui/src/assets/empty.png 
b/packages/merchant-backend-ui/src/assets/empty.png
similarity index 100%
copy from packages/anastasis-webui/src/assets/empty.png
copy to packages/merchant-backend-ui/src/assets/empty.png
diff --git 
a/packages/anastasis-webui/src/assets/icons/android-chrome-192x192.png 
b/packages/merchant-backend-ui/src/assets/icons/android-chrome-192x192.png
similarity index 100%
copy from packages/anastasis-webui/src/assets/icons/android-chrome-192x192.png
copy to packages/merchant-backend-ui/src/assets/icons/android-chrome-192x192.png
diff --git 
a/packages/anastasis-webui/src/assets/icons/android-chrome-512x512.png 
b/packages/merchant-backend-ui/src/assets/icons/android-chrome-512x512.png
similarity index 100%
copy from packages/anastasis-webui/src/assets/icons/android-chrome-512x512.png
copy to packages/merchant-backend-ui/src/assets/icons/android-chrome-512x512.png
diff --git a/packages/anastasis-webui/src/assets/icons/apple-touch-icon.png 
b/packages/merchant-backend-ui/src/assets/icons/apple-touch-icon.png
similarity index 100%
copy from packages/anastasis-webui/src/assets/icons/apple-touch-icon.png
copy to packages/merchant-backend-ui/src/assets/icons/apple-touch-icon.png
diff --git a/packages/anastasis-webui/src/assets/icons/favicon-16x16.png 
b/packages/merchant-backend-ui/src/assets/icons/favicon-16x16.png
similarity index 100%
copy from packages/anastasis-webui/src/assets/icons/favicon-16x16.png
copy to packages/merchant-backend-ui/src/assets/icons/favicon-16x16.png
diff --git a/packages/anastasis-webui/src/assets/icons/favicon-32x32.png 
b/packages/merchant-backend-ui/src/assets/icons/favicon-32x32.png
similarity index 100%
copy from packages/anastasis-webui/src/assets/icons/favicon-32x32.png
copy to packages/merchant-backend-ui/src/assets/icons/favicon-32x32.png
diff --git a/packages/anastasis-webui/src/assets/icons/languageicon.svg 
b/packages/merchant-backend-ui/src/assets/icons/languageicon.svg
similarity index 100%
copy from packages/anastasis-webui/src/assets/icons/languageicon.svg
copy to packages/merchant-backend-ui/src/assets/icons/languageicon.svg
diff --git a/packages/anastasis-webui/src/assets/icons/mstile-150x150.png 
b/packages/merchant-backend-ui/src/assets/icons/mstile-150x150.png
similarity index 100%
copy from packages/anastasis-webui/src/assets/icons/mstile-150x150.png
copy to packages/merchant-backend-ui/src/assets/icons/mstile-150x150.png
diff --git a/packages/merchant-backend-ui/src/components/Footer.tsx 
b/packages/merchant-backend-ui/src/components/Footer.tsx
new file mode 100644
index 000000000..5f2957800
--- /dev/null
+++ b/packages/merchant-backend-ui/src/components/Footer.tsx
@@ -0,0 +1,32 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import { h, VNode } from 'preact';
+import { FooterBar } from '../styled';
+
+export function Footer(): VNode {
+  return <FooterBar>
+    <p>
+      <a href="https://taler.net/";>Learn more about GNU Taler on our 
website.</a>
+      <p>Copyright &copy; 2014&mdash;2021 Taler Systems SA</p>
+    </p>
+  </FooterBar>
+}
+
diff --git a/packages/merchant-backend-ui/src/components/QR.tsx 
b/packages/merchant-backend-ui/src/components/QR.tsx
new file mode 100644
index 000000000..29c9920bf
--- /dev/null
+++ b/packages/merchant-backend-ui/src/components/QR.tsx
@@ -0,0 +1,41 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ import { h, VNode } from "preact";
+ import { useEffect, useRef } from "preact/hooks";
+ import qrcode from "qrcode-generator";
+ 
+export function createSVG(text:string):string {
+  const qr = qrcode(0, 'L');
+  qr.addData(text);
+  qr.make();
+  return qr.createSvgTag({
+    scalable: true,
+    margin: 0
+  });
+}
+
+ export function QR({ text }: { text: string; }):VNode {
+   const divRef = useRef<HTMLDivElement>(null);
+   useEffect(() => {
+     divRef.current.innerHTML = createSVG(text)
+   });
+ 
+   return <div style={{ width: '100%', display: 'flex', flexDirection: 
'column', alignItems: 'center' }}>
+     <div style={{ width: '50%', minWidth: 200, maxWidth: 300 }} ref={divRef} 
/>
+   </div>;
+ }
+ 
\ No newline at end of file
diff --git a/packages/merchant-backend-ui/src/context/backend.ts 
b/packages/merchant-backend-ui/src/context/backend.ts
new file mode 100644
index 000000000..a920d6ffc
--- /dev/null
+++ b/packages/merchant-backend-ui/src/context/backend.ts
@@ -0,0 +1,82 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { createContext, h, VNode } from 'preact'
+import { useCallback, useContext, useState } from 'preact/hooks'
+import { useBackendDefaultToken, useBackendURL } from '../hooks';
+
+interface BackendContextType {
+  url: string;
+  token?: string;
+  triedToLog: boolean;
+  resetBackend: () => void;
+  clearAllTokens: () => void;
+  addTokenCleaner: (c: () => void) => void;
+  updateLoginStatus: (url: string, token?: string) => void;
+}
+
+const BackendContext = createContext<BackendContextType>({
+  url: '',
+  token: undefined,
+  triedToLog: false,
+  resetBackend: () => null,
+  clearAllTokens: () => null,
+  addTokenCleaner: () => null,
+  updateLoginStatus: () => null,
+})
+
+function useBackendContextState(defaultUrl?: string): BackendContextType {
+  const [url, triedToLog, changeBackend, resetBackend] = 
useBackendURL(defaultUrl);
+  const [token, _updateToken] = useBackendDefaultToken();
+  const updateToken = (t?: string) => {
+    _updateToken(t)
+  }
+
+  const tokenCleaner = useCallback(() => { updateToken(undefined) }, [])
+  const [cleaners, setCleaners] = useState([tokenCleaner])
+  const addTokenCleaner = (c: () => void) => setCleaners(cs => [...cs, c])
+  const addTokenCleanerMemo = useCallback((c: () => void) => { 
addTokenCleaner(c) }, [tokenCleaner])
+
+  const clearAllTokens = () => {
+    cleaners.forEach(c => c())
+    for (let i = 0; i < localStorage.length; i++) {
+      const k = localStorage.key(i)
+      if (k && /^backend-token/.test(k)) localStorage.removeItem(k)
+    }
+    resetBackend()
+  }
+
+  const updateLoginStatus = (url: string, token?: string) => {
+    changeBackend(url);
+    if (token) updateToken(token);
+  };
+
+
+  return { url, token, triedToLog, updateLoginStatus, resetBackend, 
clearAllTokens, addTokenCleaner: addTokenCleanerMemo }
+}
+
+export const BackendContextProvider = ({ children, defaultUrl }: { children: 
any, defaultUrl?: string }): VNode => {
+  const value = useBackendContextState(defaultUrl)
+
+  return h(BackendContext.Provider, { value, children });
+}
+
+export const useBackendContext = (): BackendContextType => 
useContext(BackendContext);
diff --git a/packages/merchant-backend-ui/src/context/config.ts 
b/packages/merchant-backend-ui/src/context/config.ts
new file mode 100644
index 000000000..5cd772380
--- /dev/null
+++ b/packages/merchant-backend-ui/src/context/config.ts
@@ -0,0 +1,32 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { createContext } from 'preact'
+import { useContext } from 'preact/hooks'
+
+interface Type {
+  currency: string;
+  version: string;
+}
+const Context = createContext<Type>(null!)
+
+export const ConfigContextProvider = Context.Provider
+export const useConfigContext = (): Type => useContext(Context);
diff --git a/packages/merchant-backend-ui/src/context/fetch.ts 
b/packages/merchant-backend-ui/src/context/fetch.ts
new file mode 100644
index 000000000..52a4f9c8d
--- /dev/null
+++ b/packages/merchant-backend-ui/src/context/fetch.ts
@@ -0,0 +1,40 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, createContext, VNode, ComponentChildren } from 'preact'
+import { useContext } from 'preact/hooks'
+import useSWR, { trigger, useSWRInfinite, cache, mutate } from 'swr';
+
+interface Type {
+  useSWR: typeof useSWR,
+  useSWRInfinite: typeof useSWRInfinite,
+}
+
+const Context = createContext<Type>({} as any)
+
+export const useFetchContext = (): Type => useContext(Context);
+export const FetchContextProvider = ({ children }: { children: 
ComponentChildren }): VNode => {
+  return h(Context.Provider, { value: { useSWR, useSWRInfinite }, children });
+}
+
+export const FetchContextProviderTesting = ({ children, data }: { children: 
ComponentChildren, data:any }): VNode => {
+  return h(Context.Provider, { value: { useSWR: () => data, useSWRInfinite }, 
children });
+}
diff --git a/packages/merchant-backend-ui/src/context/instance.ts 
b/packages/merchant-backend-ui/src/context/instance.ts
new file mode 100644
index 000000000..fecf36426
--- /dev/null
+++ b/packages/merchant-backend-ui/src/context/instance.ts
@@ -0,0 +1,35 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { createContext } from 'preact'
+import { useContext } from 'preact/hooks'
+
+interface Type {
+  id: string;
+  token?: string;
+  admin?: boolean;
+  changeToken: (t?:string) => void;
+}
+
+const Context = createContext<Type>({} as any)
+
+export const InstanceContextProvider = Context.Provider
+export const useInstanceContext = (): Type => useContext(Context);
diff --git a/packages/merchant-backend-ui/src/context/listener.ts 
b/packages/merchant-backend-ui/src/context/listener.ts
new file mode 100644
index 000000000..659db0a03
--- /dev/null
+++ b/packages/merchant-backend-ui/src/context/listener.ts
@@ -0,0 +1,35 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { createContext } from 'preact'
+import { useContext } from 'preact/hooks'
+
+interface Type {
+  id: string;
+  token?: string;
+  admin?: boolean;
+  changeToken: (t?:string) => void;
+}
+
+const Context = createContext<Type>({} as any)
+
+export const ListenerContextProvider = Context.Provider
+export const useListenerContext = (): Type => useContext(Context);
diff --git a/packages/merchant-backend-ui/src/context/translation.ts 
b/packages/merchant-backend-ui/src/context/translation.ts
new file mode 100644
index 000000000..952a1e325
--- /dev/null
+++ b/packages/merchant-backend-ui/src/context/translation.ts
@@ -0,0 +1,59 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { createContext, h, VNode } from 'preact'
+import { useContext, useEffect } from 'preact/hooks'
+import { useLang } from '../hooks'
+import * as jedLib from "jed";
+import { strings } from "../i18n/strings";
+
+interface Type {
+  lang: string;
+  handler: any;
+  changeLanguage: (l: string) => void;
+}
+const initial = {
+  lang: 'en',
+  handler: null,
+  changeLanguage: () => {
+    // do not change anything
+  }
+}
+const Context = createContext<Type>(initial)
+
+interface Props {
+  initial?: string,
+  children: any,
+  forceLang?: string
+}
+
+export const TranslationProvider = ({ initial, children, forceLang }: Props): 
VNode => {
+  const [lang, changeLanguage] = useLang(initial)
+  useEffect(() => {
+    if (forceLang) {
+      changeLanguage(forceLang)
+    }
+  })
+  const handler = new jedLib.Jed(strings[lang]);
+  return h(Context.Provider, { value: { lang, handler, changeLanguage }, 
children });
+}
+
+export const useTranslationContext = (): Type => useContext(Context);
\ No newline at end of file
diff --git a/packages/merchant-backend-ui/src/css/pure-min.css 
b/packages/merchant-backend-ui/src/css/pure-min.css
new file mode 100644
index 000000000..77217b520
--- /dev/null
+++ b/packages/merchant-backend-ui/src/css/pure-min.css
@@ -0,0 +1,973 @@
+/*!
+  Pure v2.0.3
+  Copyright 2013 Yahoo!
+  Licensed under the BSD License.
+  https://github.com/pure-cs s/pure/blob/master/LICENSE.md
+*/
+/*!
+  normalize.cs s v | MIT License | git.io/normalize
+  Copyright (c) Nicolas Gallagher and Jonathan Neal
+*/
+/*! normalize.cs s v8.0.1 | MIT License | github.com/necolas/normalize.cs s */
+
+.talerbar {
+  text-align: center;
+}
+
+html {
+  line-height: 1.15;
+  -webkit-text-size-adjust: 100%;
+}
+body {
+  margin: 0;
+}
+main {
+  display: block;
+}
+h1 {
+  font-size: 2em;
+  margin: 0.67em 0;
+}
+hr {
+  -webkit-box-sizing: content-box;
+  box-sizing: content-box;
+  height: 0;
+  overflow: visible;
+}
+pre {
+  font-family: monospace, monospace;
+  font-size: 1em;
+}
+a {
+  background-color: transparent;
+}
+abbr[title] {
+  border-bottom: none;
+  text-decoration: underline;
+  -webkit-text-decoration: underline dotted;
+  text-decoration: underline dotted;
+}
+b,
+strong {
+  font-weight: bolder;
+}
+code,
+kbd,
+samp {
+  font-family: monospace, monospace;
+  font-size: 1em;
+}
+small {
+  font-size: 80%;
+}
+sub,
+sup {
+  font-size: 75%;
+  line-height: 0;
+  position: relative;
+  vertical-align: baseline;
+}
+sub {
+  bottom: -0.25em;
+}
+sup {
+  top: -0.5em;
+}
+img {
+  border-style: none;
+}
+button,
+input,
+optgroup,
+select,
+textarea {
+  font-family: inherit;
+  font-size: 100%;
+  line-height: 1.15;
+  margin: 0;
+}
+button,
+input {
+  overflow: visible;
+}
+button,
+select {
+  text-transform: none;
+}
+[type="button"],
+[type="reset"],
+[type="submit"],
+button {
+  -webkit-appearance: button;
+}
+[type="button"]::-moz-focus-inner,
+[type="reset"]::-moz-focus-inner,
+[type="submit"]::-moz-focus-inner,
+button::-moz-focus-inner {
+  border-style: none;
+  padding: 0;
+}
+[type="button"]:-moz-focusring,
+[type="reset"]:-moz-focusring,
+[type="submit"]:-moz-focusring,
+button:-moz-focusring {
+  outline: 1px dotted ButtonText;
+}
+fieldset {
+  padding: 0.35em 0.75em 0.625em;
+}
+legend {
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  color: inherit;
+  display: table;
+  max-width: 100%;
+  padding: 0;
+  white-space: normal;
+}
+progress {
+  vertical-align: baseline;
+}
+textarea {
+  overflow: auto;
+}
+[type="checkbox"],
+[type="radio"] {
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  padding: 0;
+}
+[type="number"]::-webkit-inner-spin-button,
+[type="number"]::-webkit-outer-spin-button {
+  height: auto;
+}
+[type="search"] {
+  -webkit-appearance: textfield;
+  outline-offset: -2px;
+}
+[type="search"]::-webkit-search-decoration {
+  -webkit-appearance: none;
+}
+::-webkit-file-upload-button {
+  -webkit-appearance: button;
+  font: inherit;
+}
+details {
+  display: block;
+}
+summary {
+  display: list-item;
+}
+template {
+  display: none;
+}
+[hidden] {
+  display: none;
+}
+html {
+  font-family: sans-serif;
+}
+.hidden,
+[hidden] {
+  display: none !important;
+}
+.pure-img {
+  max-width: 100%;
+  height: auto;
+  display: block;
+}
+.pure-g {
+  letter-spacing: -0.31em;
+  text-rendering: optimizespeed;
+  font-family: FreeSans, Arimo, "Droid Sans", Helvetica, Arial, sans-serif;
+  display: -webkit-box;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-box-orient: horizontal;
+  -webkit-box-direction: normal;
+  -ms-flex-flow: row wrap;
+  flex-flow: row wrap;
+  -ms-flex-line-pack: start;
+  align-content: flex-start;
+}
+@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
+  table .pure-g {
+    display: block;
+  }
+}
+.opera-only :-o-prefocus,
+.pure-g {
+  word-spacing: -0.43em;
+}
+.pure-u {
+  display: inline-block;
+  letter-spacing: normal;
+  word-spacing: normal;
+  vertical-align: top;
+  text-rendering: auto;
+}
+.pure-g [class*="pure-u"] {
+  font-family: sans-serif;
+}
+.pure-u-1,
+.pure-u-1-1,
+.pure-u-1-12,
+.pure-u-1-2,
+.pure-u-1-24,
+.pure-u-1-3,
+.pure-u-1-4,
+.pure-u-1-5,
+.pure-u-1-6,
+.pure-u-1-8,
+.pure-u-10-24,
+.pure-u-11-12,
+.pure-u-11-24,
+.pure-u-12-24,
+.pure-u-13-24,
+.pure-u-14-24,
+.pure-u-15-24,
+.pure-u-16-24,
+.pure-u-17-24,
+.pure-u-18-24,
+.pure-u-19-24,
+.pure-u-2-24,
+.pure-u-2-3,
+.pure-u-2-5,
+.pure-u-20-24,
+.pure-u-21-24,
+.pure-u-22-24,
+.pure-u-23-24,
+.pure-u-24-24,
+.pure-u-3-24,
+.pure-u-3-4,
+.pure-u-3-5,
+.pure-u-3-8,
+.pure-u-4-24,
+.pure-u-4-5,
+.pure-u-5-12,
+.pure-u-5-24,
+.pure-u-5-5,
+.pure-u-5-6,
+.pure-u-5-8,
+.pure-u-6-24,
+.pure-u-7-12,
+.pure-u-7-24,
+.pure-u-7-8,
+.pure-u-8-24,
+.pure-u-9-24 {
+  display: inline-block;
+  letter-spacing: normal;
+  word-spacing: normal;
+  vertical-align: top;
+  text-rendering: auto;
+}
+.pure-u-1-24 {
+  width: 4.1667%;
+}
+.pure-u-1-12,
+.pure-u-2-24 {
+  width: 8.3333%;
+}
+.pure-u-1-8,
+.pure-u-3-24 {
+  width: 12.5%;
+}
+.pure-u-1-6,
+.pure-u-4-24 {
+  width: 16.6667%;
+}
+.pure-u-1-5 {
+  width: 20%;
+}
+.pure-u-5-24 {
+  width: 20.8333%;
+}
+.pure-u-1-4,
+.pure-u-6-24 {
+  width: 25%;
+}
+.pure-u-7-24 {
+  width: 29.1667%;
+}
+.pure-u-1-3,
+.pure-u-8-24 {
+  width: 33.3333%;
+}
+.pure-u-3-8,
+.pure-u-9-24 {
+  width: 37.5%;
+}
+.pure-u-2-5 {
+  width: 40%;
+}
+.pure-u-10-24,
+.pure-u-5-12 {
+  width: 41.6667%;
+}
+.pure-u-11-24 {
+  width: 45.8333%;
+}
+.pure-u-1-2,
+.pure-u-12-24 {
+  width: 50%;
+}
+.pure-u-13-24 {
+  width: 54.1667%;
+}
+.pure-u-14-24,
+.pure-u-7-12 {
+  width: 58.3333%;
+}
+.pure-u-3-5 {
+  width: 60%;
+}
+.pure-u-15-24,
+.pure-u-5-8 {
+  width: 62.5%;
+}
+.pure-u-16-24,
+.pure-u-2-3 {
+  width: 66.6667%;
+}
+.pure-u-17-24 {
+  width: 70.8333%;
+}
+.pure-u-18-24,
+.pure-u-3-4 {
+  width: 75%;
+}
+.pure-u-19-24 {
+  width: 79.1667%;
+}
+.pure-u-4-5 {
+  width: 80%;
+}
+.pure-u-20-24,
+.pure-u-5-6 {
+  width: 83.3333%;
+}
+.pure-u-21-24,
+.pure-u-7-8 {
+  width: 87.5%;
+}
+.pure-u-11-12,
+.pure-u-22-24 {
+  width: 91.6667%;
+}
+.pure-u-23-24 {
+  width: 95.8333%;
+}
+.pure-u-1,
+.pure-u-1-1,
+.pure-u-24-24,
+.pure-u-5-5 {
+  width: 100%;
+}
+.pure-button {
+  display: inline-block;
+  line-height: normal;
+  white-space: nowrap;
+  vertical-align: middle;
+  text-align: center;
+  cursor: pointer;
+  -webkit-user-drag: none;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.pure-button::-moz-focus-inner {
+  padding: 0;
+  border: 0;
+}
+.pure-button-group {
+  letter-spacing: -0.31em;
+  text-rendering: optimizespeed;
+}
+.opera-only :-o-prefocus,
+.pure-button-group {
+  word-spacing: -0.43em;
+}
+.pure-button-group .pure-button {
+  letter-spacing: normal;
+  word-spacing: normal;
+  vertical-align: top;
+  text-rendering: auto;
+}
+.pure-button {
+  font-family: inherit;
+  font-size: 100%;
+  padding: 0.5em 1em;
+  color: rgba(0, 0, 0, 0.8);
+  border: none transparent;
+  background-color: #e6e6e6;
+  text-decoration: none;
+  border-radius: 2px;
+}
+.pure-button-hover,
+.pure-button:focus,
+.pure-button:hover {
+  background-image: -webkit-gradient(
+    linear,
+    left top,
+    left bottom,
+    from(transparent),
+    color-stop(40%, rgba(0, 0, 0, 0.05)),
+    to(rgba(0, 0, 0, 0.1))
+  );
+  background-image: linear-gradient(
+    transparent,
+    rgba(0, 0, 0, 0.05) 40%,
+    rgba(0, 0, 0, 0.1)
+  );
+}
+.pure-button:focus {
+  outline: 0;
+}
+.pure-button-active,
+.pure-button:active {
+  -webkit-box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.15) inset,
+    0 0 6px rgba(0, 0, 0, 0.2) inset;
+  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.15) inset,
+    0 0 6px rgba(0, 0, 0, 0.2) inset;
+  border-color: #000;
+}
+.pure-button-disabled,
+.pure-button-disabled:active,
+.pure-button-disabled:focus,
+.pure-button-disabled:hover,
+.pure-button[disabled] {
+  border: none;
+  background-image: none;
+  opacity: 0.4;
+  cursor: not-allowed;
+  -webkit-box-shadow: none;
+  box-shadow: none;
+  pointer-events: none;
+}
+.pure-button-hidden {
+  display: none;
+}
+.pure-button-primary,
+.pure-button-selected,
+a.pure-button-primary,
+a.pure-button-selected {
+  background-color: #0078e7;
+  color: #fff;
+}
+.pure-button-group .pure-button {
+  margin: 0;
+  border-radius: 0;
+  border-right: 1px solid rgba(0, 0, 0, 0.2);
+}
+.pure-button-group .pure-button:first-child {
+  border-top-left-radius: 2px;
+  border-bottom-left-radius: 2px;
+}
+.pure-button-group .pure-button:last-child {
+  border-top-right-radius: 2px;
+  border-bottom-right-radius: 2px;
+  border-right: none;
+}
+.pure-form input[type="color"],
+.pure-form input[type="date"],
+.pure-form input[type="datetime-local"],
+.pure-form input[type="datetime"],
+.pure-form input[type="email"],
+.pure-form input[type="month"],
+.pure-form input[type="number"],
+.pure-form input[type="password"],
+.pure-form input[type="search"],
+.pure-form input[type="tel"],
+.pure-form input[type="text"],
+.pure-form input[type="time"],
+.pure-form input[type="url"],
+.pure-form input[type="week"],
+.pure-form select,
+.pure-form textarea {
+  padding: 0.5em 0.6em;
+  display: inline-block;
+  border: 1px solid #ccc;
+  -webkit-box-shadow: inset 0 1px 3px #ddd;
+  box-shadow: inset 0 1px 3px #ddd;
+  border-radius: 4px;
+  vertical-align: middle;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.pure-form input:not([type]) {
+  padding: 0.5em 0.6em;
+  display: inline-block;
+  border: 1px solid #ccc;
+  -webkit-box-shadow: inset 0 1px 3px #ddd;
+  box-shadow: inset 0 1px 3px #ddd;
+  border-radius: 4px;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.pure-form input[type="color"] {
+  padding: 0.2em 0.5em;
+}
+.pure-form input[type="color"]:focus,
+.pure-form input[type="date"]:focus,
+.pure-form input[type="datetime-local"]:focus,
+.pure-form input[type="datetime"]:focus,
+.pure-form input[type="email"]:focus,
+.pure-form input[type="month"]:focus,
+.pure-form input[type="number"]:focus,
+.pure-form input[type="password"]:focus,
+.pure-form input[type="search"]:focus,
+.pure-form input[type="tel"]:focus,
+.pure-form input[type="text"]:focus,
+.pure-form input[type="time"]:focus,
+.pure-form input[type="url"]:focus,
+.pure-form input[type="week"]:focus,
+.pure-form select:focus,
+.pure-form textarea:focus {
+  outline: 0;
+  border-color: #129fea;
+}
+.pure-form input:not([type]):focus {
+  outline: 0;
+  border-color: #129fea;
+}
+.pure-form input[type="checkbox"]:focus,
+.pure-form input[type="file"]:focus,
+.pure-form input[type="radio"]:focus {
+  outline: thin solid #129fea;
+  outline: 1px auto #129fea;
+}
+.pure-form .pure-checkbox,
+.pure-form .pure-radio {
+  margin: 0.5em 0;
+  display: block;
+}
+.pure-form input[type="color"][disabled],
+.pure-form input[type="date"][disabled],
+.pure-form input[type="datetime-local"][disabled],
+.pure-form input[type="datetime"][disabled],
+.pure-form input[type="email"][disabled],
+.pure-form input[type="month"][disabled],
+.pure-form input[type="number"][disabled],
+.pure-form input[type="password"][disabled],
+.pure-form input[type="search"][disabled],
+.pure-form input[type="tel"][disabled],
+.pure-form input[type="text"][disabled],
+.pure-form input[type="time"][disabled],
+.pure-form input[type="url"][disabled],
+.pure-form input[type="week"][disabled],
+.pure-form select[disabled],
+.pure-form textarea[disabled] {
+  cursor: not-allowed;
+  background-color: #eaeded;
+  color: #cad2d3;
+}
+.pure-form input:not([type])[disabled] {
+  cursor: not-allowed;
+  background-color: #eaeded;
+  color: #cad2d3;
+}
+.pure-form input[readonly],
+.pure-form select[readonly],
+.pure-form textarea[readonly] {
+  background-color: #eee;
+  color: #777;
+  border-color: #ccc;
+}
+.pure-form input:focus:invalid,
+.pure-form select:focus:invalid,
+.pure-form textarea:focus:invalid {
+  color: #b94a48;
+  border-color: #e9322d;
+}
+.pure-form input[type="checkbox"]:focus:invalid:focus,
+.pure-form input[type="file"]:focus:invalid:focus,
+.pure-form input[type="radio"]:focus:invalid:focus {
+  outline-color: #e9322d;
+}
+.pure-form select {
+  height: 2.25em;
+  border: 1px solid #ccc;
+  background-color: #fff;
+}
+.pure-form select[multiple] {
+  height: auto;
+}
+.pure-form label {
+  margin: 0.5em 0 0.2em;
+}
+.pure-form fieldset {
+  margin: 0;
+  padding: 0.35em 0 0.75em;
+  border: 0;
+}
+.pure-form legend {
+  display: block;
+  width: 100%;
+  padding: 0.3em 0;
+  margin-bottom: 0.3em;
+  color: #333;
+  border-bottom: 1px solid #e5e5e5;
+}
+.pure-form-stacked input[type="color"],
+.pure-form-stacked input[type="date"],
+.pure-form-stacked input[type="datetime-local"],
+.pure-form-stacked input[type="datetime"],
+.pure-form-stacked input[type="email"],
+.pure-form-stacked input[type="file"],
+.pure-form-stacked input[type="month"],
+.pure-form-stacked input[type="number"],
+.pure-form-stacked input[type="password"],
+.pure-form-stacked input[type="search"],
+.pure-form-stacked input[type="tel"],
+.pure-form-stacked input[type="text"],
+.pure-form-stacked input[type="time"],
+.pure-form-stacked input[type="url"],
+.pure-form-stacked input[type="week"],
+.pure-form-stacked label,
+.pure-form-stacked select,
+.pure-form-stacked textarea {
+  display: block;
+  margin: 0.25em 0;
+}
+.pure-form-stacked input:not([type]) {
+  display: block;
+  margin: 0.25em 0;
+}
+.pure-form-aligned input,
+.pure-form-aligned select,
+.pure-form-aligned textarea,
+.pure-form-message-inline {
+  display: inline-block;
+  vertical-align: middle;
+}
+.pure-form-aligned textarea {
+  vertical-align: top;
+}
+.pure-form-aligned .pure-control-group {
+  margin-bottom: 0.5em;
+}
+.pure-form-aligned .pure-control-group label {
+  text-align: right;
+  display: inline-block;
+  vertical-align: middle;
+  width: 10em;
+  margin: 0 1em 0 0;
+}
+.pure-form-aligned .pure-controls {
+  margin: 1.5em 0 0 11em;
+}
+.pure-form .pure-input-rounded,
+.pure-form input.pure-input-rounded {
+  border-radius: 2em;
+  padding: 0.5em 1em;
+}
+.pure-form .pure-group fieldset {
+  margin-bottom: 10px;
+}
+.pure-form .pure-group input,
+.pure-form .pure-group textarea {
+  display: block;
+  padding: 10px;
+  margin: 0 0 -1px;
+  border-radius: 0;
+  position: relative;
+  top: -1px;
+}
+.pure-form .pure-group input:focus,
+.pure-form .pure-group textarea:focus {
+  z-index: 3;
+}
+.pure-form .pure-group input:first-child,
+.pure-form .pure-group textarea:first-child {
+  top: 1px;
+  border-radius: 4px 4px 0 0;
+  margin: 0;
+}
+.pure-form .pure-group input:first-child:last-child,
+.pure-form .pure-group textarea:first-child:last-child {
+  top: 1px;
+  border-radius: 4px;
+  margin: 0;
+}
+.pure-form .pure-group input:last-child,
+.pure-form .pure-group textarea:last-child {
+  top: -2px;
+  border-radius: 0 0 4px 4px;
+  margin: 0;
+}
+.pure-form .pure-group button {
+  margin: 0.35em 0;
+}
+.pure-form .pure-input-1 {
+  width: 100%;
+}
+.pure-form .pure-input-3-4 {
+  width: 75%;
+}
+.pure-form .pure-input-2-3 {
+  width: 66%;
+}
+.pure-form .pure-input-1-2 {
+  width: 50%;
+}
+.pure-form .pure-input-1-3 {
+  width: 33%;
+}
+.pure-form .pure-input-1-4 {
+  width: 25%;
+}
+.pure-form-message-inline {
+  display: inline-block;
+  padding-left: 0.3em;
+  color: #666;
+  vertical-align: middle;
+  font-size: 0.875em;
+}
+.pure-form-message {
+  display: block;
+  color: #666;
+  font-size: 0.875em;
+}
+@media only screen and (max-width: 480px) {
+  .pure-form button[type="submit"] {
+    margin: 0.7em 0 0;
+  }
+  .pure-form input:not([type]),
+  .pure-form input[type="color"],
+  .pure-form input[type="date"],
+  .pure-form input[type="datetime-local"],
+  .pure-form input[type="datetime"],
+  .pure-form input[type="email"],
+  .pure-form input[type="month"],
+  .pure-form input[type="number"],
+  .pure-form input[type="password"],
+  .pure-form input[type="search"],
+  .pure-form input[type="tel"],
+  .pure-form input[type="text"],
+  .pure-form input[type="time"],
+  .pure-form input[type="url"],
+  .pure-form input[type="week"],
+  .pure-form label {
+    margin-bottom: 0.3em;
+    display: block;
+  }
+  .pure-group input:not([type]),
+  .pure-group input[type="color"],
+  .pure-group input[type="date"],
+  .pure-group input[type="datetime-local"],
+  .pure-group input[type="datetime"],
+  .pure-group input[type="email"],
+  .pure-group input[type="month"],
+  .pure-group input[type="number"],
+  .pure-group input[type="password"],
+  .pure-group input[type="search"],
+  .pure-group input[type="tel"],
+  .pure-group input[type="text"],
+  .pure-group input[type="time"],
+  .pure-group input[type="url"],
+  .pure-group input[type="week"] {
+    margin-bottom: 0;
+  }
+  .pure-form-aligned .pure-control-group label {
+    margin-bottom: 0.3em;
+    text-align: left;
+    display: block;
+    width: 100%;
+  }
+  .pure-form-aligned .pure-controls {
+    margin: 1.5em 0 0 0;
+  }
+  .pure-form-message,
+  .pure-form-message-inline {
+    display: block;
+    font-size: 0.75em;
+    padding: 0.2em 0 0.8em;
+  }
+}
+.pure-menu {
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.pure-menu-fixed {
+  position: fixed;
+  left: 0;
+  top: 0;
+  z-index: 3;
+}
+.pure-menu-item,
+.pure-menu-list {
+  position: relative;
+}
+.pure-menu-list {
+  list-style: none;
+  margin: 0;
+  padding: 0;
+}
+.pure-menu-item {
+  padding: 0;
+  margin: 0;
+  height: 100%;
+}
+.pure-menu-heading,
+.pure-menu-link {
+  display: block;
+  text-decoration: none;
+  white-space: nowrap;
+}
+.pure-menu-horizontal {
+  width: 100%;
+  white-space: nowrap;
+}
+.pure-menu-horizontal .pure-menu-list {
+  display: inline-block;
+}
+.pure-menu-horizontal .pure-menu-heading,
+.pure-menu-horizontal .pure-menu-item,
+.pure-menu-horizontal .pure-menu-separator {
+  display: inline-block;
+  vertical-align: middle;
+}
+.pure-menu-item .pure-menu-item {
+  display: block;
+}
+.pure-menu-children {
+  display: none;
+  position: absolute;
+  left: 100%;
+  top: 0;
+  margin: 0;
+  padding: 0;
+  z-index: 3;
+}
+.pure-menu-horizontal .pure-menu-children {
+  left: 0;
+  top: auto;
+  width: inherit;
+}
+.pure-menu-active > .pure-menu-children,
+.pure-menu-allow-hover:hover > .pure-menu-children {
+  display: block;
+  position: absolute;
+}
+.pure-menu-has-children > .pure-menu-link:after {
+  padding-left: 0.5em;
+  content: "\25B8";
+  font-size: small;
+}
+.pure-menu-horizontal .pure-menu-has-children > .pure-menu-link:after {
+  content: "\25BE";
+}
+.pure-menu-scrollable {
+  overflow-y: scroll;
+  overflow-x: hidden;
+}
+.pure-menu-scrollable .pure-menu-list {
+  display: block;
+}
+.pure-menu-horizontal.pure-menu-scrollable .pure-menu-list {
+  display: inline-block;
+}
+.pure-menu-horizontal.pure-menu-scrollable {
+  white-space: nowrap;
+  overflow-y: hidden;
+  overflow-x: auto;
+  padding: 0.5em 0;
+}
+.pure-menu-horizontal .pure-menu-children .pure-menu-separator,
+.pure-menu-separator {
+  background-color: #ccc;
+  height: 1px;
+  margin: 0.3em 0;
+}
+.pure-menu-horizontal .pure-menu-separator {
+  width: 1px;
+  height: 1.3em;
+  margin: 0 0.3em;
+}
+.pure-menu-horizontal .pure-menu-children .pure-menu-separator {
+  display: block;
+  width: auto;
+}
+.pure-menu-heading {
+  text-transform: uppercase;
+  color: #565d64;
+}
+.pure-menu-link {
+  color: #777;
+}
+.pure-menu-children {
+  background-color: #fff;
+}
+.pure-menu-disabled,
+.pure-menu-heading,
+.pure-menu-link {
+  padding: 0.5em 1em;
+}
+.pure-menu-disabled {
+  opacity: 0.5;
+}
+.pure-menu-disabled .pure-menu-link:hover {
+  background-color: transparent;
+}
+.pure-menu-active > .pure-menu-link,
+.pure-menu-link:focus,
+.pure-menu-link:hover {
+  background-color: #eee;
+}
+.pure-menu-selected > .pure-menu-link,
+.pure-menu-selected > .pure-menu-link:visited {
+  color: #000;
+}
+.pure-table {
+  border-collapse: collapse;
+  border-spacing: 0;
+  empty-cells: show;
+  border: 1px solid #cbcbcb;
+}
+.pure-table caption {
+  color: #000;
+  font: italic 85%/1 arial, sans-serif;
+  padding: 1em 0;
+  text-align: center;
+}
+.pure-table td,
+.pure-table th {
+  border-left: 1px solid #cbcbcb;
+  border-width: 0 0 0 1px;
+  font-size: inherit;
+  margin: 0;
+  overflow: visible;
+  padding: 0.5em 1em;
+}
+.pure-table thead {
+  background-color: #e0e0e0;
+  color: #000;
+  text-align: left;
+  vertical-align: bottom;
+}
+.pure-table td {
+  background-color: transparent;
+}
+.pure-table-odd td {
+  background-color: #f2f2f2;
+}
+.pure-table-striped tr:nth-child(2n-1) td {
+  background-color: #f2f2f2;
+}
+.pure-table-bordered td {
+  border-bottom: 1px solid #cbcbcb;
+}
+.pure-table-bordered tbody > tr:last-child > td {
+  border-bottom-width: 0;
+}
+.pure-table-horizontal td,
+.pure-table-horizontal th {
+  border-width: 0 0 1px 0;
+  border-bottom: 1px solid #cbcbcb;
+}
+.pure-table-horizontal tbody > tr:last-child > td {
+  border-bottom-width: 0;
+}
diff --git a/packages/merchant-backend-ui/src/css/style.css 
b/packages/merchant-backend-ui/src/css/style.css
new file mode 100644
index 000000000..f24dbaa87
--- /dev/null
+++ b/packages/merchant-backend-ui/src/css/style.css
@@ -0,0 +1,61 @@
+/*!
+  Pure v2.0.3
+  Copyright 2013 Yahoo!
+  Licensed under the BSD License.
+  https://github.com/pure-ss/pure/blob/master/LICENSE.md
+*/
+/*!
+  normalize.cs v | MIT License | git.io/normalize
+  Copyright (c) Nicolas Gallagher and Jonathan Neal
+*/
+/*! normalize.ss v8.0.1 | MIT License | github.com/necolas/normalize.cs */
+
+.talerbar {
+  text-align: center;
+}
+.tt {
+  font-family: "Lucida Console", Monaco, monospace;
+}
+.content {
+  overflow-x: auto;
+  padding-left: 15%;
+  padding-right: 15%;
+}
+.qr {
+  margin: auto;
+  text-align: center;
+}
+.qrtext {
+  width: max-content;
+  margin: auto;
+  transition: font-size 0.2s;
+  font-family: "Lucida Console", Monaco, monospace;
+  font-size: 0.5em;
+}
+.qrtext:hover {
+  font-size: 1em;
+}
+.talerbar {
+  margin: 0;
+  bottom: 0;
+  background-color: #033;
+  color: white;
+  width: 100%;
+  padding: 1em;
+  overflow: auto;
+}
+body {
+  overflow-y: scroll;
+}
+@media (min-width: 500px) {
+  .content {
+    padding-bottom: 2em;
+    overflow-y: auto;
+  }
+}
+#main a:link,
+#main a:visited,
+#main a:hover,
+#main a:active {
+  color: black;
+}
\ No newline at end of file
diff --git a/packages/merchant-backend-ui/src/custom.d.ts 
b/packages/merchant-backend-ui/src/custom.d.ts
new file mode 100644
index 000000000..d2705003b
--- /dev/null
+++ b/packages/merchant-backend-ui/src/custom.d.ts
@@ -0,0 +1,40 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+declare module '*.po' {
+  const content: any;
+  export default content;
+}
+declare module 'jed' {
+  const x: any;
+  export = x;
+}
+declare module "*.jpeg" {
+  const content: any;
+  export default content;
+}
+declare module "*.png" {
+  const content: any;
+  export default content;
+}
+declare module '*.svg' {
+  const content: any;
+  export default content;
+}
+
+declare module '*.scss' {
+  const content: Record<string, string>;
+  export default content;
+}
diff --git a/packages/merchant-backend-ui/src/declaration.d.ts 
b/packages/merchant-backend-ui/src/declaration.d.ts
new file mode 100644
index 000000000..74b0a5011
--- /dev/null
+++ b/packages/merchant-backend-ui/src/declaration.d.ts
@@ -0,0 +1,1384 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+
+type HashCode = string;
+type EddsaPublicKey = string;
+type EddsaSignature = string;
+type WireTransferIdentifierRawP = string;
+type RelativeTime = Duration;
+type ImageDataUrl = string;
+
+export interface WithId {
+    id: string
+}
+
+interface Timestamp {
+    // Milliseconds since epoch, or the special
+    // value "forever" to represent an event that will
+    // never happen.
+    t_s: number | "never";
+}
+interface Duration {
+    // Duration in milliseconds or "forever"
+    // to represent an infinite duration.
+    d_us: number | "forever";
+}
+
+interface WithId {
+    id: string;
+}
+
+type Amount = string;
+type UUID = string;
+type Integer = number;
+
+export namespace ExchangeBackend {
+    interface WireResponse {
+
+        // Master public key of the exchange, must match the key returned in 
/keys.
+        master_public_key: EddsaPublicKey;
+
+        // Array of wire accounts operated by the exchange for
+        // incoming wire transfers.
+        accounts: WireAccount[];
+
+        // Object mapping names of wire methods (i.e. "sepa" or "x-taler-bank")
+        // to wire fees.
+        fees: { method: AggregateTransferFee };
+    }
+    interface WireAccount {
+        // payto:// URI identifying the account and wire method
+        payto_uri: string;
+
+        // Signature using the exchange's offline key
+        // with purpose TALER_SIGNATURE_MASTER_WIRE_DETAILS.
+        master_sig: EddsaSignature;
+    }
+    interface AggregateTransferFee {
+        // Per transfer wire transfer fee.
+        wire_fee: Amount;
+
+        // Per transfer closing fee.
+        closing_fee: Amount;
+
+        // What date (inclusive) does this fee go into effect?
+        // The different fees must cover the full time period in which
+        // any of the denomination keys are valid without overlap.
+        start_date: TalerProtocolTimestamp;
+
+        // What date (exclusive) does this fee stop going into effect?
+        // The different fees must cover the full time period in which
+        // any of the denomination keys are valid without overlap.
+        end_date: TalerProtocolTimestamp;
+
+        // Signature of TALER_MasterWireFeePS with
+        // purpose TALER_SIGNATURE_MASTER_WIRE_FEES.
+        sig: EddsaSignature;
+    }
+
+}
+export namespace MerchantBackend {
+    interface ErrorDetail {
+
+        // Numeric error code unique to the condition.
+        // The other arguments are specific to the error value reported here.
+        code: number;
+
+        // Human-readable description of the error, i.e. "missing parameter", 
"commitment violation", ...
+        // Should give a human-readable hint about the error's nature. 
Optional, may change without notice!
+        hint?: string;
+
+        // Optional detail about the specific input value that failed. May 
change without notice!
+        detail?: string;
+
+        // Name of the parameter that was bogus (if applicable).
+        parameter?: string;
+
+        // Path to the argument that was bogus (if applicable).
+        path?: string;
+
+        // Offset of the argument that was bogus (if applicable).
+        offset?: string;
+
+        // Index of the argument that was bogus (if applicable).
+        index?: string;
+
+        // Name of the object that was bogus (if applicable).
+        object?: string;
+
+        // Name of the currency than was problematic (if applicable).
+        currency?: string;
+
+        // Expected type (if applicable).
+        type_expected?: string;
+
+        // Type that was provided instead (if applicable).
+        type_actual?: string;
+    }
+
+
+    // Delivery location, loosely modeled as a subset of
+    // ISO20022's PostalAddress25.
+    interface Tax {
+        // the name of the tax
+        name: string;
+
+        // amount paid in tax
+        tax: Amount;
+    }
+
+    interface Auditor {
+        // official name
+        name: string;
+
+        // Auditor's public key
+        auditor_pub: EddsaPublicKey;
+
+        // Base URL of the auditor
+        url: string;
+    }
+    interface Exchange {
+        // the exchange's base URL
+        url: string;
+
+        // master public key of the exchange
+        master_pub: EddsaPublicKey;
+    }
+
+    interface Product {
+        // merchant-internal identifier for the product.
+        product_id?: string;
+
+        // Human-readable product description.
+        description: string;
+
+        // Map from IETF BCP 47 language tags to localized descriptions
+        description_i18n?: { [lang_tag: string]: string };
+
+        // The number of units of the product to deliver to the customer.
+        quantity: Integer;
+
+        // The unit in which the product is measured (liters, kilograms, 
packages, etc.)
+        unit: string;
+
+        // The price of the product; this is the total price for quantity 
times unit of this product.
+        price: Amount;
+
+        // An optional base64-encoded product image
+        image: ImageDataUrl;
+
+        // a list of taxes paid by the merchant for this product. Can be empty.
+        taxes: Tax[];
+
+        // time indicating when this product should be delivered
+        delivery_date?: Timestamp;
+    }
+    interface Merchant {
+        // label for a location with the business address of the merchant
+        address: Location;
+
+        // the merchant's legal name of business
+        name: string;
+
+        // label for a location that denotes the jurisdiction for disputes.
+        // Some of the typical fields for a location (such as a street 
address) may be absent.
+        jurisdiction: Location;
+    }
+
+    interface VersionResponse {
+        // libtool-style representation of the Merchant protocol version, see
+        // 
https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
+        // The format is "current:revision:age".
+        version: string;
+
+        // Name of the protocol.
+        name: "taler-merchant";
+
+        // Currency supported by this backend.
+        currency: string;
+
+    }
+    interface Location {
+        // Nation with its own government.
+        country?: string;
+
+        // Identifies a subdivision of a country such as state, region, county.
+        country_subdivision?: string;
+
+        // Identifies a subdivision within a country sub-division.
+        district?: string;
+
+        // Name of a built-up area, with defined boundaries, and a local 
government.
+        town?: string;
+
+        // Specific location name within the town.
+        town_location?: string;
+
+        // Identifier consisting of a group of letters and/or numbers that
+        // is added to a postal address to assist the sorting of mail.
+        post_code?: string;
+
+        // Name of a street or thoroughfare.
+        street?: string;
+
+        // Name of the building or house.
+        building_name?: string;
+
+        // Number that identifies the position of a building on a street.
+        building_number?: string;
+
+        // Free-form address lines, should not exceed 7 elements.
+        address_lines?: string[];
+    }
+    namespace Instances {
+
+        //POST /private/instances/$INSTANCE/auth
+        interface InstanceAuthConfigurationMessage {
+            // Type of authentication.
+            // "external":  The mechant backend does not do
+            //   any authentication checks.  Instead an API
+            //   gateway must do the authentication.
+            // "token": The merchant checks an auth token.
+            //   See "token" for details.
+            method: "external" | "token";
+
+            // For method "external", this field is mandatory.
+            // The token MUST begin with the string "secret-token:".
+            // After the auth token has been set (with method "token"),
+            // the value must be provided in a "Authorization: Bearer $token"
+            // header.
+            token?: string;
+
+        }
+        //POST /private/instances
+        interface InstanceConfigurationMessage {
+            // The URI where the wallet will send coins.  A merchant may have
+            // multiple accounts, thus this is an array.  Note that by
+            // removing URIs from this list the respective account is set to
+            // inactive and thus unavailable for new contracts, but preserved
+            // in the database as existing offers and contracts may still refer
+            // to it.
+            payto_uris: string[];
+
+            // Name of the merchant instance to create (will become $INSTANCE).
+            id: string;
+
+            // Merchant name corresponding to this instance.
+            name: string;
+
+            // "Authentication" header required to authorize management access 
the instance.
+            // Optional, if not given authentication will be disabled for
+            // this instance (hopefully authentication checks are still
+            // done by some reverse proxy).
+            auth: InstanceAuthConfigurationMessage;
+
+            // The merchant's physical address (to be put into contracts).
+            address: Location;
+
+            // The jurisdiction under which the merchant conducts its business
+            // (to be put into contracts).
+            jurisdiction: Location;
+
+            // Maximum wire fee this instance is willing to pay.
+            // Can be overridden by the frontend on a per-order basis.
+            default_max_wire_fee: Amount;
+
+            // Default factor for wire fee amortization calculations.
+            // Can be overridden by the frontend on a per-order basis.
+            default_wire_fee_amortization: Integer;
+
+            // Maximum deposit fee (sum over all coins) this instance is 
willing to pay.
+            // Can be overridden by the frontend on a per-order basis.
+            default_max_deposit_fee: Amount;
+
+            //  If the frontend does NOT specify an execution date, how long 
should
+            // we tell the exchange to wait to aggregate transactions before
+            // executing the wire transfer?  This delay is added to the current
+            // time when we generate the advisory execution time for the 
exchange.
+            default_wire_transfer_delay: RelativeTime;
+
+            // If the frontend does NOT specify a payment deadline, how long 
should
+            // offers we make be valid by default?
+            default_pay_delay: RelativeTime;
+
+        }
+
+        // PATCH /private/instances/$INSTANCE
+        interface InstanceReconfigurationMessage {
+            // The URI where the wallet will send coins.  A merchant may have
+            // multiple accounts, thus this is an array.  Note that by
+            // removing URIs from this list
+            payto_uris: string[];
+
+            // Merchant name corresponding to this instance.
+            name: string;
+
+            // The merchant's physical address (to be put into contracts).
+            address: Location;
+
+            // The jurisdiction under which the merchant conducts its business
+            // (to be put into contracts).
+            jurisdiction: Location;
+
+            // Maximum wire fee this instance is willing to pay.
+            // Can be overridden by the frontend on a per-order basis.
+            default_max_wire_fee: Amount;
+
+            // Default factor for wire fee amortization calculations.
+            // Can be overridden by the frontend on a per-order basis.
+            default_wire_fee_amortization: Integer;
+
+            // Maximum deposit fee (sum over all coins) this instance is 
willing to pay.
+            // Can be overridden by the frontend on a per-order basis.
+            default_max_deposit_fee: Amount;
+
+            //  If the frontend does NOT specify an execution date, how long 
should
+            // we tell the exchange to wait to aggregate transactions before
+            // executing the wire transfer?  This delay is added to the current
+            // time when we generate the advisory execution time for the 
exchange.
+            default_wire_transfer_delay: RelativeTime;
+
+            // If the frontend does NOT specify a payment deadline, how long 
should
+            // offers we make be valid by default?
+            default_pay_delay: RelativeTime;
+
+        }
+
+        //   GET /private/instances
+        interface InstancesResponse {
+            // List of instances that are present in the backend (see Instance)
+            instances: Instance[];
+        }
+
+        interface Instance {
+            // Merchant name corresponding to this instance.
+            name: string;
+
+            deleted?: boolean;
+
+            // Merchant instance this response is about ($INSTANCE)
+            id: string;
+
+            // Public key of the merchant/instance, in Crockford Base32 
encoding.
+            merchant_pub: EddsaPublicKey;
+
+            // List of the payment targets supported by this instance. Clients 
can
+            // specify the desired payment target in /order requests.  Note 
that
+            // front-ends do not have to support wallets selecting payment 
targets.
+            payment_targets: string[];
+
+        }
+
+        //GET /private/instances/$INSTANCE
+        interface QueryInstancesResponse {
+            // The URI where the wallet will send coins.  A merchant may have
+            // multiple accounts, thus this is an array.
+            accounts: MerchantAccount[];
+
+            // Merchant name corresponding to this instance.
+            name: string;
+
+            // Public key of the merchant/instance, in Crockford Base32 
encoding.
+            merchant_pub: EddsaPublicKey;
+
+            // The merchant's physical address (to be put into contracts).
+            address: Location;
+
+            // The jurisdiction under which the merchant conducts its business
+            // (to be put into contracts).
+            jurisdiction: Location;
+
+            // Maximum wire fee this instance is willing to pay.
+            // Can be overridden by the frontend on a per-order basis.
+            default_max_wire_fee: Amount;
+
+            // Default factor for wire fee amortization calculations.
+            // Can be overridden by the frontend on a per-order basis.
+            default_wire_fee_amortization: Integer;
+
+            // Maximum deposit fee (sum over all coins) this instance is 
willing to pay.
+            // Can be overridden by the frontend on a per-order basis.
+            default_max_deposit_fee: Amount;
+
+            //  If the frontend does NOT specify an execution date, how long 
should
+            // we tell the exchange to wait to aggregate transactions before
+            // executing the wire transfer?  This delay is added to the current
+            // time when we generate the advisory execution time for the 
exchange.
+            default_wire_transfer_delay: RelativeTime;
+
+            // If the frontend does NOT specify a payment deadline, how long 
should
+            // offers we make be valid by default?
+            default_pay_delay: RelativeTime;
+
+            // Authentication configuration.
+            // Does not contain the token when token auth is configured.
+            auth: {
+                method: "external" | "token";
+            };
+        }
+
+        interface MerchantAccount {
+
+            // payto:// URI of the account.
+            payto_uri: string;
+
+            // Hash over the wire details (including over the salt)
+            h_wire: HashCode;
+
+            // salt used to compute h_wire
+            salt: HashCode;
+
+            // true if this account is active,
+            // false if it is historic.
+            active: boolean;
+        }
+
+        //   DELETE /private/instances/$INSTANCE
+
+
+    }
+
+    namespace Products {
+        // POST /private/products
+        interface ProductAddDetail {
+
+            // product ID to use.
+            product_id: string;
+
+            // Human-readable product description.
+            description: string;
+
+            // Map from IETF BCP 47 language tags to localized descriptions
+            description_i18n: { [lang_tag: string]: string };
+
+            // unit in which the product is measured (liters, kilograms, 
packages, etc.)
+            unit: string;
+
+            // The price for one unit of the product. Zero is used
+            // to imply that this product is not sold separately, or
+            // that the price is not fixed, and must be supplied by the
+            // front-end.  If non-zero, this price MUST include applicable
+            // taxes.
+            price: Amount;
+
+            // An optional base64-encoded product image
+            image: ImageDataUrl;
+
+            // a list of taxes paid by the merchant for one unit of this 
product
+            taxes: Tax[];
+
+            // Number of units of the product in stock in sum in total,
+            // including all existing sales ever. Given in product-specific
+            // units.
+            // A value of -1 indicates "infinite" (i.e. for "electronic" 
books).
+            total_stock: Integer;
+
+            // Identifies where the product is in stock.
+            address: Location;
+
+            // Identifies when we expect the next restocking to happen.
+            next_restock?: Timestamp;
+
+        }
+        //   PATCH /private/products/$PRODUCT_ID
+        interface ProductPatchDetail {
+
+            // Human-readable product description.
+            description: string;
+
+            // Map from IETF BCP 47 language tags to localized descriptions
+            description_i18n: { [lang_tag: string]: string };
+
+            // unit in which the product is measured (liters, kilograms, 
packages, etc.)
+            unit: string;
+
+            // The price for one unit of the product. Zero is used
+            // to imply that this product is not sold separately, or
+            // that the price is not fixed, and must be supplied by the
+            // front-end.  If non-zero, this price MUST include applicable
+            // taxes.
+            price: Amount;
+
+            // An optional base64-encoded product image
+            image: ImageDataUrl;
+
+            // a list of taxes paid by the merchant for one unit of this 
product
+            taxes: Tax[];
+
+            // Number of units of the product in stock in sum in total,
+            // including all existing sales ever. Given in product-specific
+            // units.
+            // A value of -1 indicates "infinite" (i.e. for "electronic" 
books).
+            total_stock: Integer;
+
+            // Number of units of the product that were lost (spoiled, stolen, 
etc.)
+            total_lost: Integer;
+
+            // Identifies where the product is in stock.
+            address: Location;
+
+            // Identifies when we expect the next restocking to happen.
+            next_restock?: Timestamp;
+
+        }
+
+        // GET /private/products
+        interface InventorySummaryResponse {
+            // List of products that are present in the inventory
+            products: InventoryEntry[];
+        }
+        interface InventoryEntry {
+            // Product identifier, as found in the product.
+            product_id: string;
+
+        }
+
+        // GET /private/products/$PRODUCT_ID
+        interface ProductDetail {
+
+            // Human-readable product description.
+            description: string;
+
+            // Map from IETF BCP 47 language tags to localized descriptions
+            description_i18n: { [lang_tag: string]: string };
+
+            // unit in which the product is measured (liters, kilograms, 
packages, etc.)
+            unit: string;
+
+            // The price for one unit of the product. Zero is used
+            // to imply that this product is not sold separately, or
+            // that the price is not fixed, and must be supplied by the
+            // front-end.  If non-zero, this price MUST include applicable
+            // taxes.
+            price: Amount;
+
+            // An optional base64-encoded product image
+            image: ImageDataUrl;
+
+            // a list of taxes paid by the merchant for one unit of this 
product
+            taxes: Tax[];
+
+            // Number of units of the product in stock in sum in total,
+            // including all existing sales ever. Given in product-specific
+            // units.
+            // A value of -1 indicates "infinite" (i.e. for "electronic" 
books).
+            total_stock: Integer;
+
+            // Number of units of the product that have already been sold.
+            total_sold: Integer;
+
+            // Number of units of the product that were lost (spoiled, stolen, 
etc.)
+            total_lost: Integer;
+
+            // Identifies where the product is in stock.
+            address: Location;
+
+            // Identifies when we expect the next restocking to happen.
+            next_restock?: Timestamp;
+
+        }
+
+        // POST /private/products/$PRODUCT_ID/lock
+        interface LockRequest {
+
+            // UUID that identifies the frontend performing the lock
+            // It is suggested that clients use a timeflake for this,
+            // see https://github.com/anthonynsimon/timeflake
+            lock_uuid: UUID;
+
+            // How long does the frontend intend to hold the lock
+            duration: RelativeTime;
+
+            // How many units should be locked?
+            quantity: Integer;
+
+        }
+
+        //   DELETE /private/products/$PRODUCT_ID
+
+    }
+
+    namespace Orders {
+
+        type MerchantOrderStatusResponse = CheckPaymentPaidResponse |
+            CheckPaymentClaimedResponse |
+            CheckPaymentUnpaidResponse;
+        interface CheckPaymentPaidResponse {
+            // The customer paid for this contract.
+            order_status: "paid";
+
+            // Was the payment refunded (even partially)?
+            refunded: boolean;
+
+            // True if there are any approved refunds that the wallet has
+            // not yet obtained.
+            refund_pending: boolean;
+
+            // Did the exchange wire us the funds?
+            wired: boolean;
+
+            // Total amount the exchange deposited into our bank account
+            // for this contract, excluding fees.
+            deposit_total: Amount;
+
+            // Numeric error code indicating errors the exchange
+            // encountered tracking the wire transfer for this purchase (before
+            // we even got to specific coin issues).
+            // 0 if there were no issues.
+            exchange_ec: number;
+
+            // HTTP status code returned by the exchange when we asked for
+            // information to track the wire transfer for this purchase.
+            // 0 if there were no issues.
+            exchange_hc: number;
+
+            // Total amount that was refunded, 0 if refunded is false.
+            refund_amount: Amount;
+
+            // Contract terms.
+            contract_terms: ContractTerms;
+
+            // The wire transfer status from the exchange for this order if
+            // available, otherwise empty array.
+            wire_details: TransactionWireTransfer[];
+
+            // Reports about trouble obtaining wire transfer details,
+            // empty array if no trouble were encountered.
+            wire_reports: TransactionWireReport[];
+
+            // The refund details for this order.  One entry per
+            // refunded coin; empty array if there are no refunds.
+            refund_details: RefundDetails[];
+
+            // Status URL, can be used as a redirect target for the browser
+            // to show the order QR code / trigger the wallet.
+            order_status_url: string;
+        }
+        interface CheckPaymentClaimedResponse {
+            // A wallet claimed the order, but did not yet pay for the 
contract.
+            order_status: "claimed";
+
+            // Contract terms.
+            contract_terms: ContractTerms;
+
+        }
+        interface CheckPaymentUnpaidResponse {
+            // The order was neither claimed nor paid.
+            order_status: "unpaid";
+
+            // when was the order created
+            creation_time: Timestamp;
+
+            // Order summary text.
+            summary: string;
+
+            // Total amount of the order (to be paid by the customer).
+            total_amount: Amount;
+
+            // URI that the wallet must process to complete the payment.
+            taler_pay_uri: string;
+
+            // Alternative order ID which was paid for already in the same 
session.
+            // Only given if the same product was purchased before in the same 
session.
+            already_paid_order_id?: string;
+
+            // Fulfillment URL of an already paid order. Only given if under 
this
+            // session an already paid order with a fulfillment URL exists.
+            already_paid_fulfillment_url?: string;
+
+            // Status URL, can be used as a redirect target for the browser
+            // to show the order QR code / trigger the wallet.
+            order_status_url: string;
+
+            // We do we NOT return the contract terms here because they may not
+            // exist in case the wallet did not yet claim them.
+        }
+        interface RefundDetails {
+            // Reason given for the refund.
+            reason: string;
+
+            // When was the refund approved.
+            timestamp: Timestamp;
+
+            // Total amount that was refunded (minus a refund fee).
+            amount: Amount;
+        }
+        interface TransactionWireTransfer {
+            // Responsible exchange.
+            exchange_url: string;
+
+            // 32-byte wire transfer identifier.
+            wtid: Base32;
+
+            // Execution time of the wire transfer.
+            execution_time: Timestamp;
+
+            // Total amount that has been wire transferred
+            // to the merchant.
+            amount: Amount;
+
+            // Was this transfer confirmed by the merchant via the
+            // POST /transfers API, or is it merely claimed by the exchange?
+            confirmed: boolean;
+        }
+        interface TransactionWireReport {
+            // Numerical error code.
+            code: number;
+
+            // Human-readable error description.
+            hint: string;
+
+            // Numerical error code from the exchange.
+            exchange_ec: number;
+
+            // HTTP status code received from the exchange.
+            exchange_hc: number;
+
+            // Public key of the coin for which we got the exchange error.
+            coin_pub: CoinPublicKey;
+        }
+
+        interface OrderHistory {
+            // timestamp-sorted array of all orders matching the query.
+            // The order of the sorting depends on the sign of delta.
+            orders: OrderHistoryEntry[];
+        }
+        interface OrderHistoryEntry {
+
+            // order ID of the transaction related to this entry.
+            order_id: string;
+
+            // row ID of the order in the database
+            row_id: number;
+
+            // when the order was created
+            timestamp: Timestamp;
+
+            // the amount of money the order is for
+            amount: Amount;
+
+            // the summary of the order
+            summary: string;
+
+            // whether some part of the order is refundable,
+            // that is the refund deadline has not yet expired
+            // and the total amount refunded so far is below
+            // the value of the original transaction.
+            refundable: boolean;
+
+            // whether the order has been paid or not
+            paid: boolean;
+        }
+
+        interface PostOrderRequest {
+            // The order must at least contain the minimal
+            // order detail, but can override all
+            order: Order;
+
+            // if set, the backend will then set the refund deadline to the 
current
+            // time plus the specified delay.  If it's not set, refunds will 
not be
+            // possible.
+            refund_delay?: RelativeTime;
+
+            // specifies the payment target preferred by the client. Can be 
used
+            // to select among the various (active) wire methods supported by 
the instance.
+            payment_target?: string;
+
+            // specifies that some products are to be included in the
+            // order from the inventory.  For these inventory management
+            // is performed (so the products must be in stock) and
+            // details are completed from the product data of the backend.
+            inventory_products?: MinimalInventoryProduct[];
+
+            // Specifies a lock identifier that was used to
+            // lock a product in the inventory.  Only useful if
+            // manage_inventory is set.  Used in case a frontend
+            // reserved quantities of the individual products while
+            // the shopping card was being built.  Multiple UUIDs can
+            // be used in case different UUIDs were used for different
+            // products (i.e. in case the user started with multiple
+            // shopping sessions that were combined during checkout).
+            lock_uuids?: UUID[];
+
+            // Should a token for claiming the order be generated?
+            // False can make sense if the ORDER_ID is sufficiently
+            // high entropy to prevent adversarial claims (like it is
+            // if the backend auto-generates one). Default is 'true'.
+            create_token?: boolean;
+
+        }
+        type Order = MinimalOrderDetail | ContractTerms;
+
+        interface MinimalOrderDetail {
+            // Amount to be paid by the customer
+            amount: Amount;
+
+            // Short summary of the order
+            summary: string;
+
+            // URL that will show that the order was successful after
+            // it has been paid for.  Optional. When POSTing to the
+            // merchant, the placeholder "${ORDER_ID}" will be
+            // replaced with the actual order ID (useful if the
+            // order ID is generated server-side and needs to be
+            // in the URL).
+            fulfillment_url?: string;
+        }
+
+        interface MinimalInventoryProduct {
+            // Which product is requested (here mandatory!)
+            product_id: string;
+
+            // How many units of the product are requested
+            quantity: Integer;
+        }
+        interface PostOrderResponse {
+            // Order ID of the response that was just created
+            order_id: string;
+
+            // Token that authorizes the wallet to claim the order.
+            // Provided only if "create_token" was set to 'true'
+            // in the request.
+            token?: ClaimToken;
+        }
+        interface OutOfStockResponse {
+
+            // Product ID of an out-of-stock item
+            product_id: string;
+
+            // Requested quantity
+            requested_quantity: Integer;
+
+            // Available quantity (must be below requested_quanitity)
+            available_quantity: Integer;
+
+            // When do we expect the product to be again in stock?
+            // Optional, not given if unknown.
+            restock_expected?: Timestamp;
+        }
+
+        interface ForgetRequest {
+
+            // Array of valid JSON paths to forgettable fields in the order's
+            // contract terms.
+            fields: string[];
+        }
+        interface RefundRequest {
+            // Amount to be refunded
+            refund: Amount;
+
+            // Human-readable refund justification
+            reason: string;
+        }
+        interface MerchantRefundResponse {
+
+            // URL (handled by the backend) that the wallet should access to
+            // trigger refund processing.
+            // taler://refund/...
+            taler_refund_uri: string;
+
+            // Contract hash that a client may need to authenticate an
+            // HTTP request to obtain the above URI in a wallet-friendly way.
+            h_contract: HashCode;
+        }
+
+    }
+
+    namespace Tips {
+
+        // GET /private/reserves
+        interface TippingReserveStatus {
+            // Array of all known reserves (possibly empty!)
+            reserves: ReserveStatusEntry[];
+        }
+        interface ReserveStatusEntry {
+            // Public key of the reserve
+            reserve_pub: EddsaPublicKey;
+
+            // Timestamp when it was established
+            creation_time: Timestamp;
+
+            // Timestamp when it expires
+            expiration_time: Timestamp;
+
+            // Initial amount as per reserve creation call
+            merchant_initial_amount: Amount;
+
+            // Initial amount as per exchange, 0 if exchange did
+            // not confirm reserve creation yet.
+            exchange_initial_amount: Amount;
+
+            // Amount picked up so far.
+            pickup_amount: Amount;
+
+            // Amount approved for tips that exceeds the pickup_amount.
+            committed_amount: Amount;
+
+            // Is this reserve active (false if it was deleted but not purged)
+            active: boolean;
+        }
+
+        interface ReserveCreateRequest {
+            // Amount that the merchant promises to put into the reserve
+            initial_balance: Amount;
+
+            // Exchange the merchant intends to use for tipping
+            exchange_url: string;
+
+            // Desired wire method, for example "iban" or "x-taler-bank"
+            wire_method: string;
+        }
+        interface ReserveCreateConfirmation {
+            // Public key identifying the reserve
+            reserve_pub: EddsaPublicKey;
+
+            // Wire account of the exchange where to transfer the funds
+            payto_uri: string;
+        }
+        interface TipCreateRequest {
+            // Amount that the customer should be tipped
+            amount: Amount;
+
+            // Justification for giving the tip
+            justification: string;
+
+            // URL that the user should be directed to after tipping,
+            // will be included in the tip_token.
+            next_url: string;
+        }
+        interface TipCreateConfirmation {
+            // Unique tip identifier for the tip that was created.
+            tip_id: HashCode;
+
+            // taler://tip URI for the tip
+            taler_tip_uri: string;
+
+            // URL that will directly trigger processing
+            // the tip when the browser is redirected to it
+            tip_status_url: string;
+
+            // when does the tip expire
+            tip_expiration: Timestamp;
+        }
+
+        interface ReserveDetail {
+            // Timestamp when it was established.
+            creation_time: Timestamp;
+
+            // Timestamp when it expires.
+            expiration_time: Timestamp;
+
+            // Initial amount as per reserve creation call.
+            merchant_initial_amount: Amount;
+
+            // Initial amount as per exchange, 0 if exchange did
+            // not confirm reserve creation yet.
+            exchange_initial_amount: Amount;
+
+            // Amount picked up so far.
+            pickup_amount: Amount;
+
+            // Amount approved for tips that exceeds the pickup_amount.
+            committed_amount: Amount;
+
+            // Array of all tips created by this reserves (possibly empty!).
+            // Only present if asked for explicitly.
+            tips?: TipStatusEntry[];
+
+            // Is this reserve active (false if it was deleted but not purged)?
+            active: boolean;
+
+            // URI to use to fill the reserve, can be NULL
+            // if the reserve is inactive or was already filled
+            payto_uri: string;
+
+            // URL of the exchange hosting the reserve,
+            // NULL if the reserve is inactive
+            exchange_url: string;
+
+        }
+
+        interface TipStatusEntry {
+
+            // Unique identifier for the tip.
+            tip_id: HashCode;
+
+            // Total amount of the tip that can be withdrawn.
+            total_amount: Amount;
+
+            // Human-readable reason for why the tip was granted.
+            reason: string;
+        }
+
+        interface TipDetails {
+            // Amount that we authorized for this tip.
+            total_authorized: Amount;
+
+            // Amount that was picked up by the user already.
+            total_picked_up: Amount;
+
+            // Human-readable reason given when authorizing the tip.
+            reason: string;
+
+            // Timestamp indicating when the tip is set to expire (may be in 
the past).
+            expiration: TalerProtocolTimestamp;
+
+            // Reserve public key from which the tip is funded.
+            reserve_pub: EddsaPublicKey;
+
+            // Array showing the pickup operations of the wallet (possibly 
empty!).
+            // Only present if asked for explicitly.
+            pickups?: PickupDetail[];
+        }
+        interface PickupDetail {
+            // Unique identifier for the pickup operation.
+            pickup_id: HashCode;
+
+            // Number of planchets involved.
+            num_planchets: Integer;
+
+            // Total amount requested for this pickup_id.
+            requested_amount: Amount;
+        }
+
+    }
+
+    namespace Transfers {
+
+        interface TransferList {
+            // list of all the transfers that fit the filter that we know
+            transfers: TransferDetails[];
+        }
+        interface TransferDetails {
+            // how much was wired to the merchant (minus fees)
+            credit_amount: Amount;
+
+            // raw wire transfer identifier identifying the wire transfer (a 
base32-encoded value)
+            wtid: string;
+
+            // target account that received the wire transfer
+            payto_uri: string;
+
+            // base URL of the exchange that made the wire transfer
+            exchange_url: string;
+
+            // Serial number identifying the transfer in the merchant backend.
+            // Used for filgering via offset.
+            transfer_serial_id: number;
+
+            // Time of the execution of the wire transfer by the exchange, 
according to the exchange
+            // Only provided if we did get an answer from the exchange.
+            execution_time?: Timestamp;
+
+            // True if we checked the exchange's answer and are happy with it.
+            // False if we have an answer and are unhappy, missing if we
+            // do not have an answer from the exchange.
+            verified?: boolean;
+
+            // True if the merchant uses the POST /transfers API to confirm
+            // that this wire transfer took place (and it is thus not
+            // something merely claimed by the exchange).
+            confirmed?: boolean;
+        }
+
+        interface TransferInformation {
+            // how much was wired to the merchant (minus fees)
+            credit_amount: Amount;
+
+            // raw wire transfer identifier identifying the wire transfer (a 
base32-encoded value)
+            wtid: WireTransferIdentifierRawP;
+
+            // target account that received the wire transfer
+            payto_uri: string;
+
+            // base URL of the exchange that made the wire transfer
+            exchange_url: string;
+        }
+        interface MerchantTrackTransferResponse {
+            // Total amount transferred
+            total: Amount;
+
+            // Applicable wire fee that was charged
+            wire_fee: Amount;
+
+            // Time of the execution of the wire transfer by the exchange, 
according to the exchange
+            execution_time: Timestamp;
+
+            // details about the deposits
+            deposits_sums: MerchantTrackTransferDetail[];
+        }
+        interface MerchantTrackTransferDetail {
+            // Business activity associated with the wire transferred amount
+            // deposit_value.
+            order_id: string;
+
+            // The total amount the exchange paid back for order_id.
+            deposit_value: Amount;
+
+            // applicable fees for the deposit
+            deposit_fee: Amount;
+        }
+
+        type ExchangeConflictDetails = WireFeeConflictDetails | 
TrackTransferConflictDetails
+        // Note: this is not the full 'proof' of missbehavior, as
+        // the bogus message from the exchange with a signature
+        // over the 'different' wire fee is missing.
+        //
+        // This information is NOT provided by the current implementation,
+        // because this would be quite expensive to generate and is
+        // hardly needed _here_. Once we add automated reports for
+        // the Taler auditor, we need to generate this data anyway
+        // and should probably return it here as well.
+        interface WireFeeConflictDetails {
+            // Numerical error code:
+            code: "TALER_EC_MERCHANT_PRIVATE_POST_TRANSFERS_BAD_WIRE_FEE";
+
+            // Text describing the issue for humans.
+            hint: string;
+
+
+            // Wire fee (wrongly) charged by the exchange, breaking the
+            // contract affirmed by the exchange_sig.
+            wire_fee: Amount;
+
+            // Timestamp of the wire transfer
+            execution_time: Timestamp;
+
+            // The expected wire fee (as signed by the exchange)
+            expected_wire_fee: Amount;
+
+            // Expected closing fee (needed to verify signature)
+            expected_closing_fee: Amount;
+
+            // Start date of the expected fee structure
+            start_date: Timestamp;
+
+            // End date of the expected fee structure
+            end_date: Timestamp;
+
+            // Signature of the exchange affirming the expected fee structure
+            master_sig: EddsaSignature;
+
+            // Master public key of the exchange
+            master_pub: EddsaPublicKey;
+        }
+        interface TrackTransferConflictDetails {
+            // Numerical error code
+            code: 
"TALER_EC_MERCHANT_PRIVATE_POST_TRANSFERS_CONFLICTING_REPORTS";
+
+            // Text describing the issue for humans.
+            hint: string;
+
+            // Offset in the exchange_transfer where the
+            // exchange's response fails to match the exchange_deposit_proof.
+            conflict_offset: number;
+
+            // The response from the exchange which tells us when the
+            // coin was returned to us, except that it does not match
+            // the expected value of the coin.
+            //
+            // This field is NOT provided by the current implementation,
+            // because this would be quite expensive to generate and is
+            // hardly needed _here_. Once we add automated reports for
+            // the Taler auditor, we need to generate this data anyway
+            // and should probably return it here as well.
+            // exchange_transfer?: TrackTransferResponse;
+
+            // Public key of the exchange used to sign the response to
+            // our deposit request.
+            deposit_exchange_pub: EddsaPublicKey;
+
+            // Signature of the exchange signing the (conflicting) response.
+            // Signs over a struct TALER_DepositConfirmationPS.
+            deposit_exchange_sig: EddsaSignature;
+
+            // Hash of the merchant's bank account the wire transfer went to
+            h_wire: HashCode;
+
+            // Hash of the contract terms with the conflicting deposit.
+            h_contract_terms: HashCode;
+
+            // At what time the exchange received the deposit.  Needed
+            // to verify the \exchange_sig\.
+            deposit_timestamp: Timestamp;
+
+            // At what time the refund possibility expired (needed to verify 
exchange_sig).
+            refund_deadline: Timestamp;
+
+            // Public key of the coin for which we have conflicting 
information.
+            coin_pub: EddsaPublicKey;
+
+            // Amount the exchange counted the coin for in the transfer.
+            amount_with_fee: Amount;
+
+            // Expected value of the coin.
+            coin_value: Amount;
+
+            // Expected deposit fee of the coin.
+            coin_fee: Amount;
+
+            // Expected deposit fee of the coin.
+            deposit_fee: Amount;
+
+        }
+
+        // interface TrackTransferProof {
+        //     // signature from the exchange made with purpose
+        //     // TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT
+        //     exchange_sig: EddsaSignature;
+
+        //     // public EdDSA key of the exchange that was used to generate 
the signature.
+        //     // Should match one of the exchange's signing keys from /keys.  
Again given
+        //     // explicitly as the client might otherwise be confused by 
clock skew as to
+        //     // which signing key was used.
+        //     exchange_pub: EddsaSignature;
+
+        //     // hash of the wire details (identical for all deposits)
+        //     // Needed to check the exchange_sig
+        //     h_wire: HashCode;
+        // }
+
+    }
+
+
+    interface ContractTerms {
+        // Human-readable description of the whole purchase
+        summary: string;
+
+        // Map from IETF BCP 47 language tags to localized summaries
+        summary_i18n?: { [lang_tag: string]: string };
+
+        // Unique, free-form identifier for the proposal.
+        // Must be unique within a merchant instance.
+        // For merchants that do not store proposals in their DB
+        // before the customer paid for them, the order_id can be used
+        // by the frontend to restore a proposal from the information
+        // encoded in it (such as a short product identifier and timestamp).
+        order_id: string;
+
+        // Total price for the transaction.
+        // The exchange will subtract deposit fees from that amount
+        // before transferring it to the merchant.
+        amount: Amount;
+
+        // The URL for this purchase.  Every time is is visited, the merchant
+        // will send back to the customer the same proposal.  Clearly, this URL
+        // can be bookmarked and shared by users.
+        fulfillment_url?: string;
+
+        // Maximum total deposit fee accepted by the merchant for this contract
+        max_fee: Amount;
+
+        // Maximum wire fee accepted by the merchant (customer share to be
+        // divided by the 'wire_fee_amortization' factor, and further reduced
+        // if deposit fees are below 'max_fee').  Default if missing is zero.
+        max_wire_fee: Amount;
+
+        // Over how many customer transactions does the merchant expect to
+        // amortize wire fees on average?  If the exchange's wire fee is
+        // above 'max_wire_fee', the difference is divided by this number
+        // to compute the expected customer's contribution to the wire fee.
+        // The customer's contribution may further be reduced by the difference
+        // between the 'max_fee' and the sum of the actual deposit fees.
+        // Optional, default value if missing is 1.  0 and negative values are
+        // invalid and also interpreted as 1.
+        wire_fee_amortization: number;
+
+        // List of products that are part of the purchase (see Product).
+        products: Product[];
+
+        // Time when this contract was generated
+        timestamp: TalerProtocolTimestamp;
+
+        // After this deadline has passed, no refunds will be accepted.
+        refund_deadline: TalerProtocolTimestamp;
+
+        // After this deadline, the merchant won't accept payments for the 
contact
+        pay_deadline: TalerProtocolTimestamp;
+
+        // Transfer deadline for the exchange.  Must be in the
+        // deposit permissions of coins used to pay for this order.
+        wire_transfer_deadline: TalerProtocolTimestamp;
+
+        // Merchant's public key used to sign this proposal; this information
+        // is typically added by the backend Note that this can be an 
ephemeral key.
+        merchant_pub: EddsaPublicKey;
+
+        // Base URL of the (public!) merchant backend API.
+        // Must be an absolute URL that ends with a slash.
+        merchant_base_url: string;
+
+        // More info about the merchant, see below
+        merchant: Merchant;
+
+        // The hash of the merchant instance's wire details.
+        h_wire: HashCode;
+
+        // Wire transfer method identifier for the wire method associated with 
h_wire.
+        // The wallet may only select exchanges via a matching auditor if the
+        // exchange also supports this wire method.
+        // The wire transfer fees must be added based on this wire transfer 
method.
+        wire_method: string;
+
+        // Any exchanges audited by these auditors are accepted by the 
merchant.
+        auditors: Auditor[];
+
+        // Exchanges that the merchant accepts even if it does not accept any 
auditors that audit them.
+        exchanges: Exchange[];
+
+        // Delivery location for (all!) products.
+        delivery_location?: Location;
+
+        // Time indicating when the order should be delivered.
+        // May be overwritten by individual products.
+        delivery_date?: TalerProtocolTimestamp;
+
+        // Nonce generated by the wallet and echoed by the merchant
+        // in this field when the proposal is generated.
+        nonce: string;
+
+        // Specifies for how long the wallet should try to get an
+        // automatic refund for the purchase. If this field is
+        // present, the wallet should wait for a few seconds after
+        // the purchase and then automatically attempt to obtain
+        // a refund.  The wallet should probe until "delay"
+        // after the payment was successful (i.e. via long polling
+        // or via explicit requests with exponential back-off).
+        //
+        // In particular, if the wallet is offline
+        // at that time, it MUST repeat the request until it gets
+        // one response from the merchant after the delay has expired.
+        // If the refund is granted, the wallet MUST automatically
+        // recover the payment.  This is used in case a merchant
+        // knows that it might be unable to satisfy the contract and
+        // desires for the wallet to attempt to get the refund without any
+        // customer interaction.  Note that it is NOT an error if the
+        // merchant does not grant a refund.
+        auto_refund?: RelativeTime;
+
+        // Extra data that is only interpreted by the merchant frontend.
+        // Useful when the merchant needs to store extra information on a
+        // contract without storing it separately in their database.
+        extra?: any;
+    }
+
+}
diff --git a/packages/merchant-backend-ui/src/hooks/async.ts 
b/packages/merchant-backend-ui/src/hooks/async.ts
new file mode 100644
index 000000000..fd550043b
--- /dev/null
+++ b/packages/merchant-backend-ui/src/hooks/async.ts
@@ -0,0 +1,76 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import { useState } from "preact/hooks";
+import { cancelPendingRequest } from "./backend";
+
+export interface Options {
+  slowTolerance: number,
+}
+
+export interface AsyncOperationApi<T> {
+  request: (...a: any) => void,
+  cancel: () => void,
+  data: T | undefined,
+  isSlow: boolean,
+  isLoading: boolean,
+  error: string | undefined
+}
+
+export function useAsync<T>(fn?: (...args: any) => Promise<T>, { 
slowTolerance: tooLong }: Options = { slowTolerance: 1000 }): 
AsyncOperationApi<T> {
+  const [data, setData] = useState<T | undefined>(undefined);
+  const [isLoading, setLoading] = useState<boolean>(false);
+  const [error, setError] = useState<any>(undefined);
+  const [isSlow, setSlow] = useState(false)
+
+  const request = async (...args: any) => {
+    if (!fn) return;
+    setLoading(true);
+
+    const handler = setTimeout(() => {
+      setSlow(true)
+    }, tooLong)
+
+    try {
+      const result = await fn(...args);
+      setData(result);
+    } catch (error) {
+      setError(error);
+    }
+    setLoading(false);
+    setSlow(false)
+    clearTimeout(handler)
+  };
+
+  function cancel() {
+    cancelPendingRequest()
+    setLoading(false);
+    setSlow(false)
+  }
+
+  return {
+    request,
+    cancel,
+    data,
+    isSlow,
+    isLoading,
+    error
+  };
+}
diff --git a/packages/merchant-backend-ui/src/hooks/backend.ts 
b/packages/merchant-backend-ui/src/hooks/backend.ts
new file mode 100644
index 000000000..96b8f7139
--- /dev/null
+++ b/packages/merchant-backend-ui/src/hooks/backend.ts
@@ -0,0 +1,262 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { mutate, cache } from 'swr';
+import axios, { AxiosError, AxiosResponse } from 'axios'
+import { MerchantBackend } from '../declaration';
+import { useBackendContext } from '../context/backend';
+import { useEffect, useState } from 'preact/hooks';
+import { DEFAULT_REQUEST_TIMEOUT } from '../utils/constants';
+
+export function mutateAll(re: RegExp, value?: unknown): Array<Promise<any>> {
+  return cache.keys().filter(key => {
+    return re.test(key)
+  }).map(key => {
+    return mutate(key, value)
+  })
+}
+
+export type HttpResponse<T> = HttpResponseOk<T> | HttpResponseLoading<T> | 
HttpError;
+export type HttpResponsePaginated<T> = HttpResponseOkPaginated<T> | 
HttpResponseLoading<T> | HttpError;
+
+export interface RequestInfo {
+  url: string;
+  hasToken: boolean;
+  params: unknown;
+  data: unknown;
+}
+
+interface HttpResponseLoading<T> {
+  ok?: false;
+  loading: true;
+  clientError?: false;
+  serverError?: false;
+
+  data?: T;
+}
+export interface HttpResponseOk<T> {
+  ok: true;
+  loading?: false;
+  clientError?: false;
+  serverError?: false;
+
+  data: T;
+  info?: RequestInfo;
+}
+
+export type HttpResponseOkPaginated<T> = HttpResponseOk<T> & WithPagination
+
+export interface WithPagination {
+  loadMore: () => void;
+  loadMorePrev: () => void;
+  isReachingEnd?: boolean;
+  isReachingStart?: boolean;
+}
+
+export type HttpError = HttpResponseClientError | HttpResponseServerError | 
HttpResponseUnexpectedError;
+export interface SwrError {
+  info: unknown,
+  status: number,
+  message: string,
+}
+export interface HttpResponseServerError {
+  ok?: false;
+  loading?: false;
+  clientError?: false;
+  serverError: true;
+
+  error?: MerchantBackend.ErrorDetail;
+  status: number;
+  message: string;
+  info?: RequestInfo;
+}
+interface HttpResponseClientError {
+  ok?: false;
+  loading?: false;
+  clientError: true;
+  serverError?: false;
+
+  info?: RequestInfo;
+  isUnauthorized: boolean;
+  isNotfound: boolean;
+  status: number;
+  error?: MerchantBackend.ErrorDetail;
+  message: string;
+
+}
+
+interface HttpResponseUnexpectedError {
+  ok?: false;
+  loading?: false;
+  clientError?: false;
+  serverError?: false;
+
+  info?: RequestInfo;
+  status?: number;
+  error: unknown;
+  message: string;
+}
+
+type Methods = 'get' | 'post' | 'patch' | 'delete' | 'put';
+
+interface RequestOptions {
+  method?: Methods;
+  token?: string;
+  data?: unknown;
+  params?: unknown;
+}
+
+function buildRequestOk<T>(res: AxiosResponse<T>, url: string, hasToken: 
boolean): HttpResponseOk<T> {
+  return {
+    ok: true, data: res.data, info: {
+      params: res.config.params,
+      data: res.config.data,
+      url,
+      hasToken,
+    }
+  }
+}
+
+// function buildResponse<T>(data?: T, error?: MerchantBackend.ErrorDetail, 
isValidating?: boolean): HttpResponse<T> {
+//   if (isValidating) return {loading: true}
+//   if (error) return buildRequestFailed()
+// }
+
+function buildRequestFailed(ex: AxiosError<MerchantBackend.ErrorDetail>, url: 
string, hasToken: boolean): HttpResponseClientError | HttpResponseServerError | 
HttpResponseUnexpectedError {
+  const status = ex.response?.status
+
+  const info: RequestInfo = {
+    data: ex.request?.data,
+    params: ex.request?.params,
+    url,
+    hasToken,
+  };
+
+  if (status && status >= 400 && status < 500) {
+    const error: HttpResponseClientError = {
+      clientError: true,
+      isNotfound: status === 404,
+      isUnauthorized: status === 401,
+      status,
+      info,
+      message: ex.response?.data?.hint || ex.message,
+      error: ex.response?.data
+    }
+    return error
+  }
+  if (status && status >= 500 && status < 600) {
+    const error: HttpResponseServerError = {
+      serverError: true,
+      status,
+      info,
+      message: `${ex.response?.data?.hint} (code ${ex.response?.data?.code})` 
|| ex.message,
+      error: ex.response?.data
+    }
+    return error;
+  }
+
+  const error: HttpResponseUnexpectedError = {
+    info,
+    status,
+    error: ex,
+    message: ex.message
+  }
+
+  return error
+}
+
+
+const CancelToken = axios.CancelToken;
+let source = CancelToken.source();
+
+export function cancelPendingRequest() {
+  source.cancel('canceled by the user')
+  source = CancelToken.source()
+}
+
+let removeAxiosCancelToken = false
+/**
+ * Jest mocking seems to break when using the cancelToken property.
+ * Using this workaround when testing while finding the correct solution
+ */
+export function setAxiosRequestAsTestingEnvironment() {
+  removeAxiosCancelToken = true
+}
+
+export async function request<T>(url: string, options: RequestOptions = {}): 
Promise<HttpResponseOk<T>> {
+  const headers = options.token ? { Authorization: `Bearer ${options.token}` } 
: undefined
+
+  try {
+    const res = await axios({
+      url,
+      responseType: 'json',
+      headers,
+      cancelToken: !removeAxiosCancelToken? source.token : undefined,
+      method: options.method || 'get',
+      data: options.data,
+      params: options.params,
+      timeout: DEFAULT_REQUEST_TIMEOUT * 1000,
+    })
+    return buildRequestOk<T>(res, url, !!options.token)
+  } catch (e) {
+    const error = buildRequestFailed(e, url, !!options.token)
+    throw error
+  }
+
+}
+
+export function fetcher<T>(url: string, token: string, backend: string): 
Promise<HttpResponseOk<T>> {
+  return request<T>(`${backend}${url}`, { token })
+}
+
+export function useBackendInstancesTestForAdmin(): 
HttpResponse<MerchantBackend.Instances.InstancesResponse> {
+  const { url, token } = useBackendContext()
+
+  type Type = MerchantBackend.Instances.InstancesResponse;
+
+  const [result, setResult] = useState<HttpResponse<Type>>({ loading: true })
+
+  useEffect(() => {
+    request<Type>(`${url}/management/instances`, { token })
+      .then(data => setResult(data))
+      .catch(error => setResult(error))
+  }, [url, token])
+
+
+  return result
+}
+
+
+export function useBackendConfig(): 
HttpResponse<MerchantBackend.VersionResponse> {
+  const { url, token } = useBackendContext()
+
+  type Type = MerchantBackend.VersionResponse;
+
+  const [result, setResult] = useState<HttpResponse<Type>>({ loading: true })
+
+  useEffect(() => {
+    request<Type>(`${url}/config`, { token })
+      .then(data => setResult(data))
+      .catch(error => setResult(error))
+  }, [url, token])
+
+  return result
+}
diff --git a/packages/merchant-backend-ui/src/hooks/index.ts 
b/packages/merchant-backend-ui/src/hooks/index.ts
new file mode 100644
index 000000000..19d672ad3
--- /dev/null
+++ b/packages/merchant-backend-ui/src/hooks/index.ts
@@ -0,0 +1,110 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { StateUpdater, useCallback, useState } from "preact/hooks";
+import { ValueOrFunction } from '../utils/types';
+
+
+const calculateRootPath = () => {
+  const rootPath = typeof window !== undefined ? window.location.origin + 
window.location.pathname : '/'
+  return rootPath
+}
+
+export function useBackendURL(url?: string): [string, boolean, 
StateUpdater<string>, () => void] {
+  const [value, setter] = useNotNullLocalStorage('backend-url', url || 
calculateRootPath())
+  const [triedToLog, setTriedToLog] = useLocalStorage('tried-login')
+
+  const checkedSetter = (v: ValueOrFunction<string>) => {
+    setTriedToLog('yes')
+    return setter(p => (v instanceof Function ? v(p) : v).replace(/\/$/, ''))
+  }
+
+  const resetBackend = () => {
+    setTriedToLog(undefined)
+  }
+  return [value, !!triedToLog, checkedSetter, resetBackend]
+}
+
+export function useBackendDefaultToken(): [string | undefined, 
StateUpdater<string | undefined>] {
+  return useLocalStorage('backend-token')
+}
+
+export function useBackendInstanceToken(id: string): [string | undefined, 
StateUpdater<string | undefined>] {
+  const [token, setToken] = useLocalStorage(`backend-token-${id}`)
+  const [defaultToken, defaultSetToken] = useBackendDefaultToken()
+
+  // instance named 'default' use the default token
+  if (id === 'default') {
+    return [defaultToken, defaultSetToken]
+  }
+
+  return [token, setToken]
+}
+
+export function useLang(initial?: string): [string, StateUpdater<string>] {
+  const browserLang = typeof window !== "undefined" ? navigator.language || 
(navigator as any).userLanguage : undefined;
+  const defaultLang = (browserLang || initial || 'en').substring(0, 2)
+  return useNotNullLocalStorage('lang-preference', defaultLang)
+}
+
+export function useLocalStorage(key: string, initialValue?: string): [string | 
undefined, StateUpdater<string | undefined>] {
+  const [storedValue, setStoredValue] = useState<string | undefined>((): 
string | undefined => {
+    return typeof window !== "undefined" ? window.localStorage.getItem(key) || 
initialValue : initialValue;
+  });
+
+  const setValue = (value?: string | ((val?: string) => string | undefined)) 
=> {
+    setStoredValue(p => {
+      const toStore = value instanceof Function ? value(p) : value
+      if (typeof window !== "undefined") {
+        if (!toStore) {
+          window.localStorage.removeItem(key)
+        } else {
+          window.localStorage.setItem(key, toStore);
+        }
+      }
+      return toStore
+    })
+  };
+
+  return [storedValue, setValue];
+}
+
+export function useNotNullLocalStorage(key: string, initialValue: string): 
[string, StateUpdater<string>] {
+  const [storedValue, setStoredValue] = useState<string>((): string => {
+    return typeof window !== "undefined" ? window.localStorage.getItem(key) || 
initialValue : initialValue;
+  });
+
+  const setValue = (value: string | ((val: string) => string)) => {
+    const valueToStore = value instanceof Function ? value(storedValue) : 
value;
+    setStoredValue(valueToStore);
+    if (typeof window !== "undefined") {
+      if (!valueToStore) {
+        window.localStorage.removeItem(key)
+      } else {
+        window.localStorage.setItem(key, valueToStore);
+      }
+    }
+  };
+
+  return [storedValue, setValue];
+}
+
+
diff --git a/packages/merchant-backend-ui/src/hooks/instance.ts 
b/packages/merchant-backend-ui/src/hooks/instance.ts
new file mode 100644
index 000000000..14ab8de9c
--- /dev/null
+++ b/packages/merchant-backend-ui/src/hooks/instance.ts
@@ -0,0 +1,187 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+import { MerchantBackend } from '../declaration';
+import { useBackendContext } from '../context/backend';
+import { fetcher, HttpError, HttpResponse, HttpResponseOk, request, SwrError } 
from './backend';
+import useSWR, { mutate } from 'swr';
+import { useInstanceContext } from '../context/instance';
+
+
+interface InstanceAPI {
+  updateInstance: (data: 
MerchantBackend.Instances.InstanceReconfigurationMessage) => Promise<void>;
+  deleteInstance: () => Promise<void>;
+  clearToken: () => Promise<void>;
+  setNewToken: (token: string) => Promise<void>;
+}
+
+export function useManagementAPI(instanceId: string) : InstanceAPI {
+  const { url, token } = useBackendContext()
+
+  const updateInstance = async (instance: 
MerchantBackend.Instances.InstanceReconfigurationMessage): Promise<void> => {
+    await request(`${url}/management/instances/${instanceId}`, {
+      method: 'patch',
+      token,
+      data: instance
+    })
+
+    mutate([`/private/`, token, url], null)
+  };
+
+  const deleteInstance = async (): Promise<void> => {
+    await request(`${url}/management/instances/${instanceId}`, {
+      method: 'delete',
+      token,
+    })
+
+    mutate([`/private/`, token, url], null)
+  }
+
+  const clearToken = async (): Promise<void> => {
+    await request(`${url}/management/instances/${instanceId}/auth`, {
+      method: 'post',
+      token,
+      data: { method: 'external' }
+    })
+
+    mutate([`/private/`, token, url], null)
+  }
+
+  const setNewToken = async (newToken: string): Promise<void> => {
+    await request(`${url}/management/instances/${instanceId}/auth`, {
+      method: 'post',
+      token,
+      data: { method: 'token', token: newToken }
+    })
+
+    mutate([`/private/`, token, url], null)
+  }
+
+  return { updateInstance, deleteInstance, setNewToken, clearToken }
+}
+
+export function useInstanceAPI(): InstanceAPI {
+  const { url: baseUrl, token: adminToken } = useBackendContext()
+  const { token: instanceToken, id, admin } = useInstanceContext()
+
+  const { url, token } = !admin ? {
+    url: baseUrl, token: adminToken
+  } : {
+    url: `${baseUrl}/instances/${id}`, token: instanceToken
+  };
+
+  const updateInstance = async (instance: 
MerchantBackend.Instances.InstanceReconfigurationMessage): Promise<void> => {
+    await request(`${url}/private/`, {
+      method: 'patch',
+      token,
+      data: instance
+    })
+
+    if (adminToken) mutate(['/private/instances', adminToken, baseUrl], null)
+    mutate([`/private/`, token, url], null)
+  };
+
+  const deleteInstance = async (): Promise<void> => {
+    await request(`${url}/private/`, {
+      method: 'delete',
+      token: adminToken,
+    })
+
+    if (adminToken) mutate(['/private/instances', adminToken, baseUrl], null)
+    mutate([`/private/`, token, url], null)
+  }
+
+  const clearToken = async (): Promise<void> => {
+    await request(`${url}/private/auth`, {
+      method: 'post',
+      token,
+      data: { method: 'external' }
+    })
+
+    mutate([`/private/`, token, url], null)
+  }
+
+  const setNewToken = async (newToken: string): Promise<void> => {
+    await request(`${url}/private/auth`, {
+      method: 'post',
+      token,
+      data: { method: 'token', token: newToken }
+    })
+
+    mutate([`/private/`, token, url], null)
+  }
+
+  return { updateInstance, deleteInstance, setNewToken, clearToken }
+}
+
+
+export function useInstanceDetails(): 
HttpResponse<MerchantBackend.Instances.QueryInstancesResponse> {
+  const { url: baseUrl, token: baseToken } = useBackendContext();
+  const { token: instanceToken, id, admin } = useInstanceContext();
+
+  const { url, token } = !admin ? {
+    url: baseUrl, token: baseToken
+  } : {
+    url: `${baseUrl}/instances/${id}`, token: instanceToken
+  }
+
+  const { data, error, isValidating } = 
useSWR<HttpResponseOk<MerchantBackend.Instances.QueryInstancesResponse>, 
HttpError>([`/private/`, token, url], fetcher, {
+    refreshInterval:0,
+    refreshWhenHidden: false,
+    revalidateOnFocus: false,
+    revalidateOnReconnect: false,
+    refreshWhenOffline: false,
+    errorRetryCount: 0,
+    errorRetryInterval: 1,
+    shouldRetryOnError: false,
+  })
+
+  if (isValidating) return {loading:true, data: data?.data}
+  if (data) return data
+  if (error) return error
+  return {loading: true}
+}
+
+export function useManagedInstanceDetails(instanceId: string): 
HttpResponse<MerchantBackend.Instances.QueryInstancesResponse> {
+  const { url, token } = useBackendContext();
+
+  const { data, error, isValidating } = 
useSWR<HttpResponseOk<MerchantBackend.Instances.QueryInstancesResponse>, 
HttpError>([`/management/instances/${instanceId}`, token, url], fetcher, {
+    refreshInterval:0,
+    refreshWhenHidden: false,
+    revalidateOnFocus: false,
+    revalidateOnReconnect: false,
+    refreshWhenOffline: false,
+    errorRetryCount: 0,
+    errorRetryInterval: 1,
+    shouldRetryOnError: false,
+  })
+
+  if (isValidating) return {loading:true, data: data?.data}
+  if (data) return data
+  if (error) return error
+  return {loading: true}
+}
+
+export function useBackendInstances(): 
HttpResponse<MerchantBackend.Instances.InstancesResponse> {
+  const { url } = useBackendContext()
+  const { token } = useInstanceContext();
+
+  const { data, error, isValidating } = 
useSWR<HttpResponseOk<MerchantBackend.Instances.InstancesResponse>, 
HttpError>(['/management/instances', token, url], fetcher)
+
+  if (isValidating) return {loading:true, data: data?.data}
+  if (data) return data
+  if (error) return error
+  return {loading: true}
+}
diff --git a/packages/merchant-backend-ui/src/hooks/listener.ts 
b/packages/merchant-backend-ui/src/hooks/listener.ts
new file mode 100644
index 000000000..231ed6c87
--- /dev/null
+++ b/packages/merchant-backend-ui/src/hooks/listener.ts
@@ -0,0 +1,68 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { useState } from "preact/hooks";
+
+/**
+ * returns subscriber and activator
+ * subscriber will receive a method (listener) that will be call when the 
activator runs.
+ * the result of calling the listener will be sent to @action
+ *
+ * @param action from <T> to <R>
+ * @returns activator and subscriber, undefined activator means that there is 
not subscriber
+ */
+
+export function useListener<T, R = any>(action: (r: T) => Promise<R>): 
[undefined | (() => Promise<R>), (listener?: () => T) => void] {
+  type RunnerHandler = { toBeRan?: () => Promise<R>; };
+  const [state, setState] = useState<RunnerHandler>({});
+
+  /**
+   * subscriber will receive a method that will be call when the activator runs
+   *
+   * @param listener function to be run when the activator runs
+   */
+  const subscriber = (listener?: () => T) => {
+    if (listener) {
+      setState({
+        toBeRan: () => {
+          const whatWeGetFromTheListener = listener();
+          return action(whatWeGetFromTheListener);
+        }
+      });
+    } else {
+      setState({
+        toBeRan: undefined
+      })
+    }
+  };
+
+  /**
+   * activator will call runner if there is someone subscribed
+   */
+  const activator = state.toBeRan ? async () => {
+    if (state.toBeRan) {
+      return state.toBeRan();
+    }
+    return Promise.reject();
+  } : undefined;
+
+  return [activator, subscriber];
+}
diff --git a/packages/merchant-backend-ui/src/hooks/notification.ts 
b/packages/merchant-backend-ui/src/hooks/notification.ts
new file mode 100644
index 000000000..d1dfbff2c
--- /dev/null
+++ b/packages/merchant-backend-ui/src/hooks/notification.ts
@@ -0,0 +1,43 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { useCallback, useState } from "preact/hooks";
+import { Notification } from '../utils/types';
+
+interface Result {
+  notification?: Notification;
+  pushNotification: (n: Notification) => void;
+  removeNotification: () => void;
+}
+
+export function useNotification(): Result {
+  const [notification, setNotifications] = 
useState<Notification|undefined>(undefined)
+
+  const pushNotification = useCallback((n: Notification): void => {
+    setNotifications(n)
+  },[])
+
+  const removeNotification = useCallback(() => {
+    setNotifications(undefined)
+  },[])
+
+  return { notification, pushNotification, removeNotification }
+}
diff --git a/packages/merchant-backend-ui/src/hooks/notifications.ts 
b/packages/merchant-backend-ui/src/hooks/notifications.ts
new file mode 100644
index 000000000..1c0c37308
--- /dev/null
+++ b/packages/merchant-backend-ui/src/hooks/notifications.ts
@@ -0,0 +1,48 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { useState } from "preact/hooks";
+import { Notification } from '../utils/types';
+
+interface Result {
+  notifications: Notification[];
+  pushNotification: (n: Notification) => void;
+  removeNotification: (n: Notification) => void;
+}
+
+type NotificationWithDate = Notification & { since: Date }
+
+export function useNotifications(initial: Notification[] = [], timeout = 
3000): Result {
+  const [notifications, setNotifications] = 
useState<(NotificationWithDate)[]>(initial.map(i => ({...i, since: new Date() 
})))
+
+  const pushNotification = (n: Notification): void => {
+    const entry = { ...n, since: new Date() }
+    setNotifications(ns => [...ns, entry])
+    if (n.type !== 'ERROR') setTimeout(() => {
+      setNotifications(ns => ns.filter(x => x.since !== entry.since))
+    }, timeout)
+  }
+
+  const removeNotification = (notif: Notification) => {
+    setNotifications((ns: NotificationWithDate[]) => ns.filter(n => n !== 
notif))
+  }
+  return { notifications, pushNotification, removeNotification }
+}
diff --git a/packages/merchant-backend-ui/src/hooks/order.ts 
b/packages/merchant-backend-ui/src/hooks/order.ts
new file mode 100644
index 000000000..4a17eac30
--- /dev/null
+++ b/packages/merchant-backend-ui/src/hooks/order.ts
@@ -0,0 +1,217 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+import { useEffect, useState } from 'preact/hooks';
+import useSWR from 'swr';
+import { useBackendContext } from '../context/backend';
+import { useInstanceContext } from '../context/instance';
+import { MerchantBackend } from '../declaration';
+import { MAX_RESULT_SIZE, PAGE_SIZE } from '../utils/constants';
+import { fetcher, HttpError, HttpResponse, HttpResponseOk, 
HttpResponsePaginated, mutateAll, request } from './backend';
+
+export interface OrderAPI {
+  //FIXME: add OutOfStockResponse on 410
+  createOrder: (data: MerchantBackend.Orders.PostOrderRequest) => 
Promise<HttpResponseOk<MerchantBackend.Orders.PostOrderResponse>>;
+  forgetOrder: (id: string, data: MerchantBackend.Orders.ForgetRequest) => 
Promise<HttpResponseOk<void>>;
+  refundOrder: (id: string, data: MerchantBackend.Orders.RefundRequest) => 
Promise<HttpResponseOk<MerchantBackend.Orders.MerchantRefundResponse>>;
+  deleteOrder: (id: string) => Promise<HttpResponseOk<void>>;
+  getPaymentURL: (id: string) => Promise<HttpResponseOk<string>>;
+}
+
+type YesOrNo = 'yes' | 'no';
+
+
+export function orderFetcher<T>(url: string, token: string, backend: string, 
paid?: YesOrNo, refunded?: YesOrNo, wired?: YesOrNo, searchDate?: Date, delta?: 
number): Promise<HttpResponseOk<T>> {
+  const date_ms = delta && delta < 0 && searchDate ? searchDate.getTime() + 1 
: searchDate?.getTime()
+  const params: any = {}
+  if (paid !== undefined) params.paid = paid
+  if (delta !== undefined) params.delta = delta
+  if (refunded !== undefined) params.refunded = refunded
+  if (wired !== undefined) params.wired = wired
+  if (date_ms !== undefined) params.date_ms = date_ms
+  return request<T>(`${backend}${url}`, { token, params })
+}
+
+
+export function useOrderAPI(): OrderAPI {
+  const { url: baseUrl, token: adminToken } = useBackendContext()
+  const { token: instanceToken, id, admin } = useInstanceContext()
+
+  const { url, token } = !admin ? {
+    url: baseUrl, token: adminToken
+  } : {
+    url: `${baseUrl}/instances/${id}`, token: instanceToken
+  }
+
+  const createOrder = async (data: MerchantBackend.Orders.PostOrderRequest): 
Promise<HttpResponseOk<MerchantBackend.Orders.PostOrderResponse>> => {
+    const res = await 
request<MerchantBackend.Orders.PostOrderResponse>(`${url}/private/orders`, {
+      method: 'post',
+      token,
+      data
+    })
+    await mutateAll(/@"\/private\/orders"@/)
+    return res
+  }
+  const refundOrder = async (orderId: string, data: 
MerchantBackend.Orders.RefundRequest): 
Promise<HttpResponseOk<MerchantBackend.Orders.MerchantRefundResponse>> => {
+    mutateAll(/@"\/private\/orders"@/)
+    return 
request<MerchantBackend.Orders.MerchantRefundResponse>(`${url}/private/orders/${orderId}/refund`,
 {
+      method: 'post',
+      token,
+      data
+    })
+
+    // return res
+  }
+
+  const forgetOrder = async (orderId: string, data: 
MerchantBackend.Orders.ForgetRequest): Promise<HttpResponseOk<void>> => {
+    mutateAll(/@"\/private\/orders"@/)
+    return request(`${url}/private/orders/${orderId}/forget`, {
+      method: 'patch',
+      token,
+      data
+    })
+
+  }
+  const deleteOrder = async (orderId: string): Promise<HttpResponseOk<void>> 
=> {
+    mutateAll(/@"\/private\/orders"@/)
+    return request(`${url}/private/orders/${orderId}`, {
+      method: 'delete',
+      token
+    })
+  }
+
+  const getPaymentURL = async (orderId: string): 
Promise<HttpResponseOk<string>> => {
+    return 
request<MerchantBackend.Orders.MerchantOrderStatusResponse>(`${url}/private/orders/${orderId}`,
 {
+      method: 'get',
+      token
+    }).then((res) => {
+      const url = res.data.order_status === "unpaid" ? res.data.taler_pay_uri 
: res.data.contract_terms.fulfillment_url
+      const response: HttpResponseOk<string> = res as any
+      response.data = url || ''
+      return response
+    })
+  }
+
+  return { createOrder, forgetOrder, deleteOrder, refundOrder, getPaymentURL }
+}
+
+export function useOrderDetails(oderId: string): 
HttpResponse<MerchantBackend.Orders.MerchantOrderStatusResponse> {
+  const { url: baseUrl, token: baseToken } = useBackendContext();
+  const { token: instanceToken, id, admin } = useInstanceContext();
+
+  const { url, token } = !admin ? {
+    url: baseUrl, token: baseToken
+  } : {
+    url: `${baseUrl}/instances/${id}`, token: instanceToken
+  };
+
+  const { data, error, isValidating } = 
useSWR<HttpResponseOk<MerchantBackend.Orders.MerchantOrderStatusResponse>, 
HttpError>([`/private/orders/${oderId}`, token, url], fetcher, {
+    refreshInterval: 0,
+    refreshWhenHidden: false,
+    revalidateOnFocus: false,
+    revalidateOnReconnect: false,
+    refreshWhenOffline: false,
+  })
+
+  if (isValidating) return { loading: true, data: data?.data }
+  if (data) return data
+  if (error) return error
+  return { loading: true }
+}
+
+export interface InstanceOrderFilter {
+  paid?: YesOrNo;
+  refunded?: YesOrNo;
+  wired?: YesOrNo;
+  date?: Date;
+}
+
+export function useInstanceOrders(args?: InstanceOrderFilter, updateFilter?: 
(d: Date) => void): HttpResponsePaginated<MerchantBackend.Orders.OrderHistory> {
+  const { url: baseUrl, token: baseToken } = useBackendContext();
+  const { token: instanceToken, id, admin } = useInstanceContext();
+
+  const { url, token } = !admin ? {
+    url: baseUrl, token: baseToken
+  } : {
+    url: `${baseUrl}/instances/${id}`, token: instanceToken
+  }
+
+  const [pageBefore, setPageBefore] = useState(1)
+  const [pageAfter, setPageAfter] = useState(1)
+
+  const totalAfter = pageAfter * PAGE_SIZE;
+  const totalBefore = args?.date ? pageBefore * PAGE_SIZE : 0;
+
+  /**
+   * FIXME: this can be cleaned up a little
+   * 
+   * the logic of double query should be inside the orderFetch so from the 
hook perspective and cache
+   * is just one query and one error status
+   */
+  const { data: beforeData, error: beforeError, isValidating: loadingBefore } 
= useSWR<HttpResponseOk<MerchantBackend.Orders.OrderHistory>, HttpError>(
+    [`/private/orders`, token, url, args?.paid, args?.refunded, args?.wired, 
args?.date, totalBefore],
+    orderFetcher,
+  )
+  const { data: afterData, error: afterError, isValidating: loadingAfter } = 
useSWR<HttpResponseOk<MerchantBackend.Orders.OrderHistory>, HttpError>(
+    [`/private/orders`, token, url, args?.paid, args?.refunded, args?.wired, 
args?.date, -totalAfter],
+    orderFetcher,
+  )
+
+  //this will save last result
+  const [lastBefore, setLastBefore] = 
useState<HttpResponse<MerchantBackend.Orders.OrderHistory>>({ loading: true })
+  const [lastAfter, setLastAfter] = 
useState<HttpResponse<MerchantBackend.Orders.OrderHistory>>({ loading: true })
+  useEffect(() => {
+    if (afterData) setLastAfter(afterData)
+    if (beforeData) setLastBefore(beforeData)
+  }, [afterData, beforeData])
+
+  // this has problems when there are some ids missing
+
+  if (beforeError) return beforeError
+  if (afterError) return afterError
+
+
+  const pagination = {
+    isReachingEnd: afterData && afterData.data.orders.length < totalAfter,
+    isReachingStart: (!args?.date) || (beforeData && 
beforeData.data.orders.length < totalBefore),
+    loadMore: () => {
+      if (!afterData) return
+      if (afterData.data.orders.length < MAX_RESULT_SIZE) {
+        setPageAfter(pageAfter + 1)
+      } else {
+        const from = afterData.data.orders[afterData.data.orders.length - 
1].timestamp.t_s
+        if (from && updateFilter) updateFilter(new Date(from))
+      }
+    },
+    loadMorePrev: () => {
+      if (!beforeData) return
+      if (beforeData.data.orders.length < MAX_RESULT_SIZE) {
+        setPageBefore(pageBefore + 1)
+      } else if (beforeData) {
+        const from = beforeData.data.orders[beforeData.data.orders.length - 
1].timestamp.t_s
+        if (from && updateFilter) updateFilter(new Date(from))
+      }
+    },
+  }
+
+  const orders = !beforeData || !afterData ? [] : (beforeData || 
lastBefore).data.orders.slice().reverse().concat((afterData || 
lastAfter).data.orders)
+  if (loadingAfter || loadingBefore) return { loading: true, data: { orders } }
+  if (beforeData && afterData) {
+    return { ok: true, data: { orders }, ...pagination }
+  }
+  return { loading: true }
+
+}
+
diff --git a/packages/merchant-backend-ui/src/hooks/product.ts 
b/packages/merchant-backend-ui/src/hooks/product.ts
new file mode 100644
index 000000000..4fc8bccb7
--- /dev/null
+++ b/packages/merchant-backend-ui/src/hooks/product.ts
@@ -0,0 +1,223 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+import { useEffect } from "preact/hooks";
+import useSWR, { trigger, useSWRInfinite, cache, mutate } from "swr";
+import { useBackendContext } from "../context/backend";
+// import { useFetchContext } from '../context/fetch';
+import { useInstanceContext } from "../context/instance";
+import { MerchantBackend, WithId } from "../declaration";
+import {
+  fetcher,
+  HttpError,
+  HttpResponse,
+  HttpResponseOk,
+  mutateAll,
+  request,
+} from "./backend";
+
+export interface ProductAPI {
+  createProduct: (
+    data: MerchantBackend.Products.ProductAddDetail
+  ) => Promise<void>;
+  updateProduct: (
+    id: string,
+    data: MerchantBackend.Products.ProductPatchDetail
+  ) => Promise<void>;
+  deleteProduct: (id: string) => Promise<void>;
+  lockProduct: (
+    id: string,
+    data: MerchantBackend.Products.LockRequest
+  ) => Promise<void>;
+}
+
+export function useProductAPI(): ProductAPI {
+  const { url: baseUrl, token: adminToken } = useBackendContext();
+  const { token: instanceToken, id, admin } = useInstanceContext();
+
+  const { url, token } = !admin
+    ? {
+        url: baseUrl,
+        token: adminToken,
+      }
+    : {
+        url: `${baseUrl}/instances/${id}`,
+        token: instanceToken,
+      };
+
+  const createProduct = async (
+    data: MerchantBackend.Products.ProductAddDetail
+  ): Promise<void> => {
+    await request(`${url}/private/products`, {
+      method: "post",
+      token,
+      data,
+    });
+
+    await mutateAll(/@"\/private\/products"@/, null);
+  };
+
+  const updateProduct = async (
+    productId: string,
+    data: MerchantBackend.Products.ProductPatchDetail
+  ): Promise<void> => {
+    const r = await request(`${url}/private/products/${productId}`, {
+      method: "patch",
+      token,
+      data,
+    });
+
+    await mutateAll(/@"\/private\/products\/.*"@/);
+    return Promise.resolve();
+  };
+
+  const deleteProduct = async (productId: string): Promise<void> => {
+    await request(`${url}/private/products/${productId}`, {
+      method: "delete",
+      token,
+    });
+
+    await mutateAll(/@"\/private\/products"@/);
+  };
+
+  const lockProduct = async (
+    productId: string,
+    data: MerchantBackend.Products.LockRequest
+  ): Promise<void> => {
+    await request(`${url}/private/products/${productId}/lock`, {
+      method: "post",
+      token,
+      data,
+    });
+
+    await mutateAll(/@"\/private\/products"@/);
+  };
+
+  return { createProduct, updateProduct, deleteProduct, lockProduct };
+}
+
+export function useInstanceProducts(): HttpResponse<
+  (MerchantBackend.Products.ProductDetail & WithId)[]
+> {
+  const { url: baseUrl, token: baseToken } = useBackendContext();
+  const { token: instanceToken, id, admin } = useInstanceContext();
+  // const { useSWR, useSWRInfinite } = useFetchContext();
+
+  const { url, token } = !admin
+    ? {
+        url: baseUrl,
+        token: baseToken,
+      }
+    : {
+        url: `${baseUrl}/instances/${id}`,
+        token: instanceToken,
+      };
+
+  const {
+    data: list,
+    error: listError,
+    isValidating: listLoading,
+  } = useSWR<
+    HttpResponseOk<MerchantBackend.Products.InventorySummaryResponse>,
+    HttpError
+  >([`/private/products`, token, url], fetcher, {
+    refreshInterval: 0,
+    refreshWhenHidden: false,
+    revalidateOnFocus: false,
+    revalidateOnReconnect: false,
+    refreshWhenOffline: false,
+  });
+
+  const {
+    data: products,
+    error: productError,
+    setSize,
+    size,
+  } = useSWRInfinite<
+    HttpResponseOk<MerchantBackend.Products.ProductDetail>,
+    HttpError
+  >(
+    (pageIndex: number) => {
+      if (!list?.data || !list.data.products.length || listError || 
listLoading)
+        return null;
+      return [
+        `/private/products/${list.data.products[pageIndex].product_id}`,
+        token,
+        url,
+      ];
+    },
+    fetcher,
+    {
+      revalidateAll: true,
+    }
+  );
+
+  useEffect(() => {
+    if (list?.data && list.data.products.length > 0) {
+      setSize(list.data.products.length);
+    }
+  }, [list?.data.products.length, listLoading]);
+
+  if (listLoading) return { loading: true, data: [] };
+  if (listError) return listError;
+  if (productError) return productError;
+  if (list?.data && list.data.products.length === 0) {
+    return { ok: true, data: [] };
+  }
+  if (products) {
+    const dataWithId = products.map((d) => {
+      //take the id from the queried url
+      return {
+        ...d.data,
+        id: d.info?.url.replace(/.*\/private\/products\//, "") || "",
+      };
+    });
+    return { ok: true, data: dataWithId };
+  }
+  return { loading: true };
+}
+
+export function useProductDetails(
+  productId: string
+): HttpResponse<MerchantBackend.Products.ProductDetail> {
+  const { url: baseUrl, token: baseToken } = useBackendContext();
+  const { token: instanceToken, id, admin } = useInstanceContext();
+
+  const { url, token } = !admin
+    ? {
+        url: baseUrl,
+        token: baseToken,
+      }
+    : {
+        url: `${baseUrl}/instances/${id}`,
+        token: instanceToken,
+      };
+
+  const { data, error, isValidating } = useSWR<
+    HttpResponseOk<MerchantBackend.Products.ProductDetail>,
+    HttpError
+  >([`/private/products/${productId}`, token, url], fetcher, {
+    refreshInterval: 0,
+    refreshWhenHidden: false,
+    revalidateOnFocus: false,
+    revalidateOnReconnect: false,
+    refreshWhenOffline: false,
+  });
+
+  if (isValidating) return { loading: true, data: data?.data };
+  if (data) return data;
+  if (error) return error;
+  return { loading: true };
+}
diff --git a/packages/merchant-backend-ui/src/hooks/tips.ts 
b/packages/merchant-backend-ui/src/hooks/tips.ts
new file mode 100644
index 000000000..345e1faa5
--- /dev/null
+++ b/packages/merchant-backend-ui/src/hooks/tips.ts
@@ -0,0 +1,159 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+import useSWR from 'swr';
+import { useBackendContext } from '../context/backend';
+import { useInstanceContext } from '../context/instance';
+import { MerchantBackend } from '../declaration';
+import { fetcher, HttpError, HttpResponse, HttpResponseOk, mutateAll, request 
} from './backend';
+
+
+export function useReservesAPI(): ReserveMutateAPI {
+  const { url: baseUrl, token: adminToken } = useBackendContext();
+  const { token: instanceToken, id, admin } = useInstanceContext();
+
+  const { url, token } = !admin ? {
+    url: baseUrl, token: adminToken
+  } : {
+    url: `${baseUrl}/instances/${id}`, token: instanceToken
+  };
+
+  const createReserve = async (data: 
MerchantBackend.Tips.ReserveCreateRequest): 
Promise<HttpResponseOk<MerchantBackend.Tips.ReserveCreateConfirmation>> => {
+    const res = await 
request<MerchantBackend.Tips.ReserveCreateConfirmation>(`${url}/private/reserves`,
 {
+      method: 'post',
+      token,
+      data
+    });
+
+    await mutateAll(/@"\/private\/reserves"@/);
+
+    return res
+  };
+
+  const authorizeTipReserve = async (pub: string, data: 
MerchantBackend.Tips.TipCreateRequest): 
Promise<HttpResponseOk<MerchantBackend.Tips.TipCreateConfirmation>> => {
+    const res = await 
request<MerchantBackend.Tips.TipCreateConfirmation>(`${url}/private/reserves/${pub}/authorize-tip`,
 {
+      method: 'post',
+      token,
+      data
+    });
+    await mutateAll(/@"\/private\/reserves"@/);
+
+    return res
+  };
+
+  const authorizeTip = async (data: MerchantBackend.Tips.TipCreateRequest): 
Promise<HttpResponseOk<MerchantBackend.Tips.TipCreateConfirmation>> => {
+    const res = await 
request<MerchantBackend.Tips.TipCreateConfirmation>(`${url}/private/tips`, {
+      method: 'post',
+      token,
+      data
+    });
+
+    await mutateAll(/@"\/private\/reserves"@/);
+
+    return res
+  };
+
+  const deleteReserve = async (pub: string): Promise<HttpResponse<void>> => {
+    const res = await request<void>(`${url}/private/reserves/${pub}`, {
+      method: 'delete',
+      token,
+    });
+
+    await mutateAll(/@"\/private\/reserves"@/);
+
+    return res
+  };
+
+
+  return { createReserve, authorizeTip, authorizeTipReserve, deleteReserve };
+}
+
+export interface ReserveMutateAPI {
+  createReserve: (data: MerchantBackend.Tips.ReserveCreateRequest) => 
Promise<HttpResponseOk<MerchantBackend.Tips.ReserveCreateConfirmation>>;
+  authorizeTipReserve: (id: string, data: 
MerchantBackend.Tips.TipCreateRequest) => 
Promise<HttpResponseOk<MerchantBackend.Tips.TipCreateConfirmation>>;
+  authorizeTip: (data: MerchantBackend.Tips.TipCreateRequest) => 
Promise<HttpResponseOk<MerchantBackend.Tips.TipCreateConfirmation>>;
+  deleteReserve: (id: string) => Promise<HttpResponse<void>>;
+}
+
+export function useInstanceTips(): 
HttpResponse<MerchantBackend.Tips.TippingReserveStatus> {
+  const { url: baseUrl, token: baseToken } = useBackendContext();
+  const { token: instanceToken, id, admin } = useInstanceContext();
+
+  const { url, token } = !admin ? {
+    url: baseUrl, token: baseToken
+  } : {
+    url: `${baseUrl}/instances/${id}`, token: instanceToken
+  }
+
+  const { data, error, isValidating } = 
useSWR<HttpResponseOk<MerchantBackend.Tips.TippingReserveStatus>, 
HttpError>([`/private/reserves`, token, url], fetcher)
+
+  if (isValidating) return { loading: true, data: data?.data }
+  if (data) return data
+  if (error) return error
+  return { loading: true }
+}
+
+
+export function useReserveDetails(reserveId: string): 
HttpResponse<MerchantBackend.Tips.ReserveDetail> {
+  const { url: baseUrl } = useBackendContext();
+  const { token, id: instanceId, admin } = useInstanceContext();
+
+  const url = !admin ? baseUrl : `${baseUrl}/instances/${instanceId}`
+
+  const { data, error, isValidating } = 
useSWR<HttpResponseOk<MerchantBackend.Tips.ReserveDetail>, 
HttpError>([`/private/reserves/${reserveId}`, token, url], 
reserveDetailFetcher, {
+    refreshInterval:0,
+    refreshWhenHidden: false,
+    revalidateOnFocus: false,
+    revalidateOnReconnect: false,
+    refreshWhenOffline: false,
+  })
+
+  if (isValidating) return { loading: true, data: data?.data }
+  if (data) return data
+  if (error) return error
+  return { loading: true }
+}
+
+export function useTipDetails(tipId: string): 
HttpResponse<MerchantBackend.Tips.TipDetails> {
+  const { url: baseUrl } = useBackendContext();
+  const { token, id: instanceId, admin } = useInstanceContext();
+
+  const url = !admin ? baseUrl : `${baseUrl}/instances/${instanceId}`
+
+  const { data, error, isValidating } = 
useSWR<HttpResponseOk<MerchantBackend.Tips.TipDetails>, 
HttpError>([`/private/tips/${tipId}`, token, url], tipsDetailFetcher, {
+    refreshInterval:0,
+    refreshWhenHidden: false,
+    revalidateOnFocus: false,
+    revalidateOnReconnect: false,
+    refreshWhenOffline: false,
+  })
+
+  if (isValidating) return { loading: true, data: data?.data }
+  if (data) return data
+  if (error) return error
+  return { loading: true }
+}
+
+export function reserveDetailFetcher<T>(url: string, token: string, backend: 
string): Promise<HttpResponseOk<T>> {
+  return request<T>(`${backend}${url}`, { token, params: {
+    tips: 'yes'
+  } })
+}
+
+export function tipsDetailFetcher<T>(url: string, token: string, backend: 
string): Promise<HttpResponseOk<T>> {
+  return request<T>(`${backend}${url}`, { token, params: {
+    pickups: 'yes'
+  } })
+}
diff --git a/packages/merchant-backend-ui/src/hooks/transfer.ts 
b/packages/merchant-backend-ui/src/hooks/transfer.ts
new file mode 100644
index 000000000..482f00dc5
--- /dev/null
+++ b/packages/merchant-backend-ui/src/hooks/transfer.ts
@@ -0,0 +1,150 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+import { MerchantBackend } from '../declaration';
+import { useBackendContext } from '../context/backend';
+import { request, mutateAll, HttpResponse, HttpError, HttpResponseOk, 
HttpResponsePaginated } from './backend';
+import useSWR from 'swr';
+import { useInstanceContext } from '../context/instance';
+import { MAX_RESULT_SIZE, PAGE_SIZE } from '../utils/constants';
+import { useEffect, useState } from 'preact/hooks';
+
+async function transferFetcher<T>(url: string, token: string, backend: string, 
payto_uri?: string, verified?: string, position?: string, delta?: number): 
Promise<HttpResponseOk<T>> {
+  const params: any = {}
+  if (payto_uri !== undefined) params.payto_uri = payto_uri
+  if (verified !== undefined) params.verified = verified
+  if (delta !== undefined) {
+    // if (delta > 0) {
+    //   params.after = searchDate?.getTime()
+    // } else {
+    //   params.before = searchDate?.getTime()
+    // }
+    params.limit = delta
+  }
+  if (position !== undefined) params.offset = position
+
+  return request<T>(`${backend}${url}`, { token, params })
+}
+
+export function useTransferAPI(): TransferAPI {
+  const { url: baseUrl, token: adminToken } = useBackendContext();
+  const { token: instanceToken, id, admin } = useInstanceContext();
+
+  const { url, token } = !admin ? {
+    url: baseUrl, token: adminToken
+  } : {
+    url: `${baseUrl}/instances/${id}`, token: instanceToken
+  };
+
+  const informTransfer = async (data: 
MerchantBackend.Transfers.TransferInformation): 
Promise<HttpResponseOk<MerchantBackend.Transfers.MerchantTrackTransferResponse>>
 => {
+    mutateAll(/@"\/private\/transfers"@/);
+
+    return 
request<MerchantBackend.Transfers.MerchantTrackTransferResponse>(`${url}/private/transfers`,
 {
+      method: 'post',
+      token,
+      data
+    });
+  };
+
+  return { informTransfer };
+}
+
+export interface TransferAPI {
+  informTransfer: (data: MerchantBackend.Transfers.TransferInformation) => 
Promise<HttpResponseOk<MerchantBackend.Transfers.MerchantTrackTransferResponse>>;
+}
+
+export interface InstanceTransferFilter {
+  payto_uri?: string;
+  verified?: 'yes' | 'no';
+  position?: string;
+}
+
+
+export function useInstanceTransfers(args?: InstanceTransferFilter, 
updatePosition?: (id: string) => void): 
HttpResponsePaginated<MerchantBackend.Transfers.TransferList> {
+  const { url: baseUrl, token: baseToken } = useBackendContext();
+  const { token: instanceToken, id, admin } = useInstanceContext();
+
+  const { url, token } = !admin ? {
+    url: baseUrl, token: baseToken
+  } : {
+    url: `${baseUrl}/instances/${id}`, token: instanceToken
+  }
+
+  const [pageBefore, setPageBefore] = useState(1)
+  const [pageAfter, setPageAfter] = useState(1)
+
+  const totalAfter = pageAfter * PAGE_SIZE;
+  const totalBefore = args?.position !== undefined ? pageBefore * PAGE_SIZE : 
0;
+
+  /**
+   * FIXME: this can be cleaned up a little
+   * 
+   * the logic of double query should be inside the orderFetch so from the 
hook perspective and cache
+   * is just one query and one error status
+   */
+  const { data: beforeData, error: beforeError, isValidating: loadingBefore } 
= useSWR<HttpResponseOk<MerchantBackend.Transfers.TransferList>, HttpError>(
+    [`/private/transfers`, token, url, args?.payto_uri, args?.verified, 
args?.position, totalBefore],
+    transferFetcher,
+  )
+  const { data: afterData, error: afterError, isValidating: loadingAfter } = 
useSWR<HttpResponseOk<MerchantBackend.Transfers.TransferList>, HttpError>(
+    [`/private/transfers`, token, url, args?.payto_uri, args?.verified, 
args?.position, -totalAfter],
+    transferFetcher,
+  )
+
+  //this will save last result
+  const [lastBefore, setLastBefore] = 
useState<HttpResponse<MerchantBackend.Transfers.TransferList>>({ loading: true 
})
+  const [lastAfter, setLastAfter] = 
useState<HttpResponse<MerchantBackend.Transfers.TransferList>>({ loading: true 
})
+  useEffect(() => {
+    if (afterData) setLastAfter(afterData)
+    if (beforeData) setLastBefore(beforeData)
+  }, [afterData, beforeData])
+
+  // this has problems when there are some ids missing
+
+  if (beforeError) return beforeError
+  if (afterError) return afterError
+
+  const pagination = {
+    isReachingEnd: afterData && afterData.data.transfers.length < totalAfter,
+    isReachingStart: (!args?.position) || (beforeData && 
beforeData.data.transfers.length < totalBefore),
+    loadMore: () => {
+      if (!afterData) return
+      if (afterData.data.transfers.length < MAX_RESULT_SIZE) {
+        setPageAfter(pageAfter + 1)
+      } else {
+        const from = 
`${afterData.data.transfers[afterData.data.transfers.length - 
1].transfer_serial_id}`
+        if (from && updatePosition) updatePosition(from)
+      }
+    },
+    loadMorePrev: () => {
+      if (!beforeData) return
+      if (beforeData.data.transfers.length < MAX_RESULT_SIZE) {
+        setPageBefore(pageBefore + 1)
+      } else if (beforeData) {
+        const from = 
`${beforeData.data.transfers[beforeData.data.transfers.length - 
1].transfer_serial_id}`
+        if (from && updatePosition) updatePosition(from)
+      }
+    },
+  }
+
+  const transfers = !beforeData || !afterData ? [] : (beforeData || 
lastBefore).data.transfers.slice().reverse().concat((afterData || 
lastAfter).data.transfers)
+  if (loadingAfter || loadingBefore) return { loading: true, data: { transfers 
} }
+  if (beforeData && afterData) {
+    return { ok: true, data: { transfers }, ...pagination }
+  }
+  return { loading: true }
+}
+
+
diff --git a/packages/merchant-backend-ui/src/i18n/de.po 
b/packages/merchant-backend-ui/src/i18n/de.po
new file mode 100644
index 000000000..6b35bd0ce
--- /dev/null
+++ b/packages/merchant-backend-ui/src/i18n/de.po
@@ -0,0 +1,1057 @@
+# This file is part of TALER
+# (C) 2016 GNUnet e.V.
+#
+# TALER is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3, or (at your option) any later version.
+#
+# TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Taler Wallet\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2016-11-23 00:00+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: src/ApplicationReadyRoutes.tsx:50 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:299
+#, c-format
+msgid "Access denied"
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:51 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:300
+#, c-format
+msgid "Check your token is valid"
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:72
+#, c-format
+msgid "Couldn't access the server."
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:73
+#, c-format
+msgid "Could not infer instance id from url %1$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:109
+#, c-format
+msgid "HTTP status #%1$s: Server reported a problem"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:110
+#, c-format
+msgid "Got message: \"%1$s\" from: %2$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:127
+#, c-format
+msgid "No default instance"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:128
+#, c-format
+msgid ""
+"in order to use merchant backoffice, you should create the default instance"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:288
+#, c-format
+msgid "Server reported a problem: HTTP status #%1$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:289
+#, c-format
+msgid "Got message: %1$s from: %2$s"
+msgstr ""
+
+#: src/components/exception/login.tsx:46
+#, c-format
+msgid "Login required"
+msgstr ""
+
+#: src/components/exception/login.tsx:49
+#, c-format
+msgid ""
+"Please enter your auth token. Token should have \"secret-token:\" and start "
+"with Bearer or ApiKey"
+msgstr ""
+
+#: src/components/exception/login.tsx:86 src/components/modal/index.tsx:53
+#: src/components/modal/index.tsx:75 src/paths/admin/create/CreatePage.tsx:115
+#: src/paths/instance/orders/create/CreatePage.tsx:325
+#: src/paths/instance/products/create/CreatePage.tsx:51
+#: src/paths/instance/products/list/Table.tsx:174
+#: src/paths/instance/products/list/Table.tsx:228
+#: src/paths/instance/products/update/UpdatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:134
+#, c-format
+msgid "Confirm"
+msgstr ""
+
+#: src/components/form/InputArray.tsx:72
+#, c-format
+msgid "The value %1$s is invalid for a payment url"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:67
+#: src/paths/instance/orders/list/index.tsx:123
+#, c-format
+msgid "pick a date"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:81
+#, c-format
+msgid "clear"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:83
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "never"
+msgstr ""
+
+#: src/components/form/InputImage.tsx:80
+#, c-format
+msgid "Image should be smaller than 1 MB"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:28
+#, c-format
+msgid "Country"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:30
+#: src/paths/admin/create/CreatePage.tsx:99
+#: src/paths/instance/transfers/list/Table.tsx:124
+#: src/paths/instance/update/UpdatePage.tsx:118
+#, c-format
+msgid "Address"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:34
+#, c-format
+msgid "Building number"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:35
+#, c-format
+msgid "Building name"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:36
+#, c-format
+msgid "Street"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:37
+#, c-format
+msgid "Post code"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:38
+#, c-format
+msgid "Town location"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:39
+#, c-format
+msgid "Town"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:40
+#, c-format
+msgid "District"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:41
+#, c-format
+msgid "Country subdivision"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:59
+#, c-format
+msgid "Product id"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:60
+#: src/components/product/ProductForm.tsx:99
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:122
+#: src/paths/instance/orders/list/Table.tsx:227
+#: src/paths/instance/products/list/Table.tsx:86
+#, c-format
+msgid "Description"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:73
+#: src/components/form/InputTaxes.tsx:81
+#: src/paths/admin/create/CreatePage.tsx:87 src/paths/admin/list/Table.tsx:110
+#: src/paths/instance/details/DetailPage.tsx:76
+#: src/paths/instance/update/UpdatePage.tsx:106
+#, c-format
+msgid "Name"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:102
+#, c-format
+msgid "loading..."
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:108
+#, c-format
+msgid "no products found"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:116
+#, c-format
+msgid "no results"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:33
+#, c-format
+msgid "Deleting"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:34
+#, c-format
+msgid "Changing"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:60
+#, c-format
+msgid "Manage token"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:83
+#, c-format
+msgid "Update"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:100
+#: src/paths/instance/orders/create/CreatePage.tsx:252
+#: src/paths/instance/orders/create/CreatePage.tsx:273
+#, c-format
+msgid "Remove"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:106 src/components/modal/index.tsx:52
+#: src/components/modal/index.tsx:73 src/paths/admin/create/CreatePage.tsx:114
+#: src/paths/instance/orders/create/CreatePage.tsx:324
+#: src/paths/instance/products/create/CreatePage.tsx:50
+#: src/paths/instance/products/list/Table.tsx:166
+#: src/paths/instance/products/list/Table.tsx:218
+#: src/paths/instance/products/update/UpdatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:88
+#: src/paths/instance/update/UpdatePage.tsx:133
+#, c-format
+msgid "Cancel"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:91
+#, c-format
+msgid "Manage stock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:93
+#, c-format
+msgid "Infinite"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:105
+#, c-format
+msgid "lost cannot be greater that current + incoming (max %1$s)"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:111
+#, c-format
+msgid "current stock will change from %1$s to %2$s"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:112
+#, c-format
+msgid "current stock will stay at %1$s"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:129
+#: src/paths/instance/products/list/Table.tsx:204
+#, c-format
+msgid "Incoming"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:130
+#: src/paths/instance/products/list/Table.tsx:205
+#, c-format
+msgid "Lost"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:142
+#, c-format
+msgid "Current"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:145
+#, c-format
+msgid "without stock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:150
+#, c-format
+msgid "Next restock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:152
+#, c-format
+msgid "Delivery address"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:73
+#, c-format
+msgid "this product has no taxes"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:77
+#: src/paths/instance/orders/details/DetailPage.tsx:145
+#: src/paths/instance/orders/details/DetailPage.tsx:296
+#: src/paths/instance/orders/list/Table.tsx:116
+#: src/paths/instance/transfers/create/CreatePage.tsx:84
+#, c-format
+msgid "Amount"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:78
+#, c-format
+msgid "currency and value separated with colon"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:84
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:78
+#, c-format
+msgid "Add"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:53
+#, c-format
+msgid "Instance"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:59
+#, c-format
+msgid "Settings"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:65
+#: src/paths/instance/orders/list/Table.tsx:60
+#, c-format
+msgid "Orders"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:71
+#: src/paths/instance/orders/create/CreatePage.tsx:258
+#: src/paths/instance/products/list/Table.tsx:48
+#, c-format
+msgid "Products"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:77
+#: src/paths/instance/transfers/list/Table.tsx:65
+#, c-format
+msgid "Transfers"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:87
+#, c-format
+msgid "Connection"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:112 src/paths/admin/list/Table.tsx:57
+#, c-format
+msgid "Instances"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:116
+#, c-format
+msgid "New"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:122
+#, c-format
+msgid "List"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:129
+#, c-format
+msgid "Log out"
+msgstr ""
+
+#: src/components/modal/index.tsx:74
+#, c-format
+msgid "Clear"
+msgstr ""
+
+#: src/components/modal/index.tsx:110 src/components/modal/index.tsx:111
+#, c-format
+msgid "should be the same"
+msgstr ""
+
+#: src/components/modal/index.tsx:111
+#, c-format
+msgid "cannot be the same as before"
+msgstr ""
+
+#: src/components/modal/index.tsx:114
+#, c-format
+msgid ""
+"You are updating the authorization token from instance %1$s with id %2$s"
+msgstr ""
+
+#: src/components/modal/index.tsx:124
+#, c-format
+msgid "Old token"
+msgstr ""
+
+#: src/components/modal/index.tsx:125
+#, c-format
+msgid "New token"
+msgstr ""
+
+#: src/components/modal/index.tsx:127
+#, c-format
+msgid "Clearing the auth token will mean public access to the instance"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:96
+#: src/paths/admin/create/CreatePage.tsx:85 src/paths/admin/list/Table.tsx:109
+#: src/paths/instance/transfers/list/Table.tsx:122
+#, c-format
+msgid "ID"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:98
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:121
+#: src/paths/instance/products/list/Table.tsx:85
+#, c-format
+msgid "Image"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:100
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:123
+#, c-format
+msgid "Unit"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:101
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:124
+#: src/paths/instance/products/list/Table.tsx:162
+#: src/paths/instance/products/list/Table.tsx:214
+#, c-format
+msgid "Price"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:103
+#: src/paths/instance/products/list/Table.tsx:90
+#, c-format
+msgid "Stock"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:105
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:128
+#: src/paths/instance/products/list/Table.tsx:88
+#, c-format
+msgid "Taxes"
+msgstr ""
+
+#: src/index.tsx:75
+#, c-format
+msgid "Server not found"
+msgstr ""
+
+#: src/index.tsx:85
+#, c-format
+msgid "Couldn't access the server"
+msgstr ""
+
+#: src/index.tsx:87 src/index.tsx:99
+#, c-format
+msgid "Got message %1$s from %2$s"
+msgstr ""
+
+#: src/index.tsx:97
+#, c-format
+msgid "Unexpected Error"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:108
+#, c-format
+msgid "Auth token"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:91
+#: src/paths/instance/details/DetailPage.tsx:77
+#: src/paths/instance/update/UpdatePage.tsx:110
+#, c-format
+msgid "Account address"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:93
+#: src/paths/instance/update/UpdatePage.tsx:112
+#, c-format
+msgid "Default max deposit fee"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:95
+#: src/paths/instance/update/UpdatePage.tsx:114
+#, c-format
+msgid "Default max wire fee"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:97
+#: src/paths/instance/update/UpdatePage.tsx:116
+#, c-format
+msgid "Default wire fee amortization"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:103
+#: src/paths/instance/update/UpdatePage.tsx:122
+#, c-format
+msgid "Jurisdiction"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:107
+#: src/paths/instance/update/UpdatePage.tsx:126
+#, c-format
+msgid "Default pay delay"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:109
+#: src/paths/instance/update/UpdatePage.tsx:128
+#, c-format
+msgid "Default wire transfer delay"
+msgstr ""
+
+#: src/paths/admin/create/index.tsx:58
+#, c-format
+msgid "could not create instance"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:63 src/paths/admin/list/Table.tsx:131
+#: src/paths/instance/transfers/list/Table.tsx:71
+#, c-format
+msgid "Delete"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:128
+#, c-format
+msgid "Edit"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:149
+#: src/paths/instance/products/list/Table.tsx:245
+#, c-format
+msgid "There is no instances yet, add more pressing the + sign"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:237
+#, c-format
+msgid "Inventory products"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:286
+#, c-format
+msgid "Total price"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:287
+#, c-format
+msgid "Total tax"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:289
+#: src/paths/instance/orders/create/CreatePage.tsx:297
+#, c-format
+msgid "Order price"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:295
+#, c-format
+msgid "Net"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:300
+#: src/paths/instance/orders/details/DetailPage.tsx:144
+#: src/paths/instance/orders/details/DetailPage.tsx:295
+#: src/paths/instance/orders/list/Table.tsx:117
+#, c-format
+msgid "Summary"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:302
+#, c-format
+msgid "Payments options"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:303
+#, c-format
+msgid "Auto refund deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:304
+#, c-format
+msgid "Refund deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:305
+#, c-format
+msgid "Pay deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:307
+#, c-format
+msgid "Delivery date"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:308
+#, c-format
+msgid "Location"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:312
+#, c-format
+msgid "Max fee"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:313
+#, c-format
+msgid "Max wire fee"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:314
+#, c-format
+msgid "Wire fee amortization"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:315
+#, c-format
+msgid "Fullfilment url"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:318
+#, c-format
+msgid "Extra information"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:44
+#, c-format
+msgid "select a product first"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:51
+#, c-format
+msgid "should be greater than 0"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:58
+#, c-format
+msgid ""
+"cannot be greater than current stock and quantity previously added. max: %1$s"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:64
+#, c-format
+msgid "cannot be greater than current stock %1$s"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:76
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:126
+#, c-format
+msgid "Quantity"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:92
+#: src/paths/instance/orders/details/DetailPage.tsx:235
+#: src/paths/instance/orders/details/DetailPage.tsx:333
+#, c-format
+msgid "Order"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:93
+#, c-format
+msgid "claimed"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:110
+#: src/paths/instance/orders/details/DetailPage.tsx:261
+#: src/paths/instance/orders/list/Table.tsx:136
+#, c-format
+msgid "copy url"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:126
+#: src/paths/instance/orders/details/DetailPage.tsx:349
+#, c-format
+msgid "pay at"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:127
+#: src/paths/instance/orders/details/DetailPage.tsx:350
+#, c-format
+msgid "created at"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:138
+#: src/paths/instance/orders/details/DetailPage.tsx:289
+#, c-format
+msgid "Timeline"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:142
+#: src/paths/instance/orders/details/DetailPage.tsx:293
+#, c-format
+msgid "Payment details"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:146
+#: src/paths/instance/orders/details/DetailPage.tsx:299
+#: src/paths/instance/orders/details/DetailPage.tsx:363
+#, c-format
+msgid "Order status"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:156
+#: src/paths/instance/orders/details/DetailPage.tsx:308
+#, c-format
+msgid "Product list"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:236
+#, c-format
+msgid "paid"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:238
+#, c-format
+msgid "wired"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:241
+#, c-format
+msgid "refunded"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:258
+#, c-format
+msgid "refund"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:297
+#, c-format
+msgid "Refunded amount"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:298
+#, c-format
+msgid "Deposit total"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:336
+#, c-format
+msgid "unpaid"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:364
+#, c-format
+msgid "Order status URL"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:365
+#, c-format
+msgid "Pay URI"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:383
+#, c-format
+msgid ""
+"Unknown order status. This is an error, please contact the administrator."
+msgstr ""
+
+#: src/paths/instance/orders/details/index.tsx:56
+#: src/paths/instance/orders/list/index.tsx:147
+#, c-format
+msgid "refund created successfully"
+msgstr ""
+
+#: src/paths/instance/orders/details/index.tsx:59
+#: src/paths/instance/orders/list/index.tsx:150
+#, c-format
+msgid "could not create the refund"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:111
+#, c-format
+msgid "load newer orders"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:115
+#, c-format
+msgid "Date"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:131
+#: src/paths/instance/orders/list/Table.tsx:223
+#, c-format
+msgid "Refund"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:145
+#, c-format
+msgid "load older orders"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:154
+#, c-format
+msgid "No orders has been found"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:202
+#, c-format
+msgid "date"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:203
+#, c-format
+msgid "amount"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:204
+#, c-format
+msgid "reason"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:224
+#, c-format
+msgid "Max refundable:"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "Reason"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "duplicated"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "requested by the customer"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "other"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:91
+#, c-format
+msgid "go to order id"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:107
+#, c-format
+msgid "Paid"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:108
+#, c-format
+msgid "Refunded"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:109
+#, c-format
+msgid "Not wired"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:110
+#, c-format
+msgid "All"
+msgstr ""
+
+#: src/paths/instance/products/create/index.tsx:48
+#: src/paths/instance/products/update/index.tsx:64
+#, c-format
+msgid "could not create product"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:87
+#, c-format
+msgid "Sell"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:89
+#, c-format
+msgid "Profit"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:91
+#, c-format
+msgid "Sold"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:59
+#, c-format
+msgid "product updated successfully"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:62
+#, c-format
+msgid "could not update the product"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:70
+#, c-format
+msgid "product delete successfully"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:73
+#, c-format
+msgid "could not delete the product"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:59
+#, c-format
+msgid "Tips"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:111
+#, c-format
+msgid "Committed amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:112
+#, c-format
+msgid "Exchange initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:113
+#, c-format
+msgid "Merchant initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:148
+#, c-format
+msgid "There is no tips yet, add more pressing the + sign"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:50
+#: src/paths/instance/transfers/create/CreatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:56
+#, c-format
+msgid "cannot be empty"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:51
+#, c-format
+msgid "check the id, doest look valid"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:52
+#, c-format
+msgid "should have 52 characters, current %1$s"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:57
+#, c-format
+msgid "URL doesn't have the right format"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:74
+#, c-format
+msgid "Transfer ID"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:76
+#, c-format
+msgid "Account Address"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:82
+#: src/paths/instance/transfers/list/Table.tsx:125
+#, c-format
+msgid "Exchange URL"
+msgstr ""
+
+#: src/paths/instance/transfers/create/index.tsx:49
+#, c-format
+msgid "could not inform transfer"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:118
+#, c-format
+msgid "load newer transfers"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:123
+#, c-format
+msgid "Credit"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:126
+#, c-format
+msgid "Confirmed"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:127
+#: src/paths/instance/transfers/list/index.tsx:60
+#, c-format
+msgid "Verified"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:128
+#, c-format
+msgid "Executed at"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "yes"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "no"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "unknown"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:145
+#, c-format
+msgid "load older transfers"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:154
+#, c-format
+msgid "There is no transfer yet, add more pressing the + sign"
+msgstr ""
diff --git a/packages/merchant-backend-ui/src/i18n/en.po 
b/packages/merchant-backend-ui/src/i18n/en.po
new file mode 100644
index 000000000..6b35bd0ce
--- /dev/null
+++ b/packages/merchant-backend-ui/src/i18n/en.po
@@ -0,0 +1,1057 @@
+# This file is part of TALER
+# (C) 2016 GNUnet e.V.
+#
+# TALER is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3, or (at your option) any later version.
+#
+# TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Taler Wallet\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2016-11-23 00:00+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: src/ApplicationReadyRoutes.tsx:50 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:299
+#, c-format
+msgid "Access denied"
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:51 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:300
+#, c-format
+msgid "Check your token is valid"
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:72
+#, c-format
+msgid "Couldn't access the server."
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:73
+#, c-format
+msgid "Could not infer instance id from url %1$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:109
+#, c-format
+msgid "HTTP status #%1$s: Server reported a problem"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:110
+#, c-format
+msgid "Got message: \"%1$s\" from: %2$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:127
+#, c-format
+msgid "No default instance"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:128
+#, c-format
+msgid ""
+"in order to use merchant backoffice, you should create the default instance"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:288
+#, c-format
+msgid "Server reported a problem: HTTP status #%1$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:289
+#, c-format
+msgid "Got message: %1$s from: %2$s"
+msgstr ""
+
+#: src/components/exception/login.tsx:46
+#, c-format
+msgid "Login required"
+msgstr ""
+
+#: src/components/exception/login.tsx:49
+#, c-format
+msgid ""
+"Please enter your auth token. Token should have \"secret-token:\" and start "
+"with Bearer or ApiKey"
+msgstr ""
+
+#: src/components/exception/login.tsx:86 src/components/modal/index.tsx:53
+#: src/components/modal/index.tsx:75 src/paths/admin/create/CreatePage.tsx:115
+#: src/paths/instance/orders/create/CreatePage.tsx:325
+#: src/paths/instance/products/create/CreatePage.tsx:51
+#: src/paths/instance/products/list/Table.tsx:174
+#: src/paths/instance/products/list/Table.tsx:228
+#: src/paths/instance/products/update/UpdatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:134
+#, c-format
+msgid "Confirm"
+msgstr ""
+
+#: src/components/form/InputArray.tsx:72
+#, c-format
+msgid "The value %1$s is invalid for a payment url"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:67
+#: src/paths/instance/orders/list/index.tsx:123
+#, c-format
+msgid "pick a date"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:81
+#, c-format
+msgid "clear"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:83
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "never"
+msgstr ""
+
+#: src/components/form/InputImage.tsx:80
+#, c-format
+msgid "Image should be smaller than 1 MB"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:28
+#, c-format
+msgid "Country"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:30
+#: src/paths/admin/create/CreatePage.tsx:99
+#: src/paths/instance/transfers/list/Table.tsx:124
+#: src/paths/instance/update/UpdatePage.tsx:118
+#, c-format
+msgid "Address"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:34
+#, c-format
+msgid "Building number"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:35
+#, c-format
+msgid "Building name"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:36
+#, c-format
+msgid "Street"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:37
+#, c-format
+msgid "Post code"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:38
+#, c-format
+msgid "Town location"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:39
+#, c-format
+msgid "Town"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:40
+#, c-format
+msgid "District"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:41
+#, c-format
+msgid "Country subdivision"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:59
+#, c-format
+msgid "Product id"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:60
+#: src/components/product/ProductForm.tsx:99
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:122
+#: src/paths/instance/orders/list/Table.tsx:227
+#: src/paths/instance/products/list/Table.tsx:86
+#, c-format
+msgid "Description"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:73
+#: src/components/form/InputTaxes.tsx:81
+#: src/paths/admin/create/CreatePage.tsx:87 src/paths/admin/list/Table.tsx:110
+#: src/paths/instance/details/DetailPage.tsx:76
+#: src/paths/instance/update/UpdatePage.tsx:106
+#, c-format
+msgid "Name"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:102
+#, c-format
+msgid "loading..."
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:108
+#, c-format
+msgid "no products found"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:116
+#, c-format
+msgid "no results"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:33
+#, c-format
+msgid "Deleting"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:34
+#, c-format
+msgid "Changing"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:60
+#, c-format
+msgid "Manage token"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:83
+#, c-format
+msgid "Update"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:100
+#: src/paths/instance/orders/create/CreatePage.tsx:252
+#: src/paths/instance/orders/create/CreatePage.tsx:273
+#, c-format
+msgid "Remove"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:106 src/components/modal/index.tsx:52
+#: src/components/modal/index.tsx:73 src/paths/admin/create/CreatePage.tsx:114
+#: src/paths/instance/orders/create/CreatePage.tsx:324
+#: src/paths/instance/products/create/CreatePage.tsx:50
+#: src/paths/instance/products/list/Table.tsx:166
+#: src/paths/instance/products/list/Table.tsx:218
+#: src/paths/instance/products/update/UpdatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:88
+#: src/paths/instance/update/UpdatePage.tsx:133
+#, c-format
+msgid "Cancel"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:91
+#, c-format
+msgid "Manage stock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:93
+#, c-format
+msgid "Infinite"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:105
+#, c-format
+msgid "lost cannot be greater that current + incoming (max %1$s)"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:111
+#, c-format
+msgid "current stock will change from %1$s to %2$s"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:112
+#, c-format
+msgid "current stock will stay at %1$s"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:129
+#: src/paths/instance/products/list/Table.tsx:204
+#, c-format
+msgid "Incoming"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:130
+#: src/paths/instance/products/list/Table.tsx:205
+#, c-format
+msgid "Lost"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:142
+#, c-format
+msgid "Current"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:145
+#, c-format
+msgid "without stock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:150
+#, c-format
+msgid "Next restock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:152
+#, c-format
+msgid "Delivery address"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:73
+#, c-format
+msgid "this product has no taxes"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:77
+#: src/paths/instance/orders/details/DetailPage.tsx:145
+#: src/paths/instance/orders/details/DetailPage.tsx:296
+#: src/paths/instance/orders/list/Table.tsx:116
+#: src/paths/instance/transfers/create/CreatePage.tsx:84
+#, c-format
+msgid "Amount"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:78
+#, c-format
+msgid "currency and value separated with colon"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:84
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:78
+#, c-format
+msgid "Add"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:53
+#, c-format
+msgid "Instance"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:59
+#, c-format
+msgid "Settings"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:65
+#: src/paths/instance/orders/list/Table.tsx:60
+#, c-format
+msgid "Orders"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:71
+#: src/paths/instance/orders/create/CreatePage.tsx:258
+#: src/paths/instance/products/list/Table.tsx:48
+#, c-format
+msgid "Products"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:77
+#: src/paths/instance/transfers/list/Table.tsx:65
+#, c-format
+msgid "Transfers"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:87
+#, c-format
+msgid "Connection"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:112 src/paths/admin/list/Table.tsx:57
+#, c-format
+msgid "Instances"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:116
+#, c-format
+msgid "New"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:122
+#, c-format
+msgid "List"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:129
+#, c-format
+msgid "Log out"
+msgstr ""
+
+#: src/components/modal/index.tsx:74
+#, c-format
+msgid "Clear"
+msgstr ""
+
+#: src/components/modal/index.tsx:110 src/components/modal/index.tsx:111
+#, c-format
+msgid "should be the same"
+msgstr ""
+
+#: src/components/modal/index.tsx:111
+#, c-format
+msgid "cannot be the same as before"
+msgstr ""
+
+#: src/components/modal/index.tsx:114
+#, c-format
+msgid ""
+"You are updating the authorization token from instance %1$s with id %2$s"
+msgstr ""
+
+#: src/components/modal/index.tsx:124
+#, c-format
+msgid "Old token"
+msgstr ""
+
+#: src/components/modal/index.tsx:125
+#, c-format
+msgid "New token"
+msgstr ""
+
+#: src/components/modal/index.tsx:127
+#, c-format
+msgid "Clearing the auth token will mean public access to the instance"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:96
+#: src/paths/admin/create/CreatePage.tsx:85 src/paths/admin/list/Table.tsx:109
+#: src/paths/instance/transfers/list/Table.tsx:122
+#, c-format
+msgid "ID"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:98
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:121
+#: src/paths/instance/products/list/Table.tsx:85
+#, c-format
+msgid "Image"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:100
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:123
+#, c-format
+msgid "Unit"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:101
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:124
+#: src/paths/instance/products/list/Table.tsx:162
+#: src/paths/instance/products/list/Table.tsx:214
+#, c-format
+msgid "Price"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:103
+#: src/paths/instance/products/list/Table.tsx:90
+#, c-format
+msgid "Stock"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:105
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:128
+#: src/paths/instance/products/list/Table.tsx:88
+#, c-format
+msgid "Taxes"
+msgstr ""
+
+#: src/index.tsx:75
+#, c-format
+msgid "Server not found"
+msgstr ""
+
+#: src/index.tsx:85
+#, c-format
+msgid "Couldn't access the server"
+msgstr ""
+
+#: src/index.tsx:87 src/index.tsx:99
+#, c-format
+msgid "Got message %1$s from %2$s"
+msgstr ""
+
+#: src/index.tsx:97
+#, c-format
+msgid "Unexpected Error"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:108
+#, c-format
+msgid "Auth token"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:91
+#: src/paths/instance/details/DetailPage.tsx:77
+#: src/paths/instance/update/UpdatePage.tsx:110
+#, c-format
+msgid "Account address"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:93
+#: src/paths/instance/update/UpdatePage.tsx:112
+#, c-format
+msgid "Default max deposit fee"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:95
+#: src/paths/instance/update/UpdatePage.tsx:114
+#, c-format
+msgid "Default max wire fee"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:97
+#: src/paths/instance/update/UpdatePage.tsx:116
+#, c-format
+msgid "Default wire fee amortization"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:103
+#: src/paths/instance/update/UpdatePage.tsx:122
+#, c-format
+msgid "Jurisdiction"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:107
+#: src/paths/instance/update/UpdatePage.tsx:126
+#, c-format
+msgid "Default pay delay"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:109
+#: src/paths/instance/update/UpdatePage.tsx:128
+#, c-format
+msgid "Default wire transfer delay"
+msgstr ""
+
+#: src/paths/admin/create/index.tsx:58
+#, c-format
+msgid "could not create instance"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:63 src/paths/admin/list/Table.tsx:131
+#: src/paths/instance/transfers/list/Table.tsx:71
+#, c-format
+msgid "Delete"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:128
+#, c-format
+msgid "Edit"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:149
+#: src/paths/instance/products/list/Table.tsx:245
+#, c-format
+msgid "There is no instances yet, add more pressing the + sign"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:237
+#, c-format
+msgid "Inventory products"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:286
+#, c-format
+msgid "Total price"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:287
+#, c-format
+msgid "Total tax"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:289
+#: src/paths/instance/orders/create/CreatePage.tsx:297
+#, c-format
+msgid "Order price"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:295
+#, c-format
+msgid "Net"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:300
+#: src/paths/instance/orders/details/DetailPage.tsx:144
+#: src/paths/instance/orders/details/DetailPage.tsx:295
+#: src/paths/instance/orders/list/Table.tsx:117
+#, c-format
+msgid "Summary"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:302
+#, c-format
+msgid "Payments options"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:303
+#, c-format
+msgid "Auto refund deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:304
+#, c-format
+msgid "Refund deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:305
+#, c-format
+msgid "Pay deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:307
+#, c-format
+msgid "Delivery date"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:308
+#, c-format
+msgid "Location"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:312
+#, c-format
+msgid "Max fee"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:313
+#, c-format
+msgid "Max wire fee"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:314
+#, c-format
+msgid "Wire fee amortization"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:315
+#, c-format
+msgid "Fullfilment url"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:318
+#, c-format
+msgid "Extra information"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:44
+#, c-format
+msgid "select a product first"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:51
+#, c-format
+msgid "should be greater than 0"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:58
+#, c-format
+msgid ""
+"cannot be greater than current stock and quantity previously added. max: %1$s"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:64
+#, c-format
+msgid "cannot be greater than current stock %1$s"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:76
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:126
+#, c-format
+msgid "Quantity"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:92
+#: src/paths/instance/orders/details/DetailPage.tsx:235
+#: src/paths/instance/orders/details/DetailPage.tsx:333
+#, c-format
+msgid "Order"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:93
+#, c-format
+msgid "claimed"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:110
+#: src/paths/instance/orders/details/DetailPage.tsx:261
+#: src/paths/instance/orders/list/Table.tsx:136
+#, c-format
+msgid "copy url"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:126
+#: src/paths/instance/orders/details/DetailPage.tsx:349
+#, c-format
+msgid "pay at"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:127
+#: src/paths/instance/orders/details/DetailPage.tsx:350
+#, c-format
+msgid "created at"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:138
+#: src/paths/instance/orders/details/DetailPage.tsx:289
+#, c-format
+msgid "Timeline"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:142
+#: src/paths/instance/orders/details/DetailPage.tsx:293
+#, c-format
+msgid "Payment details"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:146
+#: src/paths/instance/orders/details/DetailPage.tsx:299
+#: src/paths/instance/orders/details/DetailPage.tsx:363
+#, c-format
+msgid "Order status"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:156
+#: src/paths/instance/orders/details/DetailPage.tsx:308
+#, c-format
+msgid "Product list"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:236
+#, c-format
+msgid "paid"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:238
+#, c-format
+msgid "wired"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:241
+#, c-format
+msgid "refunded"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:258
+#, c-format
+msgid "refund"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:297
+#, c-format
+msgid "Refunded amount"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:298
+#, c-format
+msgid "Deposit total"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:336
+#, c-format
+msgid "unpaid"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:364
+#, c-format
+msgid "Order status URL"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:365
+#, c-format
+msgid "Pay URI"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:383
+#, c-format
+msgid ""
+"Unknown order status. This is an error, please contact the administrator."
+msgstr ""
+
+#: src/paths/instance/orders/details/index.tsx:56
+#: src/paths/instance/orders/list/index.tsx:147
+#, c-format
+msgid "refund created successfully"
+msgstr ""
+
+#: src/paths/instance/orders/details/index.tsx:59
+#: src/paths/instance/orders/list/index.tsx:150
+#, c-format
+msgid "could not create the refund"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:111
+#, c-format
+msgid "load newer orders"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:115
+#, c-format
+msgid "Date"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:131
+#: src/paths/instance/orders/list/Table.tsx:223
+#, c-format
+msgid "Refund"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:145
+#, c-format
+msgid "load older orders"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:154
+#, c-format
+msgid "No orders has been found"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:202
+#, c-format
+msgid "date"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:203
+#, c-format
+msgid "amount"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:204
+#, c-format
+msgid "reason"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:224
+#, c-format
+msgid "Max refundable:"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "Reason"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "duplicated"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "requested by the customer"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "other"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:91
+#, c-format
+msgid "go to order id"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:107
+#, c-format
+msgid "Paid"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:108
+#, c-format
+msgid "Refunded"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:109
+#, c-format
+msgid "Not wired"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:110
+#, c-format
+msgid "All"
+msgstr ""
+
+#: src/paths/instance/products/create/index.tsx:48
+#: src/paths/instance/products/update/index.tsx:64
+#, c-format
+msgid "could not create product"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:87
+#, c-format
+msgid "Sell"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:89
+#, c-format
+msgid "Profit"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:91
+#, c-format
+msgid "Sold"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:59
+#, c-format
+msgid "product updated successfully"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:62
+#, c-format
+msgid "could not update the product"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:70
+#, c-format
+msgid "product delete successfully"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:73
+#, c-format
+msgid "could not delete the product"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:59
+#, c-format
+msgid "Tips"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:111
+#, c-format
+msgid "Committed amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:112
+#, c-format
+msgid "Exchange initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:113
+#, c-format
+msgid "Merchant initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:148
+#, c-format
+msgid "There is no tips yet, add more pressing the + sign"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:50
+#: src/paths/instance/transfers/create/CreatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:56
+#, c-format
+msgid "cannot be empty"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:51
+#, c-format
+msgid "check the id, doest look valid"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:52
+#, c-format
+msgid "should have 52 characters, current %1$s"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:57
+#, c-format
+msgid "URL doesn't have the right format"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:74
+#, c-format
+msgid "Transfer ID"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:76
+#, c-format
+msgid "Account Address"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:82
+#: src/paths/instance/transfers/list/Table.tsx:125
+#, c-format
+msgid "Exchange URL"
+msgstr ""
+
+#: src/paths/instance/transfers/create/index.tsx:49
+#, c-format
+msgid "could not inform transfer"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:118
+#, c-format
+msgid "load newer transfers"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:123
+#, c-format
+msgid "Credit"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:126
+#, c-format
+msgid "Confirmed"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:127
+#: src/paths/instance/transfers/list/index.tsx:60
+#, c-format
+msgid "Verified"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:128
+#, c-format
+msgid "Executed at"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "yes"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "no"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "unknown"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:145
+#, c-format
+msgid "load older transfers"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:154
+#, c-format
+msgid "There is no transfer yet, add more pressing the + sign"
+msgstr ""
diff --git a/packages/merchant-backend-ui/src/i18n/es.po 
b/packages/merchant-backend-ui/src/i18n/es.po
new file mode 100644
index 000000000..9075d4656
--- /dev/null
+++ b/packages/merchant-backend-ui/src/i18n/es.po
@@ -0,0 +1,1065 @@
+# This file is part of TALER
+# (C) 2016 GNUnet e.V.
+#
+# TALER is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3, or (at your option) any later version.
+#
+# TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Taler Wallet\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2016-11-23 00:00+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: src/ApplicationReadyRoutes.tsx:50 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:299
+#, c-format
+msgid "Access denied"
+msgstr "Acceso denegado"
+
+#: src/ApplicationReadyRoutes.tsx:51 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:300
+#, c-format
+msgid "Check your token is valid"
+msgstr "Verifica que el token sea valido"
+
+#: src/ApplicationReadyRoutes.tsx:72
+#, c-format
+msgid "Couldn't access the server."
+msgstr "No se pudo acceder al servidor"
+
+#: src/ApplicationReadyRoutes.tsx:73
+#, c-format
+msgid "Could not infer instance id from url %1$s"
+msgstr "No se pudo inferir el id de la instancia con la url %1$s"
+
+#: src/InstanceRoutes.tsx:109
+#, c-format
+msgid "HTTP status #%1$s: Server reported a problem"
+msgstr "HTTP status #%1$s: Servidor reporto un problema"
+
+#: src/InstanceRoutes.tsx:110
+#, fuzzy, c-format
+msgid "Got message: \"%1$s\" from: %2$s"
+msgstr "Recivimos el mensaje %1$s desde %2$s"
+
+#: src/InstanceRoutes.tsx:127
+#, c-format
+msgid "No default instance"
+msgstr "Sin instancia default"
+
+#: src/InstanceRoutes.tsx:128
+#, c-format
+msgid ""
+"in order to use merchant backoffice, you should create the default instance"
+msgstr "para usar el merchant backoffice, debería crear la instancia default"
+
+#: src/InstanceRoutes.tsx:288
+#, c-format
+msgid "Server reported a problem: HTTP status #%1$s"
+msgstr "Servidir reporto un problema: HTTP status #%1$s"
+
+#: src/InstanceRoutes.tsx:289
+#, fuzzy, c-format
+msgid "Got message: %1$s from: %2$s"
+msgstr "Recivimos el mensaje %1$s desde %2$s"
+
+#: src/components/exception/login.tsx:46
+#, c-format
+msgid "Login required"
+msgstr "Login necesario"
+
+#: src/components/exception/login.tsx:49
+#, c-format
+msgid ""
+"Please enter your auth token. Token should have \"secret-token:\" and start "
+"with Bearer or ApiKey"
+msgstr ""
+"Por favor ingrese su token de autorización. El token debe tener \"secret-"
+"token\" y comenzar con Bearer o ApiKey"
+
+#: src/components/exception/login.tsx:86 src/components/modal/index.tsx:53
+#: src/components/modal/index.tsx:75 src/paths/admin/create/CreatePage.tsx:115
+#: src/paths/instance/orders/create/CreatePage.tsx:325
+#: src/paths/instance/products/create/CreatePage.tsx:51
+#: src/paths/instance/products/list/Table.tsx:174
+#: src/paths/instance/products/list/Table.tsx:228
+#: src/paths/instance/products/update/UpdatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:134
+#, c-format
+msgid "Confirm"
+msgstr "Confirmar"
+
+#: src/components/form/InputArray.tsx:72
+#, c-format
+msgid "The value %1$s is invalid for a payment url"
+msgstr "El valor %1$s es invalido para una URL de pago"
+
+#: src/components/form/InputDate.tsx:67
+#: src/paths/instance/orders/list/index.tsx:123
+#, c-format
+msgid "pick a date"
+msgstr "elegir una fecha"
+
+#: src/components/form/InputDate.tsx:81
+#, fuzzy, c-format
+msgid "clear"
+msgstr "Limpiar"
+
+#: src/components/form/InputDate.tsx:83
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "never"
+msgstr "nunca"
+
+#: src/components/form/InputImage.tsx:80
+#, c-format
+msgid "Image should be smaller than 1 MB"
+msgstr "La imagen debe ser mas chica que 1 MB"
+
+#: src/components/form/InputLocation.tsx:28
+#, c-format
+msgid "Country"
+msgstr "País"
+
+#: src/components/form/InputLocation.tsx:30
+#: src/paths/admin/create/CreatePage.tsx:99
+#: src/paths/instance/transfers/list/Table.tsx:124
+#: src/paths/instance/update/UpdatePage.tsx:118
+#, c-format
+msgid "Address"
+msgstr "Dirección"
+
+#: src/components/form/InputLocation.tsx:34
+#, c-format
+msgid "Building number"
+msgstr "Número de edificio"
+
+#: src/components/form/InputLocation.tsx:35
+#, c-format
+msgid "Building name"
+msgstr "Nombre de edificio"
+
+#: src/components/form/InputLocation.tsx:36
+#, c-format
+msgid "Street"
+msgstr "Calle"
+
+#: src/components/form/InputLocation.tsx:37
+#, c-format
+msgid "Post code"
+msgstr "Código postal"
+
+#: src/components/form/InputLocation.tsx:38
+#, fuzzy, c-format
+msgid "Town location"
+msgstr "Ubicación de ciudad"
+
+#: src/components/form/InputLocation.tsx:39
+#, c-format
+msgid "Town"
+msgstr "Ciudad"
+
+#: src/components/form/InputLocation.tsx:40
+#, c-format
+msgid "District"
+msgstr "Distrito"
+
+#: src/components/form/InputLocation.tsx:41
+#, c-format
+msgid "Country subdivision"
+msgstr "Provincia"
+
+#: src/components/form/InputSearchProduct.tsx:59
+#, fuzzy, c-format
+msgid "Product id"
+msgstr "Id de producto"
+
+#: src/components/form/InputSearchProduct.tsx:60
+#: src/components/product/ProductForm.tsx:99
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:122
+#: src/paths/instance/orders/list/Table.tsx:227
+#: src/paths/instance/products/list/Table.tsx:86
+#, c-format
+msgid "Description"
+msgstr "Descripcion"
+
+#: src/components/form/InputSearchProduct.tsx:73
+#: src/components/form/InputTaxes.tsx:81
+#: src/paths/admin/create/CreatePage.tsx:87 src/paths/admin/list/Table.tsx:110
+#: src/paths/instance/details/DetailPage.tsx:76
+#: src/paths/instance/update/UpdatePage.tsx:106
+#, c-format
+msgid "Name"
+msgstr "Nombre"
+
+#: src/components/form/InputSearchProduct.tsx:102
+#, c-format
+msgid "loading..."
+msgstr "Cargando..."
+
+#: src/components/form/InputSearchProduct.tsx:108
+#, c-format
+msgid "no products found"
+msgstr "No se encontraron productos"
+
+#: src/components/form/InputSearchProduct.tsx:116
+#, c-format
+msgid "no results"
+msgstr "Sin resultados"
+
+#: src/components/form/InputSecured.tsx:33
+#, c-format
+msgid "Deleting"
+msgstr "Borrando"
+
+#: src/components/form/InputSecured.tsx:34
+#, c-format
+msgid "Changing"
+msgstr "Cambiando"
+
+#: src/components/form/InputSecured.tsx:60
+#, c-format
+msgid "Manage token"
+msgstr "Administrar token"
+
+#: src/components/form/InputSecured.tsx:83
+#, c-format
+msgid "Update"
+msgstr "Actualizar"
+
+#: src/components/form/InputSecured.tsx:100
+#: src/paths/instance/orders/create/CreatePage.tsx:252
+#: src/paths/instance/orders/create/CreatePage.tsx:273
+#, c-format
+msgid "Remove"
+msgstr "Eliminar"
+
+#: src/components/form/InputSecured.tsx:106 src/components/modal/index.tsx:52
+#: src/components/modal/index.tsx:73 src/paths/admin/create/CreatePage.tsx:114
+#: src/paths/instance/orders/create/CreatePage.tsx:324
+#: src/paths/instance/products/create/CreatePage.tsx:50
+#: src/paths/instance/products/list/Table.tsx:166
+#: src/paths/instance/products/list/Table.tsx:218
+#: src/paths/instance/products/update/UpdatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:88
+#: src/paths/instance/update/UpdatePage.tsx:133
+#, c-format
+msgid "Cancel"
+msgstr "Cancelar"
+
+#: src/components/form/InputStock.tsx:91
+#, c-format
+msgid "Manage stock"
+msgstr "Administrar stock"
+
+#: src/components/form/InputStock.tsx:93
+#, c-format
+msgid "Infinite"
+msgstr "Inifinito"
+
+#: src/components/form/InputStock.tsx:105
+#, fuzzy, c-format
+msgid "lost cannot be greater that current + incoming (max %1$s)"
+msgstr "no puede ser mayor al stock actual %1$s"
+
+#: src/components/form/InputStock.tsx:111
+#, c-format
+msgid "current stock will change from %1$s to %2$s"
+msgstr "stock actual cambiará desde %1$s a %2$s"
+
+#: src/components/form/InputStock.tsx:112
+#, c-format
+msgid "current stock will stay at %1$s"
+msgstr "stock actual seguirá en %1$s"
+
+#: src/components/form/InputStock.tsx:129
+#: src/paths/instance/products/list/Table.tsx:204
+#, c-format
+msgid "Incoming"
+msgstr "Ingresando"
+
+#: src/components/form/InputStock.tsx:130
+#: src/paths/instance/products/list/Table.tsx:205
+#, c-format
+msgid "Lost"
+msgstr "Perdido"
+
+#: src/components/form/InputStock.tsx:142
+#, c-format
+msgid "Current"
+msgstr "Actual"
+
+#: src/components/form/InputStock.tsx:145
+#, c-format
+msgid "without stock"
+msgstr "sin stock"
+
+#: src/components/form/InputStock.tsx:150
+#, c-format
+msgid "Next restock"
+msgstr "Próximo reabastecimiento"
+
+#: src/components/form/InputStock.tsx:152
+#, c-format
+msgid "Delivery address"
+msgstr "Dirección de entrega"
+
+#: src/components/form/InputTaxes.tsx:73
+#, c-format
+msgid "this product has no taxes"
+msgstr "este producto no tiene impuestos"
+
+#: src/components/form/InputTaxes.tsx:77
+#: src/paths/instance/orders/details/DetailPage.tsx:145
+#: src/paths/instance/orders/details/DetailPage.tsx:296
+#: src/paths/instance/orders/list/Table.tsx:116
+#: src/paths/instance/transfers/create/CreatePage.tsx:84
+#, c-format
+msgid "Amount"
+msgstr "Monto"
+
+#: src/components/form/InputTaxes.tsx:78
+#, c-format
+msgid "currency and value separated with colon"
+msgstr "Moneda y valor separado por dos puntos"
+
+#: src/components/form/InputTaxes.tsx:84
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:78
+#, c-format
+msgid "Add"
+msgstr "Agregar"
+
+#: src/components/menu/SideBar.tsx:53
+#, c-format
+msgid "Instance"
+msgstr "Instancia"
+
+#: src/components/menu/SideBar.tsx:59
+#, c-format
+msgid "Settings"
+msgstr "Configuración"
+
+#: src/components/menu/SideBar.tsx:65
+#: src/paths/instance/orders/list/Table.tsx:60
+#, fuzzy, c-format
+msgid "Orders"
+msgstr "Ordenes"
+
+#: src/components/menu/SideBar.tsx:71
+#: src/paths/instance/orders/create/CreatePage.tsx:258
+#: src/paths/instance/products/list/Table.tsx:48
+#, c-format
+msgid "Products"
+msgstr "Productos"
+
+#: src/components/menu/SideBar.tsx:77
+#: src/paths/instance/transfers/list/Table.tsx:65
+#, c-format
+msgid "Transfers"
+msgstr "Transferencias"
+
+#: src/components/menu/SideBar.tsx:87
+#, fuzzy, c-format
+msgid "Connection"
+msgstr "Conexión"
+
+#: src/components/menu/SideBar.tsx:112 src/paths/admin/list/Table.tsx:57
+#, c-format
+msgid "Instances"
+msgstr "Instancias"
+
+#: src/components/menu/SideBar.tsx:116
+#, fuzzy, c-format
+msgid "New"
+msgstr "Nuevo"
+
+#: src/components/menu/SideBar.tsx:122
+#, c-format
+msgid "List"
+msgstr "Lista"
+
+#: src/components/menu/SideBar.tsx:129
+#, c-format
+msgid "Log out"
+msgstr "Salir"
+
+#: src/components/modal/index.tsx:74
+#, c-format
+msgid "Clear"
+msgstr "Limpiar"
+
+#: src/components/modal/index.tsx:110 src/components/modal/index.tsx:111
+#, c-format
+msgid "should be the same"
+msgstr "deberían ser iguales"
+
+#: src/components/modal/index.tsx:111
+#, c-format
+msgid "cannot be the same as before"
+msgstr "no puede ser igual al anterior"
+
+#: src/components/modal/index.tsx:114
+#, c-format
+msgid ""
+"You are updating the authorization token from instance %1$s with id %2$s"
+msgstr ""
+"Está actualizando el token de autorización para la instancia %1$s con id %2$s"
+
+#: src/components/modal/index.tsx:124
+#, c-format
+msgid "Old token"
+msgstr "Viejo token"
+
+#: src/components/modal/index.tsx:125
+#, c-format
+msgid "New token"
+msgstr "Nuevo token"
+
+#: src/components/modal/index.tsx:127
+#, c-format
+msgid "Clearing the auth token will mean public access to the instance"
+msgstr ""
+"Limpiar el token de autorización significa acceso publico a la instancia"
+
+#: src/components/product/ProductForm.tsx:96
+#: src/paths/admin/create/CreatePage.tsx:85 src/paths/admin/list/Table.tsx:109
+#: src/paths/instance/transfers/list/Table.tsx:122
+#, c-format
+msgid "ID"
+msgstr "ID"
+
+#: src/components/product/ProductForm.tsx:98
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:121
+#: src/paths/instance/products/list/Table.tsx:85
+#, c-format
+msgid "Image"
+msgstr "Imagen"
+
+#: src/components/product/ProductForm.tsx:100
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:123
+#, c-format
+msgid "Unit"
+msgstr "Unidad"
+
+#: src/components/product/ProductForm.tsx:101
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:124
+#: src/paths/instance/products/list/Table.tsx:162
+#: src/paths/instance/products/list/Table.tsx:214
+#, c-format
+msgid "Price"
+msgstr "Precio"
+
+#: src/components/product/ProductForm.tsx:103
+#: src/paths/instance/products/list/Table.tsx:90
+#, c-format
+msgid "Stock"
+msgstr "Stock"
+
+#: src/components/product/ProductForm.tsx:105
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:128
+#: src/paths/instance/products/list/Table.tsx:88
+#, c-format
+msgid "Taxes"
+msgstr "Impuesto"
+
+#: src/index.tsx:75
+#, c-format
+msgid "Server not found"
+msgstr "Servidor no encontrado"
+
+#: src/index.tsx:85
+#, c-format
+msgid "Couldn't access the server"
+msgstr "No se pudo aceder al servidor"
+
+#: src/index.tsx:87 src/index.tsx:99
+#, c-format
+msgid "Got message %1$s from %2$s"
+msgstr "Recivimos el mensaje %1$s desde %2$s"
+
+#: src/index.tsx:97
+#, c-format
+msgid "Unexpected Error"
+msgstr "Error inesperado"
+
+#: src/paths/admin/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:108
+#, c-format
+msgid "Auth token"
+msgstr "Token de autorización"
+
+#: src/paths/admin/create/CreatePage.tsx:91
+#: src/paths/instance/details/DetailPage.tsx:77
+#: src/paths/instance/update/UpdatePage.tsx:110
+#, c-format
+msgid "Account address"
+msgstr "Dirección de cuenta"
+
+#: src/paths/admin/create/CreatePage.tsx:93
+#: src/paths/instance/update/UpdatePage.tsx:112
+#, c-format
+msgid "Default max deposit fee"
+msgstr "Impuesto máximo de deposito por omisión"
+
+#: src/paths/admin/create/CreatePage.tsx:95
+#: src/paths/instance/update/UpdatePage.tsx:114
+#, c-format
+msgid "Default max wire fee"
+msgstr "Impuesto máximo de transferencia por omisión"
+
+#: src/paths/admin/create/CreatePage.tsx:97
+#: src/paths/instance/update/UpdatePage.tsx:116
+#, c-format
+msgid "Default wire fee amortization"
+msgstr "Amortización de impuesto de transferencia por omisión"
+
+#: src/paths/admin/create/CreatePage.tsx:103
+#: src/paths/instance/update/UpdatePage.tsx:122
+#, c-format
+msgid "Jurisdiction"
+msgstr "Jurisdicción"
+
+#: src/paths/admin/create/CreatePage.tsx:107
+#: src/paths/instance/update/UpdatePage.tsx:126
+#, c-format
+msgid "Default pay delay"
+msgstr "Retrazo de pago por omisión"
+
+#: src/paths/admin/create/CreatePage.tsx:109
+#: src/paths/instance/update/UpdatePage.tsx:128
+#, c-format
+msgid "Default wire transfer delay"
+msgstr "Retrazo de transferencia por omisión"
+
+#: src/paths/admin/create/index.tsx:58
+#, c-format
+msgid "could not create instance"
+msgstr "no se pudo crear la instancia"
+
+#: src/paths/admin/list/Table.tsx:63 src/paths/admin/list/Table.tsx:131
+#: src/paths/instance/transfers/list/Table.tsx:71
+#, fuzzy, c-format
+msgid "Delete"
+msgstr "Borrando"
+
+#: src/paths/admin/list/Table.tsx:128
+#, c-format
+msgid "Edit"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:149
+#: src/paths/instance/products/list/Table.tsx:245
+#, c-format
+msgid "There is no instances yet, add more pressing the + sign"
+msgstr "No hay instancias todavían, agregue mas presionando el signo +"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:237
+#, c-format
+msgid "Inventory products"
+msgstr "Productos de inventario"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:286
+#, c-format
+msgid "Total price"
+msgstr "Precio total"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:287
+#, c-format
+msgid "Total tax"
+msgstr "Impuesto total"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:289
+#: src/paths/instance/orders/create/CreatePage.tsx:297
+#, c-format
+msgid "Order price"
+msgstr "Precio de la orden"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:295
+#, fuzzy, c-format
+msgid "Net"
+msgstr "Neto"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:300
+#: src/paths/instance/orders/details/DetailPage.tsx:144
+#: src/paths/instance/orders/details/DetailPage.tsx:295
+#: src/paths/instance/orders/list/Table.tsx:117
+#, c-format
+msgid "Summary"
+msgstr "Resumen"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:302
+#, c-format
+msgid "Payments options"
+msgstr "Opciones de pago"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:303
+#, c-format
+msgid "Auto refund deadline"
+msgstr "Plazo de reembolso automático"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:304
+#, c-format
+msgid "Refund deadline"
+msgstr "Plazo de reembolso"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:305
+#, c-format
+msgid "Pay deadline"
+msgstr "Plazo de pago"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:307
+#, c-format
+msgid "Delivery date"
+msgstr "Fecha de entrega"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:308
+#, fuzzy, c-format
+msgid "Location"
+msgstr "Ubicación"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:312
+#, c-format
+msgid "Max fee"
+msgstr "Impuesto máximo"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:313
+#, c-format
+msgid "Max wire fee"
+msgstr "Impuesto de transferencia máximo"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:314
+#, c-format
+msgid "Wire fee amortization"
+msgstr "Amortización de impuesto de transferencia"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:315
+#, c-format
+msgid "Fullfilment url"
+msgstr "URL de completitud"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:318
+#, c-format
+msgid "Extra information"
+msgstr "Información extra"
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:44
+#, c-format
+msgid "select a product first"
+msgstr "seleccione un producto primero"
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:51
+#, fuzzy, c-format
+msgid "should be greater than 0"
+msgstr "La imagen debe ser mas chica que 1 MB"
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:58
+#, c-format
+msgid ""
+"cannot be greater than current stock and quantity previously added. max: %1$s"
+msgstr ""
+"no puede ser mayor al stock actual y la cantidad previamente agregada. "
+"máximo: %1$s"
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:64
+#, c-format
+msgid "cannot be greater than current stock %1$s"
+msgstr "no puede ser mayor al stock actual %1$s"
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:76
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:126
+#, c-format
+msgid "Quantity"
+msgstr "Cantidad"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:92
+#: src/paths/instance/orders/details/DetailPage.tsx:235
+#: src/paths/instance/orders/details/DetailPage.tsx:333
+#, c-format
+msgid "Order"
+msgstr "Orden"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:93
+#, c-format
+msgid "claimed"
+msgstr "reclamado"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:110
+#: src/paths/instance/orders/details/DetailPage.tsx:261
+#: src/paths/instance/orders/list/Table.tsx:136
+#, c-format
+msgid "copy url"
+msgstr "copiar url"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:126
+#: src/paths/instance/orders/details/DetailPage.tsx:349
+#, c-format
+msgid "pay at"
+msgstr "pagar en"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:127
+#: src/paths/instance/orders/details/DetailPage.tsx:350
+#, c-format
+msgid "created at"
+msgstr "creado"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:138
+#: src/paths/instance/orders/details/DetailPage.tsx:289
+#, c-format
+msgid "Timeline"
+msgstr "Cronología"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:142
+#: src/paths/instance/orders/details/DetailPage.tsx:293
+#, c-format
+msgid "Payment details"
+msgstr "Detalles de pago"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:146
+#: src/paths/instance/orders/details/DetailPage.tsx:299
+#: src/paths/instance/orders/details/DetailPage.tsx:363
+#, fuzzy, c-format
+msgid "Order status"
+msgstr "Estado de orden"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:156
+#: src/paths/instance/orders/details/DetailPage.tsx:308
+#, fuzzy, c-format
+msgid "Product list"
+msgstr "Lista de producto"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:236
+#, c-format
+msgid "paid"
+msgstr "pagados"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:238
+#, c-format
+msgid "wired"
+msgstr "transferido"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:241
+#, c-format
+msgid "refunded"
+msgstr "reembolzado"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:258
+#, c-format
+msgid "refund"
+msgstr "reembolzar"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:297
+#, c-format
+msgid "Refunded amount"
+msgstr "Monto reembolzado"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:298
+#, c-format
+msgid "Deposit total"
+msgstr "Total depositado"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:336
+#, c-format
+msgid "unpaid"
+msgstr "impago"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:364
+#, c-format
+msgid "Order status URL"
+msgstr "URL de estado de orden"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:365
+#, c-format
+msgid "Pay URI"
+msgstr "URI de pago"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:383
+#, c-format
+msgid ""
+"Unknown order status. This is an error, please contact the administrator."
+msgstr ""
+"Estado de orden desconocido. Esto es un error, por favor contacte a su "
+"administrador"
+
+#: src/paths/instance/orders/details/index.tsx:56
+#: src/paths/instance/orders/list/index.tsx:147
+#, c-format
+msgid "refund created successfully"
+msgstr "reembolzo creado satisfactoriamente"
+
+#: src/paths/instance/orders/details/index.tsx:59
+#: src/paths/instance/orders/list/index.tsx:150
+#, fuzzy, c-format
+msgid "could not create the refund"
+msgstr "No se pudo aceder al servidor"
+
+#: src/paths/instance/orders/list/Table.tsx:111
+#, c-format
+msgid "load newer orders"
+msgstr "cargar nuevas ordenes"
+
+#: src/paths/instance/orders/list/Table.tsx:115
+#, c-format
+msgid "Date"
+msgstr "Fecha"
+
+#: src/paths/instance/orders/list/Table.tsx:131
+#: src/paths/instance/orders/list/Table.tsx:223
+#, c-format
+msgid "Refund"
+msgstr "Reembolzar"
+
+#: src/paths/instance/orders/list/Table.tsx:145
+#, c-format
+msgid "load older orders"
+msgstr "cargar viejas ordenes"
+
+#: src/paths/instance/orders/list/Table.tsx:154
+#, c-format
+msgid "No orders has been found"
+msgstr "No se enconraron ordenes"
+
+#: src/paths/instance/orders/list/Table.tsx:202
+#, c-format
+msgid "date"
+msgstr "fecha"
+
+#: src/paths/instance/orders/list/Table.tsx:203
+#, c-format
+msgid "amount"
+msgstr "monto"
+
+#: src/paths/instance/orders/list/Table.tsx:204
+#, c-format
+msgid "reason"
+msgstr "razón"
+
+#: src/paths/instance/orders/list/Table.tsx:224
+#, c-format
+msgid "Max refundable:"
+msgstr "Máximo reembolzable:"
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "Reason"
+msgstr "Razón"
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "duplicated"
+msgstr "duplicado"
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "requested by the customer"
+msgstr "pedido por el consumidor"
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "other"
+msgstr "otro"
+
+#: src/paths/instance/orders/list/index.tsx:91
+#, c-format
+msgid "go to order id"
+msgstr "ir a id de orden"
+
+#: src/paths/instance/orders/list/index.tsx:107
+#, c-format
+msgid "Paid"
+msgstr "Pagado"
+
+#: src/paths/instance/orders/list/index.tsx:108
+#, fuzzy, c-format
+msgid "Refunded"
+msgstr "Reembolzado"
+
+#: src/paths/instance/orders/list/index.tsx:109
+#, fuzzy, c-format
+msgid "Not wired"
+msgstr "No transferido"
+
+#: src/paths/instance/orders/list/index.tsx:110
+#, c-format
+msgid "All"
+msgstr "Todo"
+
+#: src/paths/instance/products/create/index.tsx:48
+#: src/paths/instance/products/update/index.tsx:64
+#, c-format
+msgid "could not create product"
+msgstr "no se pudo crear el producto"
+
+#: src/paths/instance/products/list/Table.tsx:87
+#, c-format
+msgid "Sell"
+msgstr "Venta"
+
+#: src/paths/instance/products/list/Table.tsx:89
+#, c-format
+msgid "Profit"
+msgstr "Ganancia"
+
+#: src/paths/instance/products/list/Table.tsx:91
+#, c-format
+msgid "Sold"
+msgstr "Vendido"
+
+#: src/paths/instance/products/list/index.tsx:59
+#, c-format
+msgid "product updated successfully"
+msgstr "producto actualizado correctamente"
+
+#: src/paths/instance/products/list/index.tsx:62
+#, c-format
+msgid "could not update the product"
+msgstr "no se pudo actualizar el producto"
+
+#: src/paths/instance/products/list/index.tsx:70
+#, c-format
+msgid "product delete successfully"
+msgstr "producto fue eliminado correctamente"
+
+#: src/paths/instance/products/list/index.tsx:73
+#, c-format
+msgid "could not delete the product"
+msgstr "no se pudo eliminar el producto"
+
+#: src/paths/instance/tips/list/Table.tsx:59
+#, c-format
+msgid "Tips"
+msgstr "Propinas"
+
+#: src/paths/instance/tips/list/Table.tsx:111
+#, c-format
+msgid "Committed amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:112
+#, c-format
+msgid "Exchange initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:113
+#, c-format
+msgid "Merchant initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:148
+#, c-format
+msgid "There is no tips yet, add more pressing the + sign"
+msgstr "No hay propinas todavía, agregar mas presionando el signo +"
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:50
+#: src/paths/instance/transfers/create/CreatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:56
+#, c-format
+msgid "cannot be empty"
+msgstr "no puede ser vacío"
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:51
+#, c-format
+msgid "check the id, doest look valid"
+msgstr "verificar el id, no parece válido"
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:52
+#, c-format
+msgid "should have 52 characters, current %1$s"
+msgstr "debería tener 52 caracteres, actualmente %1$s"
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:57
+#, c-format
+msgid "URL doesn't have the right format"
+msgstr "La URL no tiene el formato correcto"
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:74
+#, fuzzy, c-format
+msgid "Transfer ID"
+msgstr "Transferencias"
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:76
+#, fuzzy, c-format
+msgid "Account Address"
+msgstr "Dirección de cuenta"
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:82
+#: src/paths/instance/transfers/list/Table.tsx:125
+#, c-format
+msgid "Exchange URL"
+msgstr "URL del Exchange"
+
+#: src/paths/instance/transfers/create/index.tsx:49
+#, fuzzy, c-format
+msgid "could not inform transfer"
+msgstr "no se pudo crear la instancia"
+
+#: src/paths/instance/transfers/list/Table.tsx:118
+#, fuzzy, c-format
+msgid "load newer transfers"
+msgstr "cargar nuevas ordenes"
+
+#: src/paths/instance/transfers/list/Table.tsx:123
+#, c-format
+msgid "Credit"
+msgstr "Crédito"
+
+#: src/paths/instance/transfers/list/Table.tsx:126
+#, fuzzy, c-format
+msgid "Confirmed"
+msgstr "Confirmar"
+
+#: src/paths/instance/transfers/list/Table.tsx:127
+#: src/paths/instance/transfers/list/index.tsx:60
+#, c-format
+msgid "Verified"
+msgstr "Verificado"
+
+#: src/paths/instance/transfers/list/Table.tsx:128
+#, fuzzy, c-format
+msgid "Executed at"
+msgstr "creado"
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "yes"
+msgstr "si"
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "no"
+msgstr "no"
+
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "unknown"
+msgstr "desconocido"
+
+#: src/paths/instance/transfers/list/Table.tsx:145
+#, fuzzy, c-format
+msgid "load older transfers"
+msgstr "cargar viejas transferencias"
+
+#: src/paths/instance/transfers/list/Table.tsx:154
+#, c-format
+msgid "There is no transfer yet, add more pressing the + sign"
+msgstr "No hay transferencias todavía, agregar mas presionando el signo +"
diff --git a/packages/merchant-backend-ui/src/i18n/fr.po 
b/packages/merchant-backend-ui/src/i18n/fr.po
new file mode 100644
index 000000000..6b35bd0ce
--- /dev/null
+++ b/packages/merchant-backend-ui/src/i18n/fr.po
@@ -0,0 +1,1057 @@
+# This file is part of TALER
+# (C) 2016 GNUnet e.V.
+#
+# TALER is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3, or (at your option) any later version.
+#
+# TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Taler Wallet\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2016-11-23 00:00+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: src/ApplicationReadyRoutes.tsx:50 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:299
+#, c-format
+msgid "Access denied"
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:51 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:300
+#, c-format
+msgid "Check your token is valid"
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:72
+#, c-format
+msgid "Couldn't access the server."
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:73
+#, c-format
+msgid "Could not infer instance id from url %1$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:109
+#, c-format
+msgid "HTTP status #%1$s: Server reported a problem"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:110
+#, c-format
+msgid "Got message: \"%1$s\" from: %2$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:127
+#, c-format
+msgid "No default instance"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:128
+#, c-format
+msgid ""
+"in order to use merchant backoffice, you should create the default instance"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:288
+#, c-format
+msgid "Server reported a problem: HTTP status #%1$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:289
+#, c-format
+msgid "Got message: %1$s from: %2$s"
+msgstr ""
+
+#: src/components/exception/login.tsx:46
+#, c-format
+msgid "Login required"
+msgstr ""
+
+#: src/components/exception/login.tsx:49
+#, c-format
+msgid ""
+"Please enter your auth token. Token should have \"secret-token:\" and start "
+"with Bearer or ApiKey"
+msgstr ""
+
+#: src/components/exception/login.tsx:86 src/components/modal/index.tsx:53
+#: src/components/modal/index.tsx:75 src/paths/admin/create/CreatePage.tsx:115
+#: src/paths/instance/orders/create/CreatePage.tsx:325
+#: src/paths/instance/products/create/CreatePage.tsx:51
+#: src/paths/instance/products/list/Table.tsx:174
+#: src/paths/instance/products/list/Table.tsx:228
+#: src/paths/instance/products/update/UpdatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:134
+#, c-format
+msgid "Confirm"
+msgstr ""
+
+#: src/components/form/InputArray.tsx:72
+#, c-format
+msgid "The value %1$s is invalid for a payment url"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:67
+#: src/paths/instance/orders/list/index.tsx:123
+#, c-format
+msgid "pick a date"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:81
+#, c-format
+msgid "clear"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:83
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "never"
+msgstr ""
+
+#: src/components/form/InputImage.tsx:80
+#, c-format
+msgid "Image should be smaller than 1 MB"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:28
+#, c-format
+msgid "Country"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:30
+#: src/paths/admin/create/CreatePage.tsx:99
+#: src/paths/instance/transfers/list/Table.tsx:124
+#: src/paths/instance/update/UpdatePage.tsx:118
+#, c-format
+msgid "Address"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:34
+#, c-format
+msgid "Building number"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:35
+#, c-format
+msgid "Building name"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:36
+#, c-format
+msgid "Street"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:37
+#, c-format
+msgid "Post code"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:38
+#, c-format
+msgid "Town location"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:39
+#, c-format
+msgid "Town"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:40
+#, c-format
+msgid "District"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:41
+#, c-format
+msgid "Country subdivision"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:59
+#, c-format
+msgid "Product id"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:60
+#: src/components/product/ProductForm.tsx:99
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:122
+#: src/paths/instance/orders/list/Table.tsx:227
+#: src/paths/instance/products/list/Table.tsx:86
+#, c-format
+msgid "Description"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:73
+#: src/components/form/InputTaxes.tsx:81
+#: src/paths/admin/create/CreatePage.tsx:87 src/paths/admin/list/Table.tsx:110
+#: src/paths/instance/details/DetailPage.tsx:76
+#: src/paths/instance/update/UpdatePage.tsx:106
+#, c-format
+msgid "Name"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:102
+#, c-format
+msgid "loading..."
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:108
+#, c-format
+msgid "no products found"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:116
+#, c-format
+msgid "no results"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:33
+#, c-format
+msgid "Deleting"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:34
+#, c-format
+msgid "Changing"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:60
+#, c-format
+msgid "Manage token"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:83
+#, c-format
+msgid "Update"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:100
+#: src/paths/instance/orders/create/CreatePage.tsx:252
+#: src/paths/instance/orders/create/CreatePage.tsx:273
+#, c-format
+msgid "Remove"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:106 src/components/modal/index.tsx:52
+#: src/components/modal/index.tsx:73 src/paths/admin/create/CreatePage.tsx:114
+#: src/paths/instance/orders/create/CreatePage.tsx:324
+#: src/paths/instance/products/create/CreatePage.tsx:50
+#: src/paths/instance/products/list/Table.tsx:166
+#: src/paths/instance/products/list/Table.tsx:218
+#: src/paths/instance/products/update/UpdatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:88
+#: src/paths/instance/update/UpdatePage.tsx:133
+#, c-format
+msgid "Cancel"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:91
+#, c-format
+msgid "Manage stock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:93
+#, c-format
+msgid "Infinite"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:105
+#, c-format
+msgid "lost cannot be greater that current + incoming (max %1$s)"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:111
+#, c-format
+msgid "current stock will change from %1$s to %2$s"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:112
+#, c-format
+msgid "current stock will stay at %1$s"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:129
+#: src/paths/instance/products/list/Table.tsx:204
+#, c-format
+msgid "Incoming"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:130
+#: src/paths/instance/products/list/Table.tsx:205
+#, c-format
+msgid "Lost"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:142
+#, c-format
+msgid "Current"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:145
+#, c-format
+msgid "without stock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:150
+#, c-format
+msgid "Next restock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:152
+#, c-format
+msgid "Delivery address"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:73
+#, c-format
+msgid "this product has no taxes"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:77
+#: src/paths/instance/orders/details/DetailPage.tsx:145
+#: src/paths/instance/orders/details/DetailPage.tsx:296
+#: src/paths/instance/orders/list/Table.tsx:116
+#: src/paths/instance/transfers/create/CreatePage.tsx:84
+#, c-format
+msgid "Amount"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:78
+#, c-format
+msgid "currency and value separated with colon"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:84
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:78
+#, c-format
+msgid "Add"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:53
+#, c-format
+msgid "Instance"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:59
+#, c-format
+msgid "Settings"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:65
+#: src/paths/instance/orders/list/Table.tsx:60
+#, c-format
+msgid "Orders"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:71
+#: src/paths/instance/orders/create/CreatePage.tsx:258
+#: src/paths/instance/products/list/Table.tsx:48
+#, c-format
+msgid "Products"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:77
+#: src/paths/instance/transfers/list/Table.tsx:65
+#, c-format
+msgid "Transfers"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:87
+#, c-format
+msgid "Connection"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:112 src/paths/admin/list/Table.tsx:57
+#, c-format
+msgid "Instances"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:116
+#, c-format
+msgid "New"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:122
+#, c-format
+msgid "List"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:129
+#, c-format
+msgid "Log out"
+msgstr ""
+
+#: src/components/modal/index.tsx:74
+#, c-format
+msgid "Clear"
+msgstr ""
+
+#: src/components/modal/index.tsx:110 src/components/modal/index.tsx:111
+#, c-format
+msgid "should be the same"
+msgstr ""
+
+#: src/components/modal/index.tsx:111
+#, c-format
+msgid "cannot be the same as before"
+msgstr ""
+
+#: src/components/modal/index.tsx:114
+#, c-format
+msgid ""
+"You are updating the authorization token from instance %1$s with id %2$s"
+msgstr ""
+
+#: src/components/modal/index.tsx:124
+#, c-format
+msgid "Old token"
+msgstr ""
+
+#: src/components/modal/index.tsx:125
+#, c-format
+msgid "New token"
+msgstr ""
+
+#: src/components/modal/index.tsx:127
+#, c-format
+msgid "Clearing the auth token will mean public access to the instance"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:96
+#: src/paths/admin/create/CreatePage.tsx:85 src/paths/admin/list/Table.tsx:109
+#: src/paths/instance/transfers/list/Table.tsx:122
+#, c-format
+msgid "ID"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:98
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:121
+#: src/paths/instance/products/list/Table.tsx:85
+#, c-format
+msgid "Image"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:100
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:123
+#, c-format
+msgid "Unit"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:101
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:124
+#: src/paths/instance/products/list/Table.tsx:162
+#: src/paths/instance/products/list/Table.tsx:214
+#, c-format
+msgid "Price"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:103
+#: src/paths/instance/products/list/Table.tsx:90
+#, c-format
+msgid "Stock"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:105
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:128
+#: src/paths/instance/products/list/Table.tsx:88
+#, c-format
+msgid "Taxes"
+msgstr ""
+
+#: src/index.tsx:75
+#, c-format
+msgid "Server not found"
+msgstr ""
+
+#: src/index.tsx:85
+#, c-format
+msgid "Couldn't access the server"
+msgstr ""
+
+#: src/index.tsx:87 src/index.tsx:99
+#, c-format
+msgid "Got message %1$s from %2$s"
+msgstr ""
+
+#: src/index.tsx:97
+#, c-format
+msgid "Unexpected Error"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:108
+#, c-format
+msgid "Auth token"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:91
+#: src/paths/instance/details/DetailPage.tsx:77
+#: src/paths/instance/update/UpdatePage.tsx:110
+#, c-format
+msgid "Account address"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:93
+#: src/paths/instance/update/UpdatePage.tsx:112
+#, c-format
+msgid "Default max deposit fee"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:95
+#: src/paths/instance/update/UpdatePage.tsx:114
+#, c-format
+msgid "Default max wire fee"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:97
+#: src/paths/instance/update/UpdatePage.tsx:116
+#, c-format
+msgid "Default wire fee amortization"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:103
+#: src/paths/instance/update/UpdatePage.tsx:122
+#, c-format
+msgid "Jurisdiction"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:107
+#: src/paths/instance/update/UpdatePage.tsx:126
+#, c-format
+msgid "Default pay delay"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:109
+#: src/paths/instance/update/UpdatePage.tsx:128
+#, c-format
+msgid "Default wire transfer delay"
+msgstr ""
+
+#: src/paths/admin/create/index.tsx:58
+#, c-format
+msgid "could not create instance"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:63 src/paths/admin/list/Table.tsx:131
+#: src/paths/instance/transfers/list/Table.tsx:71
+#, c-format
+msgid "Delete"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:128
+#, c-format
+msgid "Edit"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:149
+#: src/paths/instance/products/list/Table.tsx:245
+#, c-format
+msgid "There is no instances yet, add more pressing the + sign"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:237
+#, c-format
+msgid "Inventory products"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:286
+#, c-format
+msgid "Total price"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:287
+#, c-format
+msgid "Total tax"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:289
+#: src/paths/instance/orders/create/CreatePage.tsx:297
+#, c-format
+msgid "Order price"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:295
+#, c-format
+msgid "Net"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:300
+#: src/paths/instance/orders/details/DetailPage.tsx:144
+#: src/paths/instance/orders/details/DetailPage.tsx:295
+#: src/paths/instance/orders/list/Table.tsx:117
+#, c-format
+msgid "Summary"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:302
+#, c-format
+msgid "Payments options"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:303
+#, c-format
+msgid "Auto refund deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:304
+#, c-format
+msgid "Refund deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:305
+#, c-format
+msgid "Pay deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:307
+#, c-format
+msgid "Delivery date"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:308
+#, c-format
+msgid "Location"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:312
+#, c-format
+msgid "Max fee"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:313
+#, c-format
+msgid "Max wire fee"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:314
+#, c-format
+msgid "Wire fee amortization"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:315
+#, c-format
+msgid "Fullfilment url"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:318
+#, c-format
+msgid "Extra information"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:44
+#, c-format
+msgid "select a product first"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:51
+#, c-format
+msgid "should be greater than 0"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:58
+#, c-format
+msgid ""
+"cannot be greater than current stock and quantity previously added. max: %1$s"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:64
+#, c-format
+msgid "cannot be greater than current stock %1$s"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:76
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:126
+#, c-format
+msgid "Quantity"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:92
+#: src/paths/instance/orders/details/DetailPage.tsx:235
+#: src/paths/instance/orders/details/DetailPage.tsx:333
+#, c-format
+msgid "Order"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:93
+#, c-format
+msgid "claimed"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:110
+#: src/paths/instance/orders/details/DetailPage.tsx:261
+#: src/paths/instance/orders/list/Table.tsx:136
+#, c-format
+msgid "copy url"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:126
+#: src/paths/instance/orders/details/DetailPage.tsx:349
+#, c-format
+msgid "pay at"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:127
+#: src/paths/instance/orders/details/DetailPage.tsx:350
+#, c-format
+msgid "created at"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:138
+#: src/paths/instance/orders/details/DetailPage.tsx:289
+#, c-format
+msgid "Timeline"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:142
+#: src/paths/instance/orders/details/DetailPage.tsx:293
+#, c-format
+msgid "Payment details"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:146
+#: src/paths/instance/orders/details/DetailPage.tsx:299
+#: src/paths/instance/orders/details/DetailPage.tsx:363
+#, c-format
+msgid "Order status"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:156
+#: src/paths/instance/orders/details/DetailPage.tsx:308
+#, c-format
+msgid "Product list"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:236
+#, c-format
+msgid "paid"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:238
+#, c-format
+msgid "wired"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:241
+#, c-format
+msgid "refunded"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:258
+#, c-format
+msgid "refund"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:297
+#, c-format
+msgid "Refunded amount"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:298
+#, c-format
+msgid "Deposit total"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:336
+#, c-format
+msgid "unpaid"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:364
+#, c-format
+msgid "Order status URL"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:365
+#, c-format
+msgid "Pay URI"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:383
+#, c-format
+msgid ""
+"Unknown order status. This is an error, please contact the administrator."
+msgstr ""
+
+#: src/paths/instance/orders/details/index.tsx:56
+#: src/paths/instance/orders/list/index.tsx:147
+#, c-format
+msgid "refund created successfully"
+msgstr ""
+
+#: src/paths/instance/orders/details/index.tsx:59
+#: src/paths/instance/orders/list/index.tsx:150
+#, c-format
+msgid "could not create the refund"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:111
+#, c-format
+msgid "load newer orders"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:115
+#, c-format
+msgid "Date"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:131
+#: src/paths/instance/orders/list/Table.tsx:223
+#, c-format
+msgid "Refund"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:145
+#, c-format
+msgid "load older orders"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:154
+#, c-format
+msgid "No orders has been found"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:202
+#, c-format
+msgid "date"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:203
+#, c-format
+msgid "amount"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:204
+#, c-format
+msgid "reason"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:224
+#, c-format
+msgid "Max refundable:"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "Reason"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "duplicated"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "requested by the customer"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "other"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:91
+#, c-format
+msgid "go to order id"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:107
+#, c-format
+msgid "Paid"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:108
+#, c-format
+msgid "Refunded"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:109
+#, c-format
+msgid "Not wired"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:110
+#, c-format
+msgid "All"
+msgstr ""
+
+#: src/paths/instance/products/create/index.tsx:48
+#: src/paths/instance/products/update/index.tsx:64
+#, c-format
+msgid "could not create product"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:87
+#, c-format
+msgid "Sell"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:89
+#, c-format
+msgid "Profit"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:91
+#, c-format
+msgid "Sold"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:59
+#, c-format
+msgid "product updated successfully"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:62
+#, c-format
+msgid "could not update the product"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:70
+#, c-format
+msgid "product delete successfully"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:73
+#, c-format
+msgid "could not delete the product"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:59
+#, c-format
+msgid "Tips"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:111
+#, c-format
+msgid "Committed amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:112
+#, c-format
+msgid "Exchange initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:113
+#, c-format
+msgid "Merchant initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:148
+#, c-format
+msgid "There is no tips yet, add more pressing the + sign"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:50
+#: src/paths/instance/transfers/create/CreatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:56
+#, c-format
+msgid "cannot be empty"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:51
+#, c-format
+msgid "check the id, doest look valid"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:52
+#, c-format
+msgid "should have 52 characters, current %1$s"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:57
+#, c-format
+msgid "URL doesn't have the right format"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:74
+#, c-format
+msgid "Transfer ID"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:76
+#, c-format
+msgid "Account Address"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:82
+#: src/paths/instance/transfers/list/Table.tsx:125
+#, c-format
+msgid "Exchange URL"
+msgstr ""
+
+#: src/paths/instance/transfers/create/index.tsx:49
+#, c-format
+msgid "could not inform transfer"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:118
+#, c-format
+msgid "load newer transfers"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:123
+#, c-format
+msgid "Credit"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:126
+#, c-format
+msgid "Confirmed"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:127
+#: src/paths/instance/transfers/list/index.tsx:60
+#, c-format
+msgid "Verified"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:128
+#, c-format
+msgid "Executed at"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "yes"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "no"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "unknown"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:145
+#, c-format
+msgid "load older transfers"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:154
+#, c-format
+msgid "There is no transfer yet, add more pressing the + sign"
+msgstr ""
diff --git a/packages/merchant-backend-ui/src/i18n/index.tsx 
b/packages/merchant-backend-ui/src/i18n/index.tsx
new file mode 100644
index 000000000..63c8e1934
--- /dev/null
+++ b/packages/merchant-backend-ui/src/i18n/index.tsx
@@ -0,0 +1,203 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ * Translation helpers for React components and template literals.
+ */
+
+/**
+ * Imports
+ */
+import { ComponentChild, ComponentChildren, h, Fragment, VNode } from "preact";
+
+import { useTranslationContext } from "../context/translation";
+
+export function useTranslator() {
+  const ctx = useTranslationContext();
+  const jed = ctx.handler
+  return function str(stringSeq: TemplateStringsArray, ...values: any[]): 
string {
+    const s = toI18nString(stringSeq);
+    if (!s) return s
+    const tr = jed
+      .translate(s)
+      .ifPlural(1, s)
+      .fetch(...values);
+    return tr;
+  }
+}
+
+
+/**
+ * Convert template strings to a msgid
+ */
+ function toI18nString(stringSeq: ReadonlyArray<string>): string {
+  let s = "";
+  for (let i = 0; i < stringSeq.length; i++) {
+    s += stringSeq[i];
+    if (i < stringSeq.length - 1) {
+      s += `%${i + 1}$s`;
+    }
+  }
+  return s;
+}
+
+
+interface TranslateSwitchProps {
+  target: number;
+  children: ComponentChildren;
+}
+
+function stringifyChildren(children: ComponentChildren): string {
+  let n = 1;
+  const ss = (children instanceof Array ? children : [children]).map((c) => {
+    if (typeof c === "string") {
+      return c;
+    }
+    return `%${n++}$s`;
+  });
+  const s = ss.join("").replace(/ +/g, " ").trim();
+  return s;
+}
+
+interface TranslateProps {
+  children: ComponentChildren;
+  /**
+   * Component that the translated element should be wrapped in.
+   * Defaults to "div".
+   */
+  wrap?: any;
+
+  /**
+   * Props to give to the wrapped component.
+   */
+  wrapProps?: any;
+}
+
+function getTranslatedChildren(
+  translation: string,
+  children: ComponentChildren,
+): ComponentChild[] {
+  const tr = translation.split(/%(\d+)\$s/);
+  const childArray = children instanceof Array ? children : [children];
+  // Merge consecutive string children.
+  const placeholderChildren = Array<ComponentChild>();
+  for (let i = 0; i < childArray.length; i++) {
+    const x = childArray[i];
+    if (x === undefined) {
+      continue;
+    } else if (typeof x === "string") {
+      continue;
+    } else {
+      placeholderChildren.push(x);
+    }
+  }
+  const result = Array<ComponentChild>();
+  for (let i = 0; i < tr.length; i++) {
+    if (i % 2 == 0) {
+      // Text
+      result.push(tr[i]);
+    } else {
+      const childIdx = Number.parseInt(tr[i],10) - 1;
+      result.push(placeholderChildren[childIdx]);
+    }
+  }
+  return result;
+}
+
+/**
+ * Translate text node children of this component.
+ * If a child component might produce a text node, it must be wrapped
+ * in a another non-text element.
+ *
+ * Example:
+ * ```
+ * <Translate>
+ * Hello.  Your score is <span><PlayerScore player={player} /></span>
+ * </Translate>
+ * ```
+ */
+export function Translate({ children }: TranslateProps): VNode {
+  const s = stringifyChildren(children);
+  const ctx = useTranslationContext()
+  const translation: string = ctx.handler.ngettext(s, s, 1);
+  const result = getTranslatedChildren(translation, children)
+  return <Fragment>{result}</Fragment>;
+}
+
+/**
+ * Switch translation based on singular or plural based on the target prop.
+ * Should only contain TranslateSingular and TransplatePlural as children.
+ *
+ * Example:
+ * ```
+ * <TranslateSwitch target={n}>
+ *  <TranslateSingular>I have {n} apple.</TranslateSingular>
+ *  <TranslatePlural>I have {n} apples.</TranslatePlural>
+ * </TranslateSwitch>
+ * ```
+ */
+export function TranslateSwitch({ children, target }: TranslateSwitchProps) {
+  let singular: VNode<TranslationPluralProps> | undefined;
+  let plural: VNode<TranslationPluralProps> | undefined;
+  // const children = this.props.children;
+  if (children) {
+    (children instanceof Array ? children : [children]).forEach((child: any) 
=> {
+      if (child.type === TranslatePlural) {
+        plural = child;
+      }
+      if (child.type === TranslateSingular) {
+        singular = child;
+      }
+    });
+  }
+  if (!singular || !plural) {
+    console.error("translation not found");
+    return h("span", {}, ["translation not found"]);
+  }
+  singular.props.target = target;
+  plural.props.target = target;
+  // We're looking up the translation based on the
+  // singular, even if we must use the plural form.
+  return singular;
+}
+
+interface TranslationPluralProps {
+  children: ComponentChildren;
+  target: number;
+}
+
+/**
+ * See [[TranslateSwitch]].
+ */
+export function TranslatePlural({ children, target }: TranslationPluralProps): 
VNode {
+  const s = stringifyChildren(children);
+  const ctx = useTranslationContext()
+  const translation = ctx.handler.ngettext(s, s, 1);
+  const result = getTranslatedChildren(translation, children);
+  return <Fragment>{result}</Fragment>;
+}
+
+/**
+ * See [[TranslateSwitch]].
+ */
+export function TranslateSingular({ children, target }: 
TranslationPluralProps): VNode {
+  const s = stringifyChildren(children);
+  const ctx = useTranslationContext()
+  const translation = ctx.handler.ngettext(s, s, target);
+  const result = getTranslatedChildren(translation, children);
+  return <Fragment>{result}</Fragment>;
+
+}
diff --git a/packages/merchant-backend-ui/src/i18n/it.po 
b/packages/merchant-backend-ui/src/i18n/it.po
new file mode 100644
index 000000000..6b35bd0ce
--- /dev/null
+++ b/packages/merchant-backend-ui/src/i18n/it.po
@@ -0,0 +1,1057 @@
+# This file is part of TALER
+# (C) 2016 GNUnet e.V.
+#
+# TALER is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3, or (at your option) any later version.
+#
+# TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Taler Wallet\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2016-11-23 00:00+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: src/ApplicationReadyRoutes.tsx:50 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:299
+#, c-format
+msgid "Access denied"
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:51 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:300
+#, c-format
+msgid "Check your token is valid"
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:72
+#, c-format
+msgid "Couldn't access the server."
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:73
+#, c-format
+msgid "Could not infer instance id from url %1$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:109
+#, c-format
+msgid "HTTP status #%1$s: Server reported a problem"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:110
+#, c-format
+msgid "Got message: \"%1$s\" from: %2$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:127
+#, c-format
+msgid "No default instance"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:128
+#, c-format
+msgid ""
+"in order to use merchant backoffice, you should create the default instance"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:288
+#, c-format
+msgid "Server reported a problem: HTTP status #%1$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:289
+#, c-format
+msgid "Got message: %1$s from: %2$s"
+msgstr ""
+
+#: src/components/exception/login.tsx:46
+#, c-format
+msgid "Login required"
+msgstr ""
+
+#: src/components/exception/login.tsx:49
+#, c-format
+msgid ""
+"Please enter your auth token. Token should have \"secret-token:\" and start "
+"with Bearer or ApiKey"
+msgstr ""
+
+#: src/components/exception/login.tsx:86 src/components/modal/index.tsx:53
+#: src/components/modal/index.tsx:75 src/paths/admin/create/CreatePage.tsx:115
+#: src/paths/instance/orders/create/CreatePage.tsx:325
+#: src/paths/instance/products/create/CreatePage.tsx:51
+#: src/paths/instance/products/list/Table.tsx:174
+#: src/paths/instance/products/list/Table.tsx:228
+#: src/paths/instance/products/update/UpdatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:134
+#, c-format
+msgid "Confirm"
+msgstr ""
+
+#: src/components/form/InputArray.tsx:72
+#, c-format
+msgid "The value %1$s is invalid for a payment url"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:67
+#: src/paths/instance/orders/list/index.tsx:123
+#, c-format
+msgid "pick a date"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:81
+#, c-format
+msgid "clear"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:83
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "never"
+msgstr ""
+
+#: src/components/form/InputImage.tsx:80
+#, c-format
+msgid "Image should be smaller than 1 MB"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:28
+#, c-format
+msgid "Country"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:30
+#: src/paths/admin/create/CreatePage.tsx:99
+#: src/paths/instance/transfers/list/Table.tsx:124
+#: src/paths/instance/update/UpdatePage.tsx:118
+#, c-format
+msgid "Address"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:34
+#, c-format
+msgid "Building number"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:35
+#, c-format
+msgid "Building name"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:36
+#, c-format
+msgid "Street"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:37
+#, c-format
+msgid "Post code"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:38
+#, c-format
+msgid "Town location"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:39
+#, c-format
+msgid "Town"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:40
+#, c-format
+msgid "District"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:41
+#, c-format
+msgid "Country subdivision"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:59
+#, c-format
+msgid "Product id"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:60
+#: src/components/product/ProductForm.tsx:99
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:122
+#: src/paths/instance/orders/list/Table.tsx:227
+#: src/paths/instance/products/list/Table.tsx:86
+#, c-format
+msgid "Description"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:73
+#: src/components/form/InputTaxes.tsx:81
+#: src/paths/admin/create/CreatePage.tsx:87 src/paths/admin/list/Table.tsx:110
+#: src/paths/instance/details/DetailPage.tsx:76
+#: src/paths/instance/update/UpdatePage.tsx:106
+#, c-format
+msgid "Name"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:102
+#, c-format
+msgid "loading..."
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:108
+#, c-format
+msgid "no products found"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:116
+#, c-format
+msgid "no results"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:33
+#, c-format
+msgid "Deleting"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:34
+#, c-format
+msgid "Changing"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:60
+#, c-format
+msgid "Manage token"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:83
+#, c-format
+msgid "Update"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:100
+#: src/paths/instance/orders/create/CreatePage.tsx:252
+#: src/paths/instance/orders/create/CreatePage.tsx:273
+#, c-format
+msgid "Remove"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:106 src/components/modal/index.tsx:52
+#: src/components/modal/index.tsx:73 src/paths/admin/create/CreatePage.tsx:114
+#: src/paths/instance/orders/create/CreatePage.tsx:324
+#: src/paths/instance/products/create/CreatePage.tsx:50
+#: src/paths/instance/products/list/Table.tsx:166
+#: src/paths/instance/products/list/Table.tsx:218
+#: src/paths/instance/products/update/UpdatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:88
+#: src/paths/instance/update/UpdatePage.tsx:133
+#, c-format
+msgid "Cancel"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:91
+#, c-format
+msgid "Manage stock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:93
+#, c-format
+msgid "Infinite"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:105
+#, c-format
+msgid "lost cannot be greater that current + incoming (max %1$s)"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:111
+#, c-format
+msgid "current stock will change from %1$s to %2$s"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:112
+#, c-format
+msgid "current stock will stay at %1$s"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:129
+#: src/paths/instance/products/list/Table.tsx:204
+#, c-format
+msgid "Incoming"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:130
+#: src/paths/instance/products/list/Table.tsx:205
+#, c-format
+msgid "Lost"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:142
+#, c-format
+msgid "Current"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:145
+#, c-format
+msgid "without stock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:150
+#, c-format
+msgid "Next restock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:152
+#, c-format
+msgid "Delivery address"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:73
+#, c-format
+msgid "this product has no taxes"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:77
+#: src/paths/instance/orders/details/DetailPage.tsx:145
+#: src/paths/instance/orders/details/DetailPage.tsx:296
+#: src/paths/instance/orders/list/Table.tsx:116
+#: src/paths/instance/transfers/create/CreatePage.tsx:84
+#, c-format
+msgid "Amount"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:78
+#, c-format
+msgid "currency and value separated with colon"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:84
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:78
+#, c-format
+msgid "Add"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:53
+#, c-format
+msgid "Instance"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:59
+#, c-format
+msgid "Settings"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:65
+#: src/paths/instance/orders/list/Table.tsx:60
+#, c-format
+msgid "Orders"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:71
+#: src/paths/instance/orders/create/CreatePage.tsx:258
+#: src/paths/instance/products/list/Table.tsx:48
+#, c-format
+msgid "Products"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:77
+#: src/paths/instance/transfers/list/Table.tsx:65
+#, c-format
+msgid "Transfers"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:87
+#, c-format
+msgid "Connection"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:112 src/paths/admin/list/Table.tsx:57
+#, c-format
+msgid "Instances"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:116
+#, c-format
+msgid "New"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:122
+#, c-format
+msgid "List"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:129
+#, c-format
+msgid "Log out"
+msgstr ""
+
+#: src/components/modal/index.tsx:74
+#, c-format
+msgid "Clear"
+msgstr ""
+
+#: src/components/modal/index.tsx:110 src/components/modal/index.tsx:111
+#, c-format
+msgid "should be the same"
+msgstr ""
+
+#: src/components/modal/index.tsx:111
+#, c-format
+msgid "cannot be the same as before"
+msgstr ""
+
+#: src/components/modal/index.tsx:114
+#, c-format
+msgid ""
+"You are updating the authorization token from instance %1$s with id %2$s"
+msgstr ""
+
+#: src/components/modal/index.tsx:124
+#, c-format
+msgid "Old token"
+msgstr ""
+
+#: src/components/modal/index.tsx:125
+#, c-format
+msgid "New token"
+msgstr ""
+
+#: src/components/modal/index.tsx:127
+#, c-format
+msgid "Clearing the auth token will mean public access to the instance"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:96
+#: src/paths/admin/create/CreatePage.tsx:85 src/paths/admin/list/Table.tsx:109
+#: src/paths/instance/transfers/list/Table.tsx:122
+#, c-format
+msgid "ID"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:98
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:121
+#: src/paths/instance/products/list/Table.tsx:85
+#, c-format
+msgid "Image"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:100
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:123
+#, c-format
+msgid "Unit"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:101
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:124
+#: src/paths/instance/products/list/Table.tsx:162
+#: src/paths/instance/products/list/Table.tsx:214
+#, c-format
+msgid "Price"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:103
+#: src/paths/instance/products/list/Table.tsx:90
+#, c-format
+msgid "Stock"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:105
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:128
+#: src/paths/instance/products/list/Table.tsx:88
+#, c-format
+msgid "Taxes"
+msgstr ""
+
+#: src/index.tsx:75
+#, c-format
+msgid "Server not found"
+msgstr ""
+
+#: src/index.tsx:85
+#, c-format
+msgid "Couldn't access the server"
+msgstr ""
+
+#: src/index.tsx:87 src/index.tsx:99
+#, c-format
+msgid "Got message %1$s from %2$s"
+msgstr ""
+
+#: src/index.tsx:97
+#, c-format
+msgid "Unexpected Error"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:108
+#, c-format
+msgid "Auth token"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:91
+#: src/paths/instance/details/DetailPage.tsx:77
+#: src/paths/instance/update/UpdatePage.tsx:110
+#, c-format
+msgid "Account address"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:93
+#: src/paths/instance/update/UpdatePage.tsx:112
+#, c-format
+msgid "Default max deposit fee"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:95
+#: src/paths/instance/update/UpdatePage.tsx:114
+#, c-format
+msgid "Default max wire fee"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:97
+#: src/paths/instance/update/UpdatePage.tsx:116
+#, c-format
+msgid "Default wire fee amortization"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:103
+#: src/paths/instance/update/UpdatePage.tsx:122
+#, c-format
+msgid "Jurisdiction"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:107
+#: src/paths/instance/update/UpdatePage.tsx:126
+#, c-format
+msgid "Default pay delay"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:109
+#: src/paths/instance/update/UpdatePage.tsx:128
+#, c-format
+msgid "Default wire transfer delay"
+msgstr ""
+
+#: src/paths/admin/create/index.tsx:58
+#, c-format
+msgid "could not create instance"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:63 src/paths/admin/list/Table.tsx:131
+#: src/paths/instance/transfers/list/Table.tsx:71
+#, c-format
+msgid "Delete"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:128
+#, c-format
+msgid "Edit"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:149
+#: src/paths/instance/products/list/Table.tsx:245
+#, c-format
+msgid "There is no instances yet, add more pressing the + sign"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:237
+#, c-format
+msgid "Inventory products"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:286
+#, c-format
+msgid "Total price"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:287
+#, c-format
+msgid "Total tax"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:289
+#: src/paths/instance/orders/create/CreatePage.tsx:297
+#, c-format
+msgid "Order price"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:295
+#, c-format
+msgid "Net"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:300
+#: src/paths/instance/orders/details/DetailPage.tsx:144
+#: src/paths/instance/orders/details/DetailPage.tsx:295
+#: src/paths/instance/orders/list/Table.tsx:117
+#, c-format
+msgid "Summary"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:302
+#, c-format
+msgid "Payments options"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:303
+#, c-format
+msgid "Auto refund deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:304
+#, c-format
+msgid "Refund deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:305
+#, c-format
+msgid "Pay deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:307
+#, c-format
+msgid "Delivery date"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:308
+#, c-format
+msgid "Location"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:312
+#, c-format
+msgid "Max fee"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:313
+#, c-format
+msgid "Max wire fee"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:314
+#, c-format
+msgid "Wire fee amortization"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:315
+#, c-format
+msgid "Fullfilment url"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:318
+#, c-format
+msgid "Extra information"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:44
+#, c-format
+msgid "select a product first"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:51
+#, c-format
+msgid "should be greater than 0"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:58
+#, c-format
+msgid ""
+"cannot be greater than current stock and quantity previously added. max: %1$s"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:64
+#, c-format
+msgid "cannot be greater than current stock %1$s"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:76
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:126
+#, c-format
+msgid "Quantity"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:92
+#: src/paths/instance/orders/details/DetailPage.tsx:235
+#: src/paths/instance/orders/details/DetailPage.tsx:333
+#, c-format
+msgid "Order"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:93
+#, c-format
+msgid "claimed"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:110
+#: src/paths/instance/orders/details/DetailPage.tsx:261
+#: src/paths/instance/orders/list/Table.tsx:136
+#, c-format
+msgid "copy url"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:126
+#: src/paths/instance/orders/details/DetailPage.tsx:349
+#, c-format
+msgid "pay at"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:127
+#: src/paths/instance/orders/details/DetailPage.tsx:350
+#, c-format
+msgid "created at"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:138
+#: src/paths/instance/orders/details/DetailPage.tsx:289
+#, c-format
+msgid "Timeline"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:142
+#: src/paths/instance/orders/details/DetailPage.tsx:293
+#, c-format
+msgid "Payment details"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:146
+#: src/paths/instance/orders/details/DetailPage.tsx:299
+#: src/paths/instance/orders/details/DetailPage.tsx:363
+#, c-format
+msgid "Order status"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:156
+#: src/paths/instance/orders/details/DetailPage.tsx:308
+#, c-format
+msgid "Product list"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:236
+#, c-format
+msgid "paid"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:238
+#, c-format
+msgid "wired"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:241
+#, c-format
+msgid "refunded"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:258
+#, c-format
+msgid "refund"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:297
+#, c-format
+msgid "Refunded amount"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:298
+#, c-format
+msgid "Deposit total"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:336
+#, c-format
+msgid "unpaid"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:364
+#, c-format
+msgid "Order status URL"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:365
+#, c-format
+msgid "Pay URI"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:383
+#, c-format
+msgid ""
+"Unknown order status. This is an error, please contact the administrator."
+msgstr ""
+
+#: src/paths/instance/orders/details/index.tsx:56
+#: src/paths/instance/orders/list/index.tsx:147
+#, c-format
+msgid "refund created successfully"
+msgstr ""
+
+#: src/paths/instance/orders/details/index.tsx:59
+#: src/paths/instance/orders/list/index.tsx:150
+#, c-format
+msgid "could not create the refund"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:111
+#, c-format
+msgid "load newer orders"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:115
+#, c-format
+msgid "Date"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:131
+#: src/paths/instance/orders/list/Table.tsx:223
+#, c-format
+msgid "Refund"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:145
+#, c-format
+msgid "load older orders"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:154
+#, c-format
+msgid "No orders has been found"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:202
+#, c-format
+msgid "date"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:203
+#, c-format
+msgid "amount"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:204
+#, c-format
+msgid "reason"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:224
+#, c-format
+msgid "Max refundable:"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "Reason"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "duplicated"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "requested by the customer"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "other"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:91
+#, c-format
+msgid "go to order id"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:107
+#, c-format
+msgid "Paid"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:108
+#, c-format
+msgid "Refunded"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:109
+#, c-format
+msgid "Not wired"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:110
+#, c-format
+msgid "All"
+msgstr ""
+
+#: src/paths/instance/products/create/index.tsx:48
+#: src/paths/instance/products/update/index.tsx:64
+#, c-format
+msgid "could not create product"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:87
+#, c-format
+msgid "Sell"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:89
+#, c-format
+msgid "Profit"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:91
+#, c-format
+msgid "Sold"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:59
+#, c-format
+msgid "product updated successfully"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:62
+#, c-format
+msgid "could not update the product"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:70
+#, c-format
+msgid "product delete successfully"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:73
+#, c-format
+msgid "could not delete the product"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:59
+#, c-format
+msgid "Tips"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:111
+#, c-format
+msgid "Committed amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:112
+#, c-format
+msgid "Exchange initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:113
+#, c-format
+msgid "Merchant initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:148
+#, c-format
+msgid "There is no tips yet, add more pressing the + sign"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:50
+#: src/paths/instance/transfers/create/CreatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:56
+#, c-format
+msgid "cannot be empty"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:51
+#, c-format
+msgid "check the id, doest look valid"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:52
+#, c-format
+msgid "should have 52 characters, current %1$s"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:57
+#, c-format
+msgid "URL doesn't have the right format"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:74
+#, c-format
+msgid "Transfer ID"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:76
+#, c-format
+msgid "Account Address"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:82
+#: src/paths/instance/transfers/list/Table.tsx:125
+#, c-format
+msgid "Exchange URL"
+msgstr ""
+
+#: src/paths/instance/transfers/create/index.tsx:49
+#, c-format
+msgid "could not inform transfer"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:118
+#, c-format
+msgid "load newer transfers"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:123
+#, c-format
+msgid "Credit"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:126
+#, c-format
+msgid "Confirmed"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:127
+#: src/paths/instance/transfers/list/index.tsx:60
+#, c-format
+msgid "Verified"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:128
+#, c-format
+msgid "Executed at"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "yes"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "no"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "unknown"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:145
+#, c-format
+msgid "load older transfers"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:154
+#, c-format
+msgid "There is no transfer yet, add more pressing the + sign"
+msgstr ""
diff --git a/packages/merchant-backend-ui/src/i18n/poheader 
b/packages/merchant-backend-ui/src/i18n/poheader
new file mode 100644
index 000000000..ee3fcd7be
--- /dev/null
+++ b/packages/merchant-backend-ui/src/i18n/poheader
@@ -0,0 +1,27 @@
+#  This file is part of GNU Taler
+#  (C) 2021 Taler Systems S.A.
+
+#  GNU Taler is free software; you can redistribute it and/or modify it under 
the
+#  terms of the GNU General Public License as published by the Free Software
+#  Foundation; either version 3, or (at your option) any later version.
+
+#  GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+#  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+#  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+#  You should have received a copy of the GNU General Public License along with
+#  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Taler Wallet\n"
+"Report-Msgid-Bugs-To: taler@gnu.org\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
diff --git a/packages/merchant-backend-ui/src/i18n/strings-prelude 
b/packages/merchant-backend-ui/src/i18n/strings-prelude
new file mode 100644
index 000000000..cca13afad
--- /dev/null
+++ b/packages/merchant-backend-ui/src/i18n/strings-prelude
@@ -0,0 +1,19 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/*eslint quote-props: ["error", "consistent"]*/
+export const strings: {[s: string]: any} = {};
+
diff --git a/packages/merchant-backend-ui/src/i18n/strings.ts 
b/packages/merchant-backend-ui/src/i18n/strings.ts
new file mode 100644
index 000000000..63e96949a
--- /dev/null
+++ b/packages/merchant-backend-ui/src/i18n/strings.ts
@@ -0,0 +1,3445 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/*eslint quote-props: ["error", "consistent"]*/
+export const strings: {[s: string]: any} = {};
+
+strings['de'] = {
+  "domain": "messages",
+  "locale_data": {
+    "messages": {
+      "": {
+        "domain": "messages",
+        "plural_forms": "nplurals=2; plural=(n != 1);",
+        "lang": ""
+      },
+      "Access denied": [
+        ""
+      ],
+      "Check your token is valid": [
+        ""
+      ],
+      "Couldn't access the server.": [
+        ""
+      ],
+      "Could not infer instance id from url %1$s": [
+        ""
+      ],
+      "HTTP status #%1$s: Server reported a problem": [
+        ""
+      ],
+      "Got message: \"%1$s\" from: %2$s": [
+        ""
+      ],
+      "No default instance": [
+        ""
+      ],
+      "in order to use merchant backoffice, you should create the default 
instance": [
+        ""
+      ],
+      "Server reported a problem: HTTP status #%1$s": [
+        ""
+      ],
+      "Got message: %1$s from: %2$s": [
+        ""
+      ],
+      "Login required": [
+        ""
+      ],
+      "Please enter your auth token. Token should have \"secret-token:\" and 
start with Bearer or ApiKey": [
+        ""
+      ],
+      "Confirm": [
+        ""
+      ],
+      "The value %1$s is invalid for a payment url": [
+        ""
+      ],
+      "pick a date": [
+        ""
+      ],
+      "clear": [
+        ""
+      ],
+      "never": [
+        ""
+      ],
+      "Image should be smaller than 1 MB": [
+        ""
+      ],
+      "Country": [
+        ""
+      ],
+      "Address": [
+        ""
+      ],
+      "Building number": [
+        ""
+      ],
+      "Building name": [
+        ""
+      ],
+      "Street": [
+        ""
+      ],
+      "Post code": [
+        ""
+      ],
+      "Town location": [
+        ""
+      ],
+      "Town": [
+        ""
+      ],
+      "District": [
+        ""
+      ],
+      "Country subdivision": [
+        ""
+      ],
+      "Product id": [
+        ""
+      ],
+      "Description": [
+        ""
+      ],
+      "Name": [
+        ""
+      ],
+      "loading...": [
+        ""
+      ],
+      "no products found": [
+        ""
+      ],
+      "no results": [
+        ""
+      ],
+      "Deleting": [
+        ""
+      ],
+      "Changing": [
+        ""
+      ],
+      "Manage token": [
+        ""
+      ],
+      "Update": [
+        ""
+      ],
+      "Remove": [
+        ""
+      ],
+      "Cancel": [
+        ""
+      ],
+      "Manage stock": [
+        ""
+      ],
+      "Infinite": [
+        ""
+      ],
+      "lost cannot be greater that current + incoming (max %1$s)": [
+        ""
+      ],
+      "current stock will change from %1$s to %2$s": [
+        ""
+      ],
+      "current stock will stay at %1$s": [
+        ""
+      ],
+      "Incoming": [
+        ""
+      ],
+      "Lost": [
+        ""
+      ],
+      "Current": [
+        ""
+      ],
+      "without stock": [
+        ""
+      ],
+      "Next restock": [
+        ""
+      ],
+      "Delivery address": [
+        ""
+      ],
+      "this product has no taxes": [
+        ""
+      ],
+      "Amount": [
+        ""
+      ],
+      "currency and value separated with colon": [
+        ""
+      ],
+      "Add": [
+        ""
+      ],
+      "Instance": [
+        ""
+      ],
+      "Settings": [
+        ""
+      ],
+      "Orders": [
+        ""
+      ],
+      "Products": [
+        ""
+      ],
+      "Transfers": [
+        ""
+      ],
+      "Connection": [
+        ""
+      ],
+      "Instances": [
+        ""
+      ],
+      "New": [
+        ""
+      ],
+      "List": [
+        ""
+      ],
+      "Log out": [
+        ""
+      ],
+      "Clear": [
+        ""
+      ],
+      "should be the same": [
+        ""
+      ],
+      "cannot be the same as before": [
+        ""
+      ],
+      "You are updating the authorization token from instance %1$s with id 
%2$s": [
+        ""
+      ],
+      "Old token": [
+        ""
+      ],
+      "New token": [
+        ""
+      ],
+      "Clearing the auth token will mean public access to the instance": [
+        ""
+      ],
+      "ID": [
+        ""
+      ],
+      "Image": [
+        ""
+      ],
+      "Unit": [
+        ""
+      ],
+      "Price": [
+        ""
+      ],
+      "Stock": [
+        ""
+      ],
+      "Taxes": [
+        ""
+      ],
+      "Server not found": [
+        ""
+      ],
+      "Couldn't access the server": [
+        ""
+      ],
+      "Got message %1$s from %2$s": [
+        ""
+      ],
+      "Unexpected Error": [
+        ""
+      ],
+      "Auth token": [
+        ""
+      ],
+      "Account address": [
+        ""
+      ],
+      "Default max deposit fee": [
+        ""
+      ],
+      "Default max wire fee": [
+        ""
+      ],
+      "Default wire fee amortization": [
+        ""
+      ],
+      "Jurisdiction": [
+        ""
+      ],
+      "Default pay delay": [
+        ""
+      ],
+      "Default wire transfer delay": [
+        ""
+      ],
+      "could not create instance": [
+        ""
+      ],
+      "Delete": [
+        ""
+      ],
+      "Edit": [
+        ""
+      ],
+      "There is no instances yet, add more pressing the + sign": [
+        ""
+      ],
+      "Inventory products": [
+        ""
+      ],
+      "Total price": [
+        ""
+      ],
+      "Total tax": [
+        ""
+      ],
+      "Order price": [
+        ""
+      ],
+      "Net": [
+        ""
+      ],
+      "Summary": [
+        ""
+      ],
+      "Payments options": [
+        ""
+      ],
+      "Auto refund deadline": [
+        ""
+      ],
+      "Refund deadline": [
+        ""
+      ],
+      "Pay deadline": [
+        ""
+      ],
+      "Delivery date": [
+        ""
+      ],
+      "Location": [
+        ""
+      ],
+      "Max fee": [
+        ""
+      ],
+      "Max wire fee": [
+        ""
+      ],
+      "Wire fee amortization": [
+        ""
+      ],
+      "Fullfilment url": [
+        ""
+      ],
+      "Extra information": [
+        ""
+      ],
+      "select a product first": [
+        ""
+      ],
+      "should be greater than 0": [
+        ""
+      ],
+      "cannot be greater than current stock and quantity previously added. 
max: %1$s": [
+        ""
+      ],
+      "cannot be greater than current stock %1$s": [
+        ""
+      ],
+      "Quantity": [
+        ""
+      ],
+      "Order": [
+        ""
+      ],
+      "claimed": [
+        ""
+      ],
+      "copy url": [
+        ""
+      ],
+      "pay at": [
+        ""
+      ],
+      "created at": [
+        ""
+      ],
+      "Timeline": [
+        ""
+      ],
+      "Payment details": [
+        ""
+      ],
+      "Order status": [
+        ""
+      ],
+      "Product list": [
+        ""
+      ],
+      "paid": [
+        ""
+      ],
+      "wired": [
+        ""
+      ],
+      "refunded": [
+        ""
+      ],
+      "refund": [
+        ""
+      ],
+      "Refunded amount": [
+        ""
+      ],
+      "Deposit total": [
+        ""
+      ],
+      "unpaid": [
+        ""
+      ],
+      "Order status URL": [
+        ""
+      ],
+      "Pay URI": [
+        ""
+      ],
+      "Unknown order status. This is an error, please contact the 
administrator.": [
+        ""
+      ],
+      "refund created successfully": [
+        ""
+      ],
+      "could not create the refund": [
+        ""
+      ],
+      "load newer orders": [
+        ""
+      ],
+      "Date": [
+        ""
+      ],
+      "Refund": [
+        ""
+      ],
+      "load older orders": [
+        ""
+      ],
+      "No orders has been found": [
+        ""
+      ],
+      "date": [
+        ""
+      ],
+      "amount": [
+        ""
+      ],
+      "reason": [
+        ""
+      ],
+      "Max refundable:": [
+        ""
+      ],
+      "Reason": [
+        ""
+      ],
+      "duplicated": [
+        ""
+      ],
+      "requested by the customer": [
+        ""
+      ],
+      "other": [
+        ""
+      ],
+      "go to order id": [
+        ""
+      ],
+      "Paid": [
+        ""
+      ],
+      "Refunded": [
+        ""
+      ],
+      "Not wired": [
+        ""
+      ],
+      "All": [
+        ""
+      ],
+      "could not create product": [
+        ""
+      ],
+      "Sell": [
+        ""
+      ],
+      "Profit": [
+        ""
+      ],
+      "Sold": [
+        ""
+      ],
+      "product updated successfully": [
+        ""
+      ],
+      "could not update the product": [
+        ""
+      ],
+      "product delete successfully": [
+        ""
+      ],
+      "could not delete the product": [
+        ""
+      ],
+      "Tips": [
+        ""
+      ],
+      "Committed amount": [
+        ""
+      ],
+      "Exchange initial amount": [
+        ""
+      ],
+      "Merchant initial amount": [
+        ""
+      ],
+      "There is no tips yet, add more pressing the + sign": [
+        ""
+      ],
+      "cannot be empty": [
+        ""
+      ],
+      "check the id, doest look valid": [
+        ""
+      ],
+      "should have 52 characters, current %1$s": [
+        ""
+      ],
+      "URL doesn't have the right format": [
+        ""
+      ],
+      "Transfer ID": [
+        ""
+      ],
+      "Account Address": [
+        ""
+      ],
+      "Exchange URL": [
+        ""
+      ],
+      "could not inform transfer": [
+        ""
+      ],
+      "load newer transfers": [
+        ""
+      ],
+      "Credit": [
+        ""
+      ],
+      "Confirmed": [
+        ""
+      ],
+      "Verified": [
+        ""
+      ],
+      "Executed at": [
+        ""
+      ],
+      "yes": [
+        ""
+      ],
+      "no": [
+        ""
+      ],
+      "unknown": [
+        ""
+      ],
+      "load older transfers": [
+        ""
+      ],
+      "There is no transfer yet, add more pressing the + sign": [
+        ""
+      ]
+    }
+  }
+};
+
+strings['en'] = {
+  "domain": "messages",
+  "locale_data": {
+    "messages": {
+      "": {
+        "domain": "messages",
+        "plural_forms": "nplurals=2; plural=(n != 1);",
+        "lang": ""
+      },
+      "Access denied": [
+        ""
+      ],
+      "Check your token is valid": [
+        ""
+      ],
+      "Couldn't access the server.": [
+        ""
+      ],
+      "Could not infer instance id from url %1$s": [
+        ""
+      ],
+      "HTTP status #%1$s: Server reported a problem": [
+        ""
+      ],
+      "Got message: \"%1$s\" from: %2$s": [
+        ""
+      ],
+      "No default instance": [
+        ""
+      ],
+      "in order to use merchant backoffice, you should create the default 
instance": [
+        ""
+      ],
+      "Server reported a problem: HTTP status #%1$s": [
+        ""
+      ],
+      "Got message: %1$s from: %2$s": [
+        ""
+      ],
+      "Login required": [
+        ""
+      ],
+      "Please enter your auth token. Token should have \"secret-token:\" and 
start with Bearer or ApiKey": [
+        ""
+      ],
+      "Confirm": [
+        ""
+      ],
+      "The value %1$s is invalid for a payment url": [
+        ""
+      ],
+      "pick a date": [
+        ""
+      ],
+      "clear": [
+        ""
+      ],
+      "never": [
+        ""
+      ],
+      "Image should be smaller than 1 MB": [
+        ""
+      ],
+      "Country": [
+        ""
+      ],
+      "Address": [
+        ""
+      ],
+      "Building number": [
+        ""
+      ],
+      "Building name": [
+        ""
+      ],
+      "Street": [
+        ""
+      ],
+      "Post code": [
+        ""
+      ],
+      "Town location": [
+        ""
+      ],
+      "Town": [
+        ""
+      ],
+      "District": [
+        ""
+      ],
+      "Country subdivision": [
+        ""
+      ],
+      "Product id": [
+        ""
+      ],
+      "Description": [
+        ""
+      ],
+      "Name": [
+        ""
+      ],
+      "loading...": [
+        ""
+      ],
+      "no products found": [
+        ""
+      ],
+      "no results": [
+        ""
+      ],
+      "Deleting": [
+        ""
+      ],
+      "Changing": [
+        ""
+      ],
+      "Manage token": [
+        ""
+      ],
+      "Update": [
+        ""
+      ],
+      "Remove": [
+        ""
+      ],
+      "Cancel": [
+        ""
+      ],
+      "Manage stock": [
+        ""
+      ],
+      "Infinite": [
+        ""
+      ],
+      "lost cannot be greater that current + incoming (max %1$s)": [
+        ""
+      ],
+      "current stock will change from %1$s to %2$s": [
+        ""
+      ],
+      "current stock will stay at %1$s": [
+        ""
+      ],
+      "Incoming": [
+        ""
+      ],
+      "Lost": [
+        ""
+      ],
+      "Current": [
+        ""
+      ],
+      "without stock": [
+        ""
+      ],
+      "Next restock": [
+        ""
+      ],
+      "Delivery address": [
+        ""
+      ],
+      "this product has no taxes": [
+        ""
+      ],
+      "Amount": [
+        ""
+      ],
+      "currency and value separated with colon": [
+        ""
+      ],
+      "Add": [
+        ""
+      ],
+      "Instance": [
+        ""
+      ],
+      "Settings": [
+        ""
+      ],
+      "Orders": [
+        ""
+      ],
+      "Products": [
+        ""
+      ],
+      "Transfers": [
+        ""
+      ],
+      "Connection": [
+        ""
+      ],
+      "Instances": [
+        ""
+      ],
+      "New": [
+        ""
+      ],
+      "List": [
+        ""
+      ],
+      "Log out": [
+        ""
+      ],
+      "Clear": [
+        ""
+      ],
+      "should be the same": [
+        ""
+      ],
+      "cannot be the same as before": [
+        ""
+      ],
+      "You are updating the authorization token from instance %1$s with id 
%2$s": [
+        ""
+      ],
+      "Old token": [
+        ""
+      ],
+      "New token": [
+        ""
+      ],
+      "Clearing the auth token will mean public access to the instance": [
+        ""
+      ],
+      "ID": [
+        ""
+      ],
+      "Image": [
+        ""
+      ],
+      "Unit": [
+        ""
+      ],
+      "Price": [
+        ""
+      ],
+      "Stock": [
+        ""
+      ],
+      "Taxes": [
+        ""
+      ],
+      "Server not found": [
+        ""
+      ],
+      "Couldn't access the server": [
+        ""
+      ],
+      "Got message %1$s from %2$s": [
+        ""
+      ],
+      "Unexpected Error": [
+        ""
+      ],
+      "Auth token": [
+        ""
+      ],
+      "Account address": [
+        ""
+      ],
+      "Default max deposit fee": [
+        ""
+      ],
+      "Default max wire fee": [
+        ""
+      ],
+      "Default wire fee amortization": [
+        ""
+      ],
+      "Jurisdiction": [
+        ""
+      ],
+      "Default pay delay": [
+        ""
+      ],
+      "Default wire transfer delay": [
+        ""
+      ],
+      "could not create instance": [
+        ""
+      ],
+      "Delete": [
+        ""
+      ],
+      "Edit": [
+        ""
+      ],
+      "There is no instances yet, add more pressing the + sign": [
+        ""
+      ],
+      "Inventory products": [
+        ""
+      ],
+      "Total price": [
+        ""
+      ],
+      "Total tax": [
+        ""
+      ],
+      "Order price": [
+        ""
+      ],
+      "Net": [
+        ""
+      ],
+      "Summary": [
+        ""
+      ],
+      "Payments options": [
+        ""
+      ],
+      "Auto refund deadline": [
+        ""
+      ],
+      "Refund deadline": [
+        ""
+      ],
+      "Pay deadline": [
+        ""
+      ],
+      "Delivery date": [
+        ""
+      ],
+      "Location": [
+        ""
+      ],
+      "Max fee": [
+        ""
+      ],
+      "Max wire fee": [
+        ""
+      ],
+      "Wire fee amortization": [
+        ""
+      ],
+      "Fullfilment url": [
+        ""
+      ],
+      "Extra information": [
+        ""
+      ],
+      "select a product first": [
+        ""
+      ],
+      "should be greater than 0": [
+        ""
+      ],
+      "cannot be greater than current stock and quantity previously added. 
max: %1$s": [
+        ""
+      ],
+      "cannot be greater than current stock %1$s": [
+        ""
+      ],
+      "Quantity": [
+        ""
+      ],
+      "Order": [
+        ""
+      ],
+      "claimed": [
+        ""
+      ],
+      "copy url": [
+        ""
+      ],
+      "pay at": [
+        ""
+      ],
+      "created at": [
+        ""
+      ],
+      "Timeline": [
+        ""
+      ],
+      "Payment details": [
+        ""
+      ],
+      "Order status": [
+        ""
+      ],
+      "Product list": [
+        ""
+      ],
+      "paid": [
+        ""
+      ],
+      "wired": [
+        ""
+      ],
+      "refunded": [
+        ""
+      ],
+      "refund": [
+        ""
+      ],
+      "Refunded amount": [
+        ""
+      ],
+      "Deposit total": [
+        ""
+      ],
+      "unpaid": [
+        ""
+      ],
+      "Order status URL": [
+        ""
+      ],
+      "Pay URI": [
+        ""
+      ],
+      "Unknown order status. This is an error, please contact the 
administrator.": [
+        ""
+      ],
+      "refund created successfully": [
+        ""
+      ],
+      "could not create the refund": [
+        ""
+      ],
+      "load newer orders": [
+        ""
+      ],
+      "Date": [
+        ""
+      ],
+      "Refund": [
+        ""
+      ],
+      "load older orders": [
+        ""
+      ],
+      "No orders has been found": [
+        ""
+      ],
+      "date": [
+        ""
+      ],
+      "amount": [
+        ""
+      ],
+      "reason": [
+        ""
+      ],
+      "Max refundable:": [
+        ""
+      ],
+      "Reason": [
+        ""
+      ],
+      "duplicated": [
+        ""
+      ],
+      "requested by the customer": [
+        ""
+      ],
+      "other": [
+        ""
+      ],
+      "go to order id": [
+        ""
+      ],
+      "Paid": [
+        ""
+      ],
+      "Refunded": [
+        ""
+      ],
+      "Not wired": [
+        ""
+      ],
+      "All": [
+        ""
+      ],
+      "could not create product": [
+        ""
+      ],
+      "Sell": [
+        ""
+      ],
+      "Profit": [
+        ""
+      ],
+      "Sold": [
+        ""
+      ],
+      "product updated successfully": [
+        ""
+      ],
+      "could not update the product": [
+        ""
+      ],
+      "product delete successfully": [
+        ""
+      ],
+      "could not delete the product": [
+        ""
+      ],
+      "Tips": [
+        ""
+      ],
+      "Committed amount": [
+        ""
+      ],
+      "Exchange initial amount": [
+        ""
+      ],
+      "Merchant initial amount": [
+        ""
+      ],
+      "There is no tips yet, add more pressing the + sign": [
+        ""
+      ],
+      "cannot be empty": [
+        ""
+      ],
+      "check the id, doest look valid": [
+        ""
+      ],
+      "should have 52 characters, current %1$s": [
+        ""
+      ],
+      "URL doesn't have the right format": [
+        ""
+      ],
+      "Transfer ID": [
+        ""
+      ],
+      "Account Address": [
+        ""
+      ],
+      "Exchange URL": [
+        ""
+      ],
+      "could not inform transfer": [
+        ""
+      ],
+      "load newer transfers": [
+        ""
+      ],
+      "Credit": [
+        ""
+      ],
+      "Confirmed": [
+        ""
+      ],
+      "Verified": [
+        ""
+      ],
+      "Executed at": [
+        ""
+      ],
+      "yes": [
+        ""
+      ],
+      "no": [
+        ""
+      ],
+      "unknown": [
+        ""
+      ],
+      "load older transfers": [
+        ""
+      ],
+      "There is no transfer yet, add more pressing the + sign": [
+        ""
+      ]
+    }
+  }
+};
+
+strings['es'] = {
+  "domain": "messages",
+  "locale_data": {
+    "messages": {
+      "": {
+        "domain": "messages",
+        "plural_forms": "nplurals=2; plural=(n != 1);",
+        "lang": ""
+      },
+      "Access denied": [
+        "Acceso denegado"
+      ],
+      "Check your token is valid": [
+        "Verifica que el token sea valido"
+      ],
+      "Couldn't access the server.": [
+        "No se pudo acceder al servidor"
+      ],
+      "Could not infer instance id from url %1$s": [
+        "No se pudo inferir el id de la instancia con la url %1$s"
+      ],
+      "HTTP status #%1$s: Server reported a problem": [
+        "HTTP status #%1$s: Servidor reporto un problema"
+      ],
+      "Got message: \"%1$s\" from: %2$s": [
+        "Recivimos el mensaje %1$s desde %2$s"
+      ],
+      "No default instance": [
+        "Sin instancia default"
+      ],
+      "in order to use merchant backoffice, you should create the default 
instance": [
+        "para usar el merchant backoffice, debería crear la instancia default"
+      ],
+      "Server reported a problem: HTTP status #%1$s": [
+        "Servidir reporto un problema: HTTP status #%1$s"
+      ],
+      "Got message: %1$s from: %2$s": [
+        "Recivimos el mensaje %1$s desde %2$s"
+      ],
+      "Login required": [
+        "Login necesario"
+      ],
+      "Please enter your auth token. Token should have \"secret-token:\" and 
start with Bearer or ApiKey": [
+        "Por favor ingrese su token de autorización. El token debe tener 
\"secret-token\" y comenzar con Bearer o ApiKey"
+      ],
+      "Confirm": [
+        "Confirmar"
+      ],
+      "The value %1$s is invalid for a payment url": [
+        "El valor %1$s es invalido para una URL de pago"
+      ],
+      "pick a date": [
+        "elegir una fecha"
+      ],
+      "clear": [
+        "Limpiar"
+      ],
+      "never": [
+        "nunca"
+      ],
+      "Image should be smaller than 1 MB": [
+        "La imagen debe ser mas chica que 1 MB"
+      ],
+      "Country": [
+        "País"
+      ],
+      "Address": [
+        "Dirección"
+      ],
+      "Building number": [
+        "Número de edificio"
+      ],
+      "Building name": [
+        "Nombre de edificio"
+      ],
+      "Street": [
+        "Calle"
+      ],
+      "Post code": [
+        "Código postal"
+      ],
+      "Town location": [
+        "Ubicación de ciudad"
+      ],
+      "Town": [
+        "Ciudad"
+      ],
+      "District": [
+        "Distrito"
+      ],
+      "Country subdivision": [
+        "Provincia"
+      ],
+      "Product id": [
+        "Id de producto"
+      ],
+      "Description": [
+        "Descripcion"
+      ],
+      "Name": [
+        "Nombre"
+      ],
+      "loading...": [
+        "Cargando..."
+      ],
+      "no products found": [
+        "No se encontraron productos"
+      ],
+      "no results": [
+        "Sin resultados"
+      ],
+      "Deleting": [
+        "Borrando"
+      ],
+      "Changing": [
+        "Cambiando"
+      ],
+      "Manage token": [
+        "Administrar token"
+      ],
+      "Update": [
+        "Actualizar"
+      ],
+      "Remove": [
+        "Eliminar"
+      ],
+      "Cancel": [
+        "Cancelar"
+      ],
+      "Manage stock": [
+        "Administrar stock"
+      ],
+      "Infinite": [
+        "Inifinito"
+      ],
+      "lost cannot be greater that current + incoming (max %1$s)": [
+        "no puede ser mayor al stock actual %1$s"
+      ],
+      "current stock will change from %1$s to %2$s": [
+        "stock actual cambiará desde %1$s a %2$s"
+      ],
+      "current stock will stay at %1$s": [
+        "stock actual seguirá en %1$s"
+      ],
+      "Incoming": [
+        "Ingresando"
+      ],
+      "Lost": [
+        "Perdido"
+      ],
+      "Current": [
+        "Actual"
+      ],
+      "without stock": [
+        "sin stock"
+      ],
+      "Next restock": [
+        "Próximo reabastecimiento"
+      ],
+      "Delivery address": [
+        "Dirección de entrega"
+      ],
+      "this product has no taxes": [
+        "este producto no tiene impuestos"
+      ],
+      "Amount": [
+        "Monto"
+      ],
+      "currency and value separated with colon": [
+        "Moneda y valor separado por dos puntos"
+      ],
+      "Add": [
+        "Agregar"
+      ],
+      "Instance": [
+        "Instancia"
+      ],
+      "Settings": [
+        "Configuración"
+      ],
+      "Orders": [
+        "Ordenes"
+      ],
+      "Products": [
+        "Productos"
+      ],
+      "Transfers": [
+        "Transferencias"
+      ],
+      "Connection": [
+        "Conexión"
+      ],
+      "Instances": [
+        "Instancias"
+      ],
+      "New": [
+        "Nuevo"
+      ],
+      "List": [
+        "Lista"
+      ],
+      "Log out": [
+        "Salir"
+      ],
+      "Clear": [
+        "Limpiar"
+      ],
+      "should be the same": [
+        "deberían ser iguales"
+      ],
+      "cannot be the same as before": [
+        "no puede ser igual al anterior"
+      ],
+      "You are updating the authorization token from instance %1$s with id 
%2$s": [
+        "Está actualizando el token de autorización para la instancia %1$s con 
id %2$s"
+      ],
+      "Old token": [
+        "Viejo token"
+      ],
+      "New token": [
+        "Nuevo token"
+      ],
+      "Clearing the auth token will mean public access to the instance": [
+        "Limpiar el token de autorización significa acceso publico a la 
instancia"
+      ],
+      "ID": [
+        "ID"
+      ],
+      "Image": [
+        "Imagen"
+      ],
+      "Unit": [
+        "Unidad"
+      ],
+      "Price": [
+        "Precio"
+      ],
+      "Stock": [
+        "Stock"
+      ],
+      "Taxes": [
+        "Impuesto"
+      ],
+      "Server not found": [
+        "Servidor no encontrado"
+      ],
+      "Couldn't access the server": [
+        "No se pudo aceder al servidor"
+      ],
+      "Got message %1$s from %2$s": [
+        "Recivimos el mensaje %1$s desde %2$s"
+      ],
+      "Unexpected Error": [
+        "Error inesperado"
+      ],
+      "Auth token": [
+        "Token de autorización"
+      ],
+      "Account address": [
+        "Dirección de cuenta"
+      ],
+      "Default max deposit fee": [
+        "Impuesto máximo de deposito por omisión"
+      ],
+      "Default max wire fee": [
+        "Impuesto máximo de transferencia por omisión"
+      ],
+      "Default wire fee amortization": [
+        "Amortización de impuesto de transferencia por omisión"
+      ],
+      "Jurisdiction": [
+        "Jurisdicción"
+      ],
+      "Default pay delay": [
+        "Retrazo de pago por omisión"
+      ],
+      "Default wire transfer delay": [
+        "Retrazo de transferencia por omisión"
+      ],
+      "could not create instance": [
+        "no se pudo crear la instancia"
+      ],
+      "Delete": [
+        "Borrando"
+      ],
+      "Edit": [
+        ""
+      ],
+      "There is no instances yet, add more pressing the + sign": [
+        "No hay instancias todavían, agregue mas presionando el signo +"
+      ],
+      "Inventory products": [
+        "Productos de inventario"
+      ],
+      "Total price": [
+        "Precio total"
+      ],
+      "Total tax": [
+        "Impuesto total"
+      ],
+      "Order price": [
+        "Precio de la orden"
+      ],
+      "Net": [
+        "Neto"
+      ],
+      "Summary": [
+        "Resumen"
+      ],
+      "Payments options": [
+        "Opciones de pago"
+      ],
+      "Auto refund deadline": [
+        "Plazo de reembolso automático"
+      ],
+      "Refund deadline": [
+        "Plazo de reembolso"
+      ],
+      "Pay deadline": [
+        "Plazo de pago"
+      ],
+      "Delivery date": [
+        "Fecha de entrega"
+      ],
+      "Location": [
+        "Ubicación"
+      ],
+      "Max fee": [
+        "Impuesto máximo"
+      ],
+      "Max wire fee": [
+        "Impuesto de transferencia máximo"
+      ],
+      "Wire fee amortization": [
+        "Amortización de impuesto de transferencia"
+      ],
+      "Fullfilment url": [
+        "URL de completitud"
+      ],
+      "Extra information": [
+        "Información extra"
+      ],
+      "select a product first": [
+        "seleccione un producto primero"
+      ],
+      "should be greater than 0": [
+        "La imagen debe ser mas chica que 1 MB"
+      ],
+      "cannot be greater than current stock and quantity previously added. 
max: %1$s": [
+        "no puede ser mayor al stock actual y la cantidad previamente 
agregada. máximo: %1$s"
+      ],
+      "cannot be greater than current stock %1$s": [
+        "no puede ser mayor al stock actual %1$s"
+      ],
+      "Quantity": [
+        "Cantidad"
+      ],
+      "Order": [
+        "Orden"
+      ],
+      "claimed": [
+        "reclamado"
+      ],
+      "copy url": [
+        "copiar url"
+      ],
+      "pay at": [
+        "pagar en"
+      ],
+      "created at": [
+        "creado"
+      ],
+      "Timeline": [
+        "Cronología"
+      ],
+      "Payment details": [
+        "Detalles de pago"
+      ],
+      "Order status": [
+        "Estado de orden"
+      ],
+      "Product list": [
+        "Lista de producto"
+      ],
+      "paid": [
+        "pagados"
+      ],
+      "wired": [
+        "transferido"
+      ],
+      "refunded": [
+        "reembolzado"
+      ],
+      "refund": [
+        "reembolzar"
+      ],
+      "Refunded amount": [
+        "Monto reembolzado"
+      ],
+      "Deposit total": [
+        "Total depositado"
+      ],
+      "unpaid": [
+        "impago"
+      ],
+      "Order status URL": [
+        "URL de estado de orden"
+      ],
+      "Pay URI": [
+        "URI de pago"
+      ],
+      "Unknown order status. This is an error, please contact the 
administrator.": [
+        "Estado de orden desconocido. Esto es un error, por favor contacte a 
su administrador"
+      ],
+      "refund created successfully": [
+        "reembolzo creado satisfactoriamente"
+      ],
+      "could not create the refund": [
+        "No se pudo aceder al servidor"
+      ],
+      "load newer orders": [
+        "cargar nuevas ordenes"
+      ],
+      "Date": [
+        "Fecha"
+      ],
+      "Refund": [
+        "Reembolzar"
+      ],
+      "load older orders": [
+        "cargar viejas ordenes"
+      ],
+      "No orders has been found": [
+        "No se enconraron ordenes"
+      ],
+      "date": [
+        "fecha"
+      ],
+      "amount": [
+        "monto"
+      ],
+      "reason": [
+        "razón"
+      ],
+      "Max refundable:": [
+        "Máximo reembolzable:"
+      ],
+      "Reason": [
+        "Razón"
+      ],
+      "duplicated": [
+        "duplicado"
+      ],
+      "requested by the customer": [
+        "pedido por el consumidor"
+      ],
+      "other": [
+        "otro"
+      ],
+      "go to order id": [
+        "ir a id de orden"
+      ],
+      "Paid": [
+        "Pagado"
+      ],
+      "Refunded": [
+        "Reembolzado"
+      ],
+      "Not wired": [
+        "No transferido"
+      ],
+      "All": [
+        "Todo"
+      ],
+      "could not create product": [
+        "no se pudo crear el producto"
+      ],
+      "Sell": [
+        "Venta"
+      ],
+      "Profit": [
+        "Ganancia"
+      ],
+      "Sold": [
+        "Vendido"
+      ],
+      "product updated successfully": [
+        "producto actualizado correctamente"
+      ],
+      "could not update the product": [
+        "no se pudo actualizar el producto"
+      ],
+      "product delete successfully": [
+        "producto fue eliminado correctamente"
+      ],
+      "could not delete the product": [
+        "no se pudo eliminar el producto"
+      ],
+      "Tips": [
+        "Propinas"
+      ],
+      "Committed amount": [
+        ""
+      ],
+      "Exchange initial amount": [
+        ""
+      ],
+      "Merchant initial amount": [
+        ""
+      ],
+      "There is no tips yet, add more pressing the + sign": [
+        "No hay propinas todavía, agregar mas presionando el signo +"
+      ],
+      "cannot be empty": [
+        "no puede ser vacío"
+      ],
+      "check the id, doest look valid": [
+        "verificar el id, no parece válido"
+      ],
+      "should have 52 characters, current %1$s": [
+        "debería tener 52 caracteres, actualmente %1$s"
+      ],
+      "URL doesn't have the right format": [
+        "La URL no tiene el formato correcto"
+      ],
+      "Transfer ID": [
+        "Transferencias"
+      ],
+      "Account Address": [
+        "Dirección de cuenta"
+      ],
+      "Exchange URL": [
+        "URL del Exchange"
+      ],
+      "could not inform transfer": [
+        "no se pudo crear la instancia"
+      ],
+      "load newer transfers": [
+        "cargar nuevas ordenes"
+      ],
+      "Credit": [
+        "Crédito"
+      ],
+      "Confirmed": [
+        "Confirmar"
+      ],
+      "Verified": [
+        "Verificado"
+      ],
+      "Executed at": [
+        "creado"
+      ],
+      "yes": [
+        "si"
+      ],
+      "no": [
+        "no"
+      ],
+      "unknown": [
+        "desconocido"
+      ],
+      "load older transfers": [
+        "cargar viejas transferencias"
+      ],
+      "There is no transfer yet, add more pressing the + sign": [
+        "No hay transferencias todavía, agregar mas presionando el signo +"
+      ]
+    }
+  }
+};
+
+strings['fr'] = {
+  "domain": "messages",
+  "locale_data": {
+    "messages": {
+      "": {
+        "domain": "messages",
+        "plural_forms": "nplurals=2; plural=(n != 1);",
+        "lang": ""
+      },
+      "Access denied": [
+        ""
+      ],
+      "Check your token is valid": [
+        ""
+      ],
+      "Couldn't access the server.": [
+        ""
+      ],
+      "Could not infer instance id from url %1$s": [
+        ""
+      ],
+      "HTTP status #%1$s: Server reported a problem": [
+        ""
+      ],
+      "Got message: \"%1$s\" from: %2$s": [
+        ""
+      ],
+      "No default instance": [
+        ""
+      ],
+      "in order to use merchant backoffice, you should create the default 
instance": [
+        ""
+      ],
+      "Server reported a problem: HTTP status #%1$s": [
+        ""
+      ],
+      "Got message: %1$s from: %2$s": [
+        ""
+      ],
+      "Login required": [
+        ""
+      ],
+      "Please enter your auth token. Token should have \"secret-token:\" and 
start with Bearer or ApiKey": [
+        ""
+      ],
+      "Confirm": [
+        ""
+      ],
+      "The value %1$s is invalid for a payment url": [
+        ""
+      ],
+      "pick a date": [
+        ""
+      ],
+      "clear": [
+        ""
+      ],
+      "never": [
+        ""
+      ],
+      "Image should be smaller than 1 MB": [
+        ""
+      ],
+      "Country": [
+        ""
+      ],
+      "Address": [
+        ""
+      ],
+      "Building number": [
+        ""
+      ],
+      "Building name": [
+        ""
+      ],
+      "Street": [
+        ""
+      ],
+      "Post code": [
+        ""
+      ],
+      "Town location": [
+        ""
+      ],
+      "Town": [
+        ""
+      ],
+      "District": [
+        ""
+      ],
+      "Country subdivision": [
+        ""
+      ],
+      "Product id": [
+        ""
+      ],
+      "Description": [
+        ""
+      ],
+      "Name": [
+        ""
+      ],
+      "loading...": [
+        ""
+      ],
+      "no products found": [
+        ""
+      ],
+      "no results": [
+        ""
+      ],
+      "Deleting": [
+        ""
+      ],
+      "Changing": [
+        ""
+      ],
+      "Manage token": [
+        ""
+      ],
+      "Update": [
+        ""
+      ],
+      "Remove": [
+        ""
+      ],
+      "Cancel": [
+        ""
+      ],
+      "Manage stock": [
+        ""
+      ],
+      "Infinite": [
+        ""
+      ],
+      "lost cannot be greater that current + incoming (max %1$s)": [
+        ""
+      ],
+      "current stock will change from %1$s to %2$s": [
+        ""
+      ],
+      "current stock will stay at %1$s": [
+        ""
+      ],
+      "Incoming": [
+        ""
+      ],
+      "Lost": [
+        ""
+      ],
+      "Current": [
+        ""
+      ],
+      "without stock": [
+        ""
+      ],
+      "Next restock": [
+        ""
+      ],
+      "Delivery address": [
+        ""
+      ],
+      "this product has no taxes": [
+        ""
+      ],
+      "Amount": [
+        ""
+      ],
+      "currency and value separated with colon": [
+        ""
+      ],
+      "Add": [
+        ""
+      ],
+      "Instance": [
+        ""
+      ],
+      "Settings": [
+        ""
+      ],
+      "Orders": [
+        ""
+      ],
+      "Products": [
+        ""
+      ],
+      "Transfers": [
+        ""
+      ],
+      "Connection": [
+        ""
+      ],
+      "Instances": [
+        ""
+      ],
+      "New": [
+        ""
+      ],
+      "List": [
+        ""
+      ],
+      "Log out": [
+        ""
+      ],
+      "Clear": [
+        ""
+      ],
+      "should be the same": [
+        ""
+      ],
+      "cannot be the same as before": [
+        ""
+      ],
+      "You are updating the authorization token from instance %1$s with id 
%2$s": [
+        ""
+      ],
+      "Old token": [
+        ""
+      ],
+      "New token": [
+        ""
+      ],
+      "Clearing the auth token will mean public access to the instance": [
+        ""
+      ],
+      "ID": [
+        ""
+      ],
+      "Image": [
+        ""
+      ],
+      "Unit": [
+        ""
+      ],
+      "Price": [
+        ""
+      ],
+      "Stock": [
+        ""
+      ],
+      "Taxes": [
+        ""
+      ],
+      "Server not found": [
+        ""
+      ],
+      "Couldn't access the server": [
+        ""
+      ],
+      "Got message %1$s from %2$s": [
+        ""
+      ],
+      "Unexpected Error": [
+        ""
+      ],
+      "Auth token": [
+        ""
+      ],
+      "Account address": [
+        ""
+      ],
+      "Default max deposit fee": [
+        ""
+      ],
+      "Default max wire fee": [
+        ""
+      ],
+      "Default wire fee amortization": [
+        ""
+      ],
+      "Jurisdiction": [
+        ""
+      ],
+      "Default pay delay": [
+        ""
+      ],
+      "Default wire transfer delay": [
+        ""
+      ],
+      "could not create instance": [
+        ""
+      ],
+      "Delete": [
+        ""
+      ],
+      "Edit": [
+        ""
+      ],
+      "There is no instances yet, add more pressing the + sign": [
+        ""
+      ],
+      "Inventory products": [
+        ""
+      ],
+      "Total price": [
+        ""
+      ],
+      "Total tax": [
+        ""
+      ],
+      "Order price": [
+        ""
+      ],
+      "Net": [
+        ""
+      ],
+      "Summary": [
+        ""
+      ],
+      "Payments options": [
+        ""
+      ],
+      "Auto refund deadline": [
+        ""
+      ],
+      "Refund deadline": [
+        ""
+      ],
+      "Pay deadline": [
+        ""
+      ],
+      "Delivery date": [
+        ""
+      ],
+      "Location": [
+        ""
+      ],
+      "Max fee": [
+        ""
+      ],
+      "Max wire fee": [
+        ""
+      ],
+      "Wire fee amortization": [
+        ""
+      ],
+      "Fullfilment url": [
+        ""
+      ],
+      "Extra information": [
+        ""
+      ],
+      "select a product first": [
+        ""
+      ],
+      "should be greater than 0": [
+        ""
+      ],
+      "cannot be greater than current stock and quantity previously added. 
max: %1$s": [
+        ""
+      ],
+      "cannot be greater than current stock %1$s": [
+        ""
+      ],
+      "Quantity": [
+        ""
+      ],
+      "Order": [
+        ""
+      ],
+      "claimed": [
+        ""
+      ],
+      "copy url": [
+        ""
+      ],
+      "pay at": [
+        ""
+      ],
+      "created at": [
+        ""
+      ],
+      "Timeline": [
+        ""
+      ],
+      "Payment details": [
+        ""
+      ],
+      "Order status": [
+        ""
+      ],
+      "Product list": [
+        ""
+      ],
+      "paid": [
+        ""
+      ],
+      "wired": [
+        ""
+      ],
+      "refunded": [
+        ""
+      ],
+      "refund": [
+        ""
+      ],
+      "Refunded amount": [
+        ""
+      ],
+      "Deposit total": [
+        ""
+      ],
+      "unpaid": [
+        ""
+      ],
+      "Order status URL": [
+        ""
+      ],
+      "Pay URI": [
+        ""
+      ],
+      "Unknown order status. This is an error, please contact the 
administrator.": [
+        ""
+      ],
+      "refund created successfully": [
+        ""
+      ],
+      "could not create the refund": [
+        ""
+      ],
+      "load newer orders": [
+        ""
+      ],
+      "Date": [
+        ""
+      ],
+      "Refund": [
+        ""
+      ],
+      "load older orders": [
+        ""
+      ],
+      "No orders has been found": [
+        ""
+      ],
+      "date": [
+        ""
+      ],
+      "amount": [
+        ""
+      ],
+      "reason": [
+        ""
+      ],
+      "Max refundable:": [
+        ""
+      ],
+      "Reason": [
+        ""
+      ],
+      "duplicated": [
+        ""
+      ],
+      "requested by the customer": [
+        ""
+      ],
+      "other": [
+        ""
+      ],
+      "go to order id": [
+        ""
+      ],
+      "Paid": [
+        ""
+      ],
+      "Refunded": [
+        ""
+      ],
+      "Not wired": [
+        ""
+      ],
+      "All": [
+        ""
+      ],
+      "could not create product": [
+        ""
+      ],
+      "Sell": [
+        ""
+      ],
+      "Profit": [
+        ""
+      ],
+      "Sold": [
+        ""
+      ],
+      "product updated successfully": [
+        ""
+      ],
+      "could not update the product": [
+        ""
+      ],
+      "product delete successfully": [
+        ""
+      ],
+      "could not delete the product": [
+        ""
+      ],
+      "Tips": [
+        ""
+      ],
+      "Committed amount": [
+        ""
+      ],
+      "Exchange initial amount": [
+        ""
+      ],
+      "Merchant initial amount": [
+        ""
+      ],
+      "There is no tips yet, add more pressing the + sign": [
+        ""
+      ],
+      "cannot be empty": [
+        ""
+      ],
+      "check the id, doest look valid": [
+        ""
+      ],
+      "should have 52 characters, current %1$s": [
+        ""
+      ],
+      "URL doesn't have the right format": [
+        ""
+      ],
+      "Transfer ID": [
+        ""
+      ],
+      "Account Address": [
+        ""
+      ],
+      "Exchange URL": [
+        ""
+      ],
+      "could not inform transfer": [
+        ""
+      ],
+      "load newer transfers": [
+        ""
+      ],
+      "Credit": [
+        ""
+      ],
+      "Confirmed": [
+        ""
+      ],
+      "Verified": [
+        ""
+      ],
+      "Executed at": [
+        ""
+      ],
+      "yes": [
+        ""
+      ],
+      "no": [
+        ""
+      ],
+      "unknown": [
+        ""
+      ],
+      "load older transfers": [
+        ""
+      ],
+      "There is no transfer yet, add more pressing the + sign": [
+        ""
+      ]
+    }
+  }
+};
+
+strings['it'] = {
+  "domain": "messages",
+  "locale_data": {
+    "messages": {
+      "": {
+        "domain": "messages",
+        "plural_forms": "nplurals=2; plural=(n != 1);",
+        "lang": ""
+      },
+      "Access denied": [
+        ""
+      ],
+      "Check your token is valid": [
+        ""
+      ],
+      "Couldn't access the server.": [
+        ""
+      ],
+      "Could not infer instance id from url %1$s": [
+        ""
+      ],
+      "HTTP status #%1$s: Server reported a problem": [
+        ""
+      ],
+      "Got message: \"%1$s\" from: %2$s": [
+        ""
+      ],
+      "No default instance": [
+        ""
+      ],
+      "in order to use merchant backoffice, you should create the default 
instance": [
+        ""
+      ],
+      "Server reported a problem: HTTP status #%1$s": [
+        ""
+      ],
+      "Got message: %1$s from: %2$s": [
+        ""
+      ],
+      "Login required": [
+        ""
+      ],
+      "Please enter your auth token. Token should have \"secret-token:\" and 
start with Bearer or ApiKey": [
+        ""
+      ],
+      "Confirm": [
+        ""
+      ],
+      "The value %1$s is invalid for a payment url": [
+        ""
+      ],
+      "pick a date": [
+        ""
+      ],
+      "clear": [
+        ""
+      ],
+      "never": [
+        ""
+      ],
+      "Image should be smaller than 1 MB": [
+        ""
+      ],
+      "Country": [
+        ""
+      ],
+      "Address": [
+        ""
+      ],
+      "Building number": [
+        ""
+      ],
+      "Building name": [
+        ""
+      ],
+      "Street": [
+        ""
+      ],
+      "Post code": [
+        ""
+      ],
+      "Town location": [
+        ""
+      ],
+      "Town": [
+        ""
+      ],
+      "District": [
+        ""
+      ],
+      "Country subdivision": [
+        ""
+      ],
+      "Product id": [
+        ""
+      ],
+      "Description": [
+        ""
+      ],
+      "Name": [
+        ""
+      ],
+      "loading...": [
+        ""
+      ],
+      "no products found": [
+        ""
+      ],
+      "no results": [
+        ""
+      ],
+      "Deleting": [
+        ""
+      ],
+      "Changing": [
+        ""
+      ],
+      "Manage token": [
+        ""
+      ],
+      "Update": [
+        ""
+      ],
+      "Remove": [
+        ""
+      ],
+      "Cancel": [
+        ""
+      ],
+      "Manage stock": [
+        ""
+      ],
+      "Infinite": [
+        ""
+      ],
+      "lost cannot be greater that current + incoming (max %1$s)": [
+        ""
+      ],
+      "current stock will change from %1$s to %2$s": [
+        ""
+      ],
+      "current stock will stay at %1$s": [
+        ""
+      ],
+      "Incoming": [
+        ""
+      ],
+      "Lost": [
+        ""
+      ],
+      "Current": [
+        ""
+      ],
+      "without stock": [
+        ""
+      ],
+      "Next restock": [
+        ""
+      ],
+      "Delivery address": [
+        ""
+      ],
+      "this product has no taxes": [
+        ""
+      ],
+      "Amount": [
+        ""
+      ],
+      "currency and value separated with colon": [
+        ""
+      ],
+      "Add": [
+        ""
+      ],
+      "Instance": [
+        ""
+      ],
+      "Settings": [
+        ""
+      ],
+      "Orders": [
+        ""
+      ],
+      "Products": [
+        ""
+      ],
+      "Transfers": [
+        ""
+      ],
+      "Connection": [
+        ""
+      ],
+      "Instances": [
+        ""
+      ],
+      "New": [
+        ""
+      ],
+      "List": [
+        ""
+      ],
+      "Log out": [
+        ""
+      ],
+      "Clear": [
+        ""
+      ],
+      "should be the same": [
+        ""
+      ],
+      "cannot be the same as before": [
+        ""
+      ],
+      "You are updating the authorization token from instance %1$s with id 
%2$s": [
+        ""
+      ],
+      "Old token": [
+        ""
+      ],
+      "New token": [
+        ""
+      ],
+      "Clearing the auth token will mean public access to the instance": [
+        ""
+      ],
+      "ID": [
+        ""
+      ],
+      "Image": [
+        ""
+      ],
+      "Unit": [
+        ""
+      ],
+      "Price": [
+        ""
+      ],
+      "Stock": [
+        ""
+      ],
+      "Taxes": [
+        ""
+      ],
+      "Server not found": [
+        ""
+      ],
+      "Couldn't access the server": [
+        ""
+      ],
+      "Got message %1$s from %2$s": [
+        ""
+      ],
+      "Unexpected Error": [
+        ""
+      ],
+      "Auth token": [
+        ""
+      ],
+      "Account address": [
+        ""
+      ],
+      "Default max deposit fee": [
+        ""
+      ],
+      "Default max wire fee": [
+        ""
+      ],
+      "Default wire fee amortization": [
+        ""
+      ],
+      "Jurisdiction": [
+        ""
+      ],
+      "Default pay delay": [
+        ""
+      ],
+      "Default wire transfer delay": [
+        ""
+      ],
+      "could not create instance": [
+        ""
+      ],
+      "Delete": [
+        ""
+      ],
+      "Edit": [
+        ""
+      ],
+      "There is no instances yet, add more pressing the + sign": [
+        ""
+      ],
+      "Inventory products": [
+        ""
+      ],
+      "Total price": [
+        ""
+      ],
+      "Total tax": [
+        ""
+      ],
+      "Order price": [
+        ""
+      ],
+      "Net": [
+        ""
+      ],
+      "Summary": [
+        ""
+      ],
+      "Payments options": [
+        ""
+      ],
+      "Auto refund deadline": [
+        ""
+      ],
+      "Refund deadline": [
+        ""
+      ],
+      "Pay deadline": [
+        ""
+      ],
+      "Delivery date": [
+        ""
+      ],
+      "Location": [
+        ""
+      ],
+      "Max fee": [
+        ""
+      ],
+      "Max wire fee": [
+        ""
+      ],
+      "Wire fee amortization": [
+        ""
+      ],
+      "Fullfilment url": [
+        ""
+      ],
+      "Extra information": [
+        ""
+      ],
+      "select a product first": [
+        ""
+      ],
+      "should be greater than 0": [
+        ""
+      ],
+      "cannot be greater than current stock and quantity previously added. 
max: %1$s": [
+        ""
+      ],
+      "cannot be greater than current stock %1$s": [
+        ""
+      ],
+      "Quantity": [
+        ""
+      ],
+      "Order": [
+        ""
+      ],
+      "claimed": [
+        ""
+      ],
+      "copy url": [
+        ""
+      ],
+      "pay at": [
+        ""
+      ],
+      "created at": [
+        ""
+      ],
+      "Timeline": [
+        ""
+      ],
+      "Payment details": [
+        ""
+      ],
+      "Order status": [
+        ""
+      ],
+      "Product list": [
+        ""
+      ],
+      "paid": [
+        ""
+      ],
+      "wired": [
+        ""
+      ],
+      "refunded": [
+        ""
+      ],
+      "refund": [
+        ""
+      ],
+      "Refunded amount": [
+        ""
+      ],
+      "Deposit total": [
+        ""
+      ],
+      "unpaid": [
+        ""
+      ],
+      "Order status URL": [
+        ""
+      ],
+      "Pay URI": [
+        ""
+      ],
+      "Unknown order status. This is an error, please contact the 
administrator.": [
+        ""
+      ],
+      "refund created successfully": [
+        ""
+      ],
+      "could not create the refund": [
+        ""
+      ],
+      "load newer orders": [
+        ""
+      ],
+      "Date": [
+        ""
+      ],
+      "Refund": [
+        ""
+      ],
+      "load older orders": [
+        ""
+      ],
+      "No orders has been found": [
+        ""
+      ],
+      "date": [
+        ""
+      ],
+      "amount": [
+        ""
+      ],
+      "reason": [
+        ""
+      ],
+      "Max refundable:": [
+        ""
+      ],
+      "Reason": [
+        ""
+      ],
+      "duplicated": [
+        ""
+      ],
+      "requested by the customer": [
+        ""
+      ],
+      "other": [
+        ""
+      ],
+      "go to order id": [
+        ""
+      ],
+      "Paid": [
+        ""
+      ],
+      "Refunded": [
+        ""
+      ],
+      "Not wired": [
+        ""
+      ],
+      "All": [
+        ""
+      ],
+      "could not create product": [
+        ""
+      ],
+      "Sell": [
+        ""
+      ],
+      "Profit": [
+        ""
+      ],
+      "Sold": [
+        ""
+      ],
+      "product updated successfully": [
+        ""
+      ],
+      "could not update the product": [
+        ""
+      ],
+      "product delete successfully": [
+        ""
+      ],
+      "could not delete the product": [
+        ""
+      ],
+      "Tips": [
+        ""
+      ],
+      "Committed amount": [
+        ""
+      ],
+      "Exchange initial amount": [
+        ""
+      ],
+      "Merchant initial amount": [
+        ""
+      ],
+      "There is no tips yet, add more pressing the + sign": [
+        ""
+      ],
+      "cannot be empty": [
+        ""
+      ],
+      "check the id, doest look valid": [
+        ""
+      ],
+      "should have 52 characters, current %1$s": [
+        ""
+      ],
+      "URL doesn't have the right format": [
+        ""
+      ],
+      "Transfer ID": [
+        ""
+      ],
+      "Account Address": [
+        ""
+      ],
+      "Exchange URL": [
+        ""
+      ],
+      "could not inform transfer": [
+        ""
+      ],
+      "load newer transfers": [
+        ""
+      ],
+      "Credit": [
+        ""
+      ],
+      "Confirmed": [
+        ""
+      ],
+      "Verified": [
+        ""
+      ],
+      "Executed at": [
+        ""
+      ],
+      "yes": [
+        ""
+      ],
+      "no": [
+        ""
+      ],
+      "unknown": [
+        ""
+      ],
+      "load older transfers": [
+        ""
+      ],
+      "There is no transfer yet, add more pressing the + sign": [
+        ""
+      ]
+    }
+  }
+};
+
+strings['sv'] = {
+  "domain": "messages",
+  "locale_data": {
+    "messages": {
+      "": {
+        "domain": "messages",
+        "plural_forms": "nplurals=2; plural=(n != 1);",
+        "lang": ""
+      },
+      "Access denied": [
+        ""
+      ],
+      "Check your token is valid": [
+        ""
+      ],
+      "Couldn't access the server.": [
+        ""
+      ],
+      "Could not infer instance id from url %1$s": [
+        ""
+      ],
+      "HTTP status #%1$s: Server reported a problem": [
+        ""
+      ],
+      "Got message: \"%1$s\" from: %2$s": [
+        ""
+      ],
+      "No default instance": [
+        ""
+      ],
+      "in order to use merchant backoffice, you should create the default 
instance": [
+        ""
+      ],
+      "Server reported a problem: HTTP status #%1$s": [
+        ""
+      ],
+      "Got message: %1$s from: %2$s": [
+        ""
+      ],
+      "Login required": [
+        ""
+      ],
+      "Please enter your auth token. Token should have \"secret-token:\" and 
start with Bearer or ApiKey": [
+        ""
+      ],
+      "Confirm": [
+        ""
+      ],
+      "The value %1$s is invalid for a payment url": [
+        ""
+      ],
+      "pick a date": [
+        ""
+      ],
+      "clear": [
+        ""
+      ],
+      "never": [
+        ""
+      ],
+      "Image should be smaller than 1 MB": [
+        ""
+      ],
+      "Country": [
+        ""
+      ],
+      "Address": [
+        ""
+      ],
+      "Building number": [
+        ""
+      ],
+      "Building name": [
+        ""
+      ],
+      "Street": [
+        ""
+      ],
+      "Post code": [
+        ""
+      ],
+      "Town location": [
+        ""
+      ],
+      "Town": [
+        ""
+      ],
+      "District": [
+        ""
+      ],
+      "Country subdivision": [
+        ""
+      ],
+      "Product id": [
+        ""
+      ],
+      "Description": [
+        ""
+      ],
+      "Name": [
+        ""
+      ],
+      "loading...": [
+        ""
+      ],
+      "no products found": [
+        ""
+      ],
+      "no results": [
+        ""
+      ],
+      "Deleting": [
+        ""
+      ],
+      "Changing": [
+        ""
+      ],
+      "Manage token": [
+        ""
+      ],
+      "Update": [
+        ""
+      ],
+      "Remove": [
+        ""
+      ],
+      "Cancel": [
+        ""
+      ],
+      "Manage stock": [
+        ""
+      ],
+      "Infinite": [
+        ""
+      ],
+      "lost cannot be greater that current + incoming (max %1$s)": [
+        ""
+      ],
+      "current stock will change from %1$s to %2$s": [
+        ""
+      ],
+      "current stock will stay at %1$s": [
+        ""
+      ],
+      "Incoming": [
+        ""
+      ],
+      "Lost": [
+        ""
+      ],
+      "Current": [
+        ""
+      ],
+      "without stock": [
+        ""
+      ],
+      "Next restock": [
+        ""
+      ],
+      "Delivery address": [
+        ""
+      ],
+      "this product has no taxes": [
+        ""
+      ],
+      "Amount": [
+        ""
+      ],
+      "currency and value separated with colon": [
+        ""
+      ],
+      "Add": [
+        ""
+      ],
+      "Instance": [
+        ""
+      ],
+      "Settings": [
+        ""
+      ],
+      "Orders": [
+        ""
+      ],
+      "Products": [
+        ""
+      ],
+      "Transfers": [
+        ""
+      ],
+      "Connection": [
+        ""
+      ],
+      "Instances": [
+        ""
+      ],
+      "New": [
+        ""
+      ],
+      "List": [
+        ""
+      ],
+      "Log out": [
+        ""
+      ],
+      "Clear": [
+        ""
+      ],
+      "should be the same": [
+        ""
+      ],
+      "cannot be the same as before": [
+        ""
+      ],
+      "You are updating the authorization token from instance %1$s with id 
%2$s": [
+        ""
+      ],
+      "Old token": [
+        ""
+      ],
+      "New token": [
+        ""
+      ],
+      "Clearing the auth token will mean public access to the instance": [
+        ""
+      ],
+      "ID": [
+        ""
+      ],
+      "Image": [
+        ""
+      ],
+      "Unit": [
+        ""
+      ],
+      "Price": [
+        ""
+      ],
+      "Stock": [
+        ""
+      ],
+      "Taxes": [
+        ""
+      ],
+      "Server not found": [
+        ""
+      ],
+      "Couldn't access the server": [
+        ""
+      ],
+      "Got message %1$s from %2$s": [
+        ""
+      ],
+      "Unexpected Error": [
+        ""
+      ],
+      "Auth token": [
+        ""
+      ],
+      "Account address": [
+        ""
+      ],
+      "Default max deposit fee": [
+        ""
+      ],
+      "Default max wire fee": [
+        ""
+      ],
+      "Default wire fee amortization": [
+        ""
+      ],
+      "Jurisdiction": [
+        ""
+      ],
+      "Default pay delay": [
+        ""
+      ],
+      "Default wire transfer delay": [
+        ""
+      ],
+      "could not create instance": [
+        ""
+      ],
+      "Delete": [
+        ""
+      ],
+      "Edit": [
+        ""
+      ],
+      "There is no instances yet, add more pressing the + sign": [
+        ""
+      ],
+      "Inventory products": [
+        ""
+      ],
+      "Total price": [
+        ""
+      ],
+      "Total tax": [
+        ""
+      ],
+      "Order price": [
+        ""
+      ],
+      "Net": [
+        ""
+      ],
+      "Summary": [
+        ""
+      ],
+      "Payments options": [
+        ""
+      ],
+      "Auto refund deadline": [
+        ""
+      ],
+      "Refund deadline": [
+        ""
+      ],
+      "Pay deadline": [
+        ""
+      ],
+      "Delivery date": [
+        ""
+      ],
+      "Location": [
+        ""
+      ],
+      "Max fee": [
+        ""
+      ],
+      "Max wire fee": [
+        ""
+      ],
+      "Wire fee amortization": [
+        ""
+      ],
+      "Fullfilment url": [
+        ""
+      ],
+      "Extra information": [
+        ""
+      ],
+      "select a product first": [
+        ""
+      ],
+      "should be greater than 0": [
+        ""
+      ],
+      "cannot be greater than current stock and quantity previously added. 
max: %1$s": [
+        ""
+      ],
+      "cannot be greater than current stock %1$s": [
+        ""
+      ],
+      "Quantity": [
+        ""
+      ],
+      "Order": [
+        ""
+      ],
+      "claimed": [
+        ""
+      ],
+      "copy url": [
+        ""
+      ],
+      "pay at": [
+        ""
+      ],
+      "created at": [
+        ""
+      ],
+      "Timeline": [
+        ""
+      ],
+      "Payment details": [
+        ""
+      ],
+      "Order status": [
+        ""
+      ],
+      "Product list": [
+        ""
+      ],
+      "paid": [
+        ""
+      ],
+      "wired": [
+        ""
+      ],
+      "refunded": [
+        ""
+      ],
+      "refund": [
+        ""
+      ],
+      "Refunded amount": [
+        ""
+      ],
+      "Deposit total": [
+        ""
+      ],
+      "unpaid": [
+        ""
+      ],
+      "Order status URL": [
+        ""
+      ],
+      "Pay URI": [
+        ""
+      ],
+      "Unknown order status. This is an error, please contact the 
administrator.": [
+        ""
+      ],
+      "refund created successfully": [
+        ""
+      ],
+      "could not create the refund": [
+        ""
+      ],
+      "load newer orders": [
+        ""
+      ],
+      "Date": [
+        ""
+      ],
+      "Refund": [
+        ""
+      ],
+      "load older orders": [
+        ""
+      ],
+      "No orders has been found": [
+        ""
+      ],
+      "date": [
+        ""
+      ],
+      "amount": [
+        ""
+      ],
+      "reason": [
+        ""
+      ],
+      "Max refundable:": [
+        ""
+      ],
+      "Reason": [
+        ""
+      ],
+      "duplicated": [
+        ""
+      ],
+      "requested by the customer": [
+        ""
+      ],
+      "other": [
+        ""
+      ],
+      "go to order id": [
+        ""
+      ],
+      "Paid": [
+        ""
+      ],
+      "Refunded": [
+        ""
+      ],
+      "Not wired": [
+        ""
+      ],
+      "All": [
+        ""
+      ],
+      "could not create product": [
+        ""
+      ],
+      "Sell": [
+        ""
+      ],
+      "Profit": [
+        ""
+      ],
+      "Sold": [
+        ""
+      ],
+      "product updated successfully": [
+        ""
+      ],
+      "could not update the product": [
+        ""
+      ],
+      "product delete successfully": [
+        ""
+      ],
+      "could not delete the product": [
+        ""
+      ],
+      "Tips": [
+        ""
+      ],
+      "Committed amount": [
+        ""
+      ],
+      "Exchange initial amount": [
+        ""
+      ],
+      "Merchant initial amount": [
+        ""
+      ],
+      "There is no tips yet, add more pressing the + sign": [
+        ""
+      ],
+      "cannot be empty": [
+        ""
+      ],
+      "check the id, doest look valid": [
+        ""
+      ],
+      "should have 52 characters, current %1$s": [
+        ""
+      ],
+      "URL doesn't have the right format": [
+        ""
+      ],
+      "Transfer ID": [
+        ""
+      ],
+      "Account Address": [
+        ""
+      ],
+      "Exchange URL": [
+        ""
+      ],
+      "could not inform transfer": [
+        ""
+      ],
+      "load newer transfers": [
+        ""
+      ],
+      "Credit": [
+        ""
+      ],
+      "Confirmed": [
+        ""
+      ],
+      "Verified": [
+        ""
+      ],
+      "Executed at": [
+        ""
+      ],
+      "yes": [
+        ""
+      ],
+      "no": [
+        ""
+      ],
+      "unknown": [
+        ""
+      ],
+      "load older transfers": [
+        ""
+      ],
+      "There is no transfer yet, add more pressing the + sign": [
+        ""
+      ]
+    }
+  }
+};
+
diff --git a/packages/merchant-backend-ui/src/i18n/sv.po 
b/packages/merchant-backend-ui/src/i18n/sv.po
new file mode 100644
index 000000000..6b35bd0ce
--- /dev/null
+++ b/packages/merchant-backend-ui/src/i18n/sv.po
@@ -0,0 +1,1057 @@
+# This file is part of TALER
+# (C) 2016 GNUnet e.V.
+#
+# TALER is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3, or (at your option) any later version.
+#
+# TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Taler Wallet\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2016-11-23 00:00+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: src/ApplicationReadyRoutes.tsx:50 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:299
+#, c-format
+msgid "Access denied"
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:51 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:300
+#, c-format
+msgid "Check your token is valid"
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:72
+#, c-format
+msgid "Couldn't access the server."
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:73
+#, c-format
+msgid "Could not infer instance id from url %1$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:109
+#, c-format
+msgid "HTTP status #%1$s: Server reported a problem"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:110
+#, c-format
+msgid "Got message: \"%1$s\" from: %2$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:127
+#, c-format
+msgid "No default instance"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:128
+#, c-format
+msgid ""
+"in order to use merchant backoffice, you should create the default instance"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:288
+#, c-format
+msgid "Server reported a problem: HTTP status #%1$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:289
+#, c-format
+msgid "Got message: %1$s from: %2$s"
+msgstr ""
+
+#: src/components/exception/login.tsx:46
+#, c-format
+msgid "Login required"
+msgstr ""
+
+#: src/components/exception/login.tsx:49
+#, c-format
+msgid ""
+"Please enter your auth token. Token should have \"secret-token:\" and start "
+"with Bearer or ApiKey"
+msgstr ""
+
+#: src/components/exception/login.tsx:86 src/components/modal/index.tsx:53
+#: src/components/modal/index.tsx:75 src/paths/admin/create/CreatePage.tsx:115
+#: src/paths/instance/orders/create/CreatePage.tsx:325
+#: src/paths/instance/products/create/CreatePage.tsx:51
+#: src/paths/instance/products/list/Table.tsx:174
+#: src/paths/instance/products/list/Table.tsx:228
+#: src/paths/instance/products/update/UpdatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:134
+#, c-format
+msgid "Confirm"
+msgstr ""
+
+#: src/components/form/InputArray.tsx:72
+#, c-format
+msgid "The value %1$s is invalid for a payment url"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:67
+#: src/paths/instance/orders/list/index.tsx:123
+#, c-format
+msgid "pick a date"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:81
+#, c-format
+msgid "clear"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:83
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "never"
+msgstr ""
+
+#: src/components/form/InputImage.tsx:80
+#, c-format
+msgid "Image should be smaller than 1 MB"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:28
+#, c-format
+msgid "Country"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:30
+#: src/paths/admin/create/CreatePage.tsx:99
+#: src/paths/instance/transfers/list/Table.tsx:124
+#: src/paths/instance/update/UpdatePage.tsx:118
+#, c-format
+msgid "Address"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:34
+#, c-format
+msgid "Building number"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:35
+#, c-format
+msgid "Building name"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:36
+#, c-format
+msgid "Street"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:37
+#, c-format
+msgid "Post code"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:38
+#, c-format
+msgid "Town location"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:39
+#, c-format
+msgid "Town"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:40
+#, c-format
+msgid "District"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:41
+#, c-format
+msgid "Country subdivision"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:59
+#, c-format
+msgid "Product id"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:60
+#: src/components/product/ProductForm.tsx:99
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:122
+#: src/paths/instance/orders/list/Table.tsx:227
+#: src/paths/instance/products/list/Table.tsx:86
+#, c-format
+msgid "Description"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:73
+#: src/components/form/InputTaxes.tsx:81
+#: src/paths/admin/create/CreatePage.tsx:87 src/paths/admin/list/Table.tsx:110
+#: src/paths/instance/details/DetailPage.tsx:76
+#: src/paths/instance/update/UpdatePage.tsx:106
+#, c-format
+msgid "Name"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:102
+#, c-format
+msgid "loading..."
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:108
+#, c-format
+msgid "no products found"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:116
+#, c-format
+msgid "no results"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:33
+#, c-format
+msgid "Deleting"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:34
+#, c-format
+msgid "Changing"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:60
+#, c-format
+msgid "Manage token"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:83
+#, c-format
+msgid "Update"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:100
+#: src/paths/instance/orders/create/CreatePage.tsx:252
+#: src/paths/instance/orders/create/CreatePage.tsx:273
+#, c-format
+msgid "Remove"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:106 src/components/modal/index.tsx:52
+#: src/components/modal/index.tsx:73 src/paths/admin/create/CreatePage.tsx:114
+#: src/paths/instance/orders/create/CreatePage.tsx:324
+#: src/paths/instance/products/create/CreatePage.tsx:50
+#: src/paths/instance/products/list/Table.tsx:166
+#: src/paths/instance/products/list/Table.tsx:218
+#: src/paths/instance/products/update/UpdatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:88
+#: src/paths/instance/update/UpdatePage.tsx:133
+#, c-format
+msgid "Cancel"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:91
+#, c-format
+msgid "Manage stock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:93
+#, c-format
+msgid "Infinite"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:105
+#, c-format
+msgid "lost cannot be greater that current + incoming (max %1$s)"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:111
+#, c-format
+msgid "current stock will change from %1$s to %2$s"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:112
+#, c-format
+msgid "current stock will stay at %1$s"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:129
+#: src/paths/instance/products/list/Table.tsx:204
+#, c-format
+msgid "Incoming"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:130
+#: src/paths/instance/products/list/Table.tsx:205
+#, c-format
+msgid "Lost"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:142
+#, c-format
+msgid "Current"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:145
+#, c-format
+msgid "without stock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:150
+#, c-format
+msgid "Next restock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:152
+#, c-format
+msgid "Delivery address"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:73
+#, c-format
+msgid "this product has no taxes"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:77
+#: src/paths/instance/orders/details/DetailPage.tsx:145
+#: src/paths/instance/orders/details/DetailPage.tsx:296
+#: src/paths/instance/orders/list/Table.tsx:116
+#: src/paths/instance/transfers/create/CreatePage.tsx:84
+#, c-format
+msgid "Amount"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:78
+#, c-format
+msgid "currency and value separated with colon"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:84
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:78
+#, c-format
+msgid "Add"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:53
+#, c-format
+msgid "Instance"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:59
+#, c-format
+msgid "Settings"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:65
+#: src/paths/instance/orders/list/Table.tsx:60
+#, c-format
+msgid "Orders"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:71
+#: src/paths/instance/orders/create/CreatePage.tsx:258
+#: src/paths/instance/products/list/Table.tsx:48
+#, c-format
+msgid "Products"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:77
+#: src/paths/instance/transfers/list/Table.tsx:65
+#, c-format
+msgid "Transfers"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:87
+#, c-format
+msgid "Connection"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:112 src/paths/admin/list/Table.tsx:57
+#, c-format
+msgid "Instances"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:116
+#, c-format
+msgid "New"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:122
+#, c-format
+msgid "List"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:129
+#, c-format
+msgid "Log out"
+msgstr ""
+
+#: src/components/modal/index.tsx:74
+#, c-format
+msgid "Clear"
+msgstr ""
+
+#: src/components/modal/index.tsx:110 src/components/modal/index.tsx:111
+#, c-format
+msgid "should be the same"
+msgstr ""
+
+#: src/components/modal/index.tsx:111
+#, c-format
+msgid "cannot be the same as before"
+msgstr ""
+
+#: src/components/modal/index.tsx:114
+#, c-format
+msgid ""
+"You are updating the authorization token from instance %1$s with id %2$s"
+msgstr ""
+
+#: src/components/modal/index.tsx:124
+#, c-format
+msgid "Old token"
+msgstr ""
+
+#: src/components/modal/index.tsx:125
+#, c-format
+msgid "New token"
+msgstr ""
+
+#: src/components/modal/index.tsx:127
+#, c-format
+msgid "Clearing the auth token will mean public access to the instance"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:96
+#: src/paths/admin/create/CreatePage.tsx:85 src/paths/admin/list/Table.tsx:109
+#: src/paths/instance/transfers/list/Table.tsx:122
+#, c-format
+msgid "ID"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:98
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:121
+#: src/paths/instance/products/list/Table.tsx:85
+#, c-format
+msgid "Image"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:100
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:123
+#, c-format
+msgid "Unit"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:101
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:124
+#: src/paths/instance/products/list/Table.tsx:162
+#: src/paths/instance/products/list/Table.tsx:214
+#, c-format
+msgid "Price"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:103
+#: src/paths/instance/products/list/Table.tsx:90
+#, c-format
+msgid "Stock"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:105
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:128
+#: src/paths/instance/products/list/Table.tsx:88
+#, c-format
+msgid "Taxes"
+msgstr ""
+
+#: src/index.tsx:75
+#, c-format
+msgid "Server not found"
+msgstr ""
+
+#: src/index.tsx:85
+#, c-format
+msgid "Couldn't access the server"
+msgstr ""
+
+#: src/index.tsx:87 src/index.tsx:99
+#, c-format
+msgid "Got message %1$s from %2$s"
+msgstr ""
+
+#: src/index.tsx:97
+#, c-format
+msgid "Unexpected Error"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:108
+#, c-format
+msgid "Auth token"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:91
+#: src/paths/instance/details/DetailPage.tsx:77
+#: src/paths/instance/update/UpdatePage.tsx:110
+#, c-format
+msgid "Account address"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:93
+#: src/paths/instance/update/UpdatePage.tsx:112
+#, c-format
+msgid "Default max deposit fee"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:95
+#: src/paths/instance/update/UpdatePage.tsx:114
+#, c-format
+msgid "Default max wire fee"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:97
+#: src/paths/instance/update/UpdatePage.tsx:116
+#, c-format
+msgid "Default wire fee amortization"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:103
+#: src/paths/instance/update/UpdatePage.tsx:122
+#, c-format
+msgid "Jurisdiction"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:107
+#: src/paths/instance/update/UpdatePage.tsx:126
+#, c-format
+msgid "Default pay delay"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:109
+#: src/paths/instance/update/UpdatePage.tsx:128
+#, c-format
+msgid "Default wire transfer delay"
+msgstr ""
+
+#: src/paths/admin/create/index.tsx:58
+#, c-format
+msgid "could not create instance"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:63 src/paths/admin/list/Table.tsx:131
+#: src/paths/instance/transfers/list/Table.tsx:71
+#, c-format
+msgid "Delete"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:128
+#, c-format
+msgid "Edit"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:149
+#: src/paths/instance/products/list/Table.tsx:245
+#, c-format
+msgid "There is no instances yet, add more pressing the + sign"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:237
+#, c-format
+msgid "Inventory products"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:286
+#, c-format
+msgid "Total price"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:287
+#, c-format
+msgid "Total tax"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:289
+#: src/paths/instance/orders/create/CreatePage.tsx:297
+#, c-format
+msgid "Order price"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:295
+#, c-format
+msgid "Net"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:300
+#: src/paths/instance/orders/details/DetailPage.tsx:144
+#: src/paths/instance/orders/details/DetailPage.tsx:295
+#: src/paths/instance/orders/list/Table.tsx:117
+#, c-format
+msgid "Summary"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:302
+#, c-format
+msgid "Payments options"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:303
+#, c-format
+msgid "Auto refund deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:304
+#, c-format
+msgid "Refund deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:305
+#, c-format
+msgid "Pay deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:307
+#, c-format
+msgid "Delivery date"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:308
+#, c-format
+msgid "Location"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:312
+#, c-format
+msgid "Max fee"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:313
+#, c-format
+msgid "Max wire fee"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:314
+#, c-format
+msgid "Wire fee amortization"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:315
+#, c-format
+msgid "Fullfilment url"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:318
+#, c-format
+msgid "Extra information"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:44
+#, c-format
+msgid "select a product first"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:51
+#, c-format
+msgid "should be greater than 0"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:58
+#, c-format
+msgid ""
+"cannot be greater than current stock and quantity previously added. max: %1$s"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:64
+#, c-format
+msgid "cannot be greater than current stock %1$s"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:76
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:126
+#, c-format
+msgid "Quantity"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:92
+#: src/paths/instance/orders/details/DetailPage.tsx:235
+#: src/paths/instance/orders/details/DetailPage.tsx:333
+#, c-format
+msgid "Order"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:93
+#, c-format
+msgid "claimed"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:110
+#: src/paths/instance/orders/details/DetailPage.tsx:261
+#: src/paths/instance/orders/list/Table.tsx:136
+#, c-format
+msgid "copy url"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:126
+#: src/paths/instance/orders/details/DetailPage.tsx:349
+#, c-format
+msgid "pay at"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:127
+#: src/paths/instance/orders/details/DetailPage.tsx:350
+#, c-format
+msgid "created at"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:138
+#: src/paths/instance/orders/details/DetailPage.tsx:289
+#, c-format
+msgid "Timeline"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:142
+#: src/paths/instance/orders/details/DetailPage.tsx:293
+#, c-format
+msgid "Payment details"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:146
+#: src/paths/instance/orders/details/DetailPage.tsx:299
+#: src/paths/instance/orders/details/DetailPage.tsx:363
+#, c-format
+msgid "Order status"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:156
+#: src/paths/instance/orders/details/DetailPage.tsx:308
+#, c-format
+msgid "Product list"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:236
+#, c-format
+msgid "paid"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:238
+#, c-format
+msgid "wired"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:241
+#, c-format
+msgid "refunded"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:258
+#, c-format
+msgid "refund"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:297
+#, c-format
+msgid "Refunded amount"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:298
+#, c-format
+msgid "Deposit total"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:336
+#, c-format
+msgid "unpaid"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:364
+#, c-format
+msgid "Order status URL"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:365
+#, c-format
+msgid "Pay URI"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:383
+#, c-format
+msgid ""
+"Unknown order status. This is an error, please contact the administrator."
+msgstr ""
+
+#: src/paths/instance/orders/details/index.tsx:56
+#: src/paths/instance/orders/list/index.tsx:147
+#, c-format
+msgid "refund created successfully"
+msgstr ""
+
+#: src/paths/instance/orders/details/index.tsx:59
+#: src/paths/instance/orders/list/index.tsx:150
+#, c-format
+msgid "could not create the refund"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:111
+#, c-format
+msgid "load newer orders"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:115
+#, c-format
+msgid "Date"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:131
+#: src/paths/instance/orders/list/Table.tsx:223
+#, c-format
+msgid "Refund"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:145
+#, c-format
+msgid "load older orders"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:154
+#, c-format
+msgid "No orders has been found"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:202
+#, c-format
+msgid "date"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:203
+#, c-format
+msgid "amount"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:204
+#, c-format
+msgid "reason"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:224
+#, c-format
+msgid "Max refundable:"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "Reason"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "duplicated"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "requested by the customer"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "other"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:91
+#, c-format
+msgid "go to order id"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:107
+#, c-format
+msgid "Paid"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:108
+#, c-format
+msgid "Refunded"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:109
+#, c-format
+msgid "Not wired"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:110
+#, c-format
+msgid "All"
+msgstr ""
+
+#: src/paths/instance/products/create/index.tsx:48
+#: src/paths/instance/products/update/index.tsx:64
+#, c-format
+msgid "could not create product"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:87
+#, c-format
+msgid "Sell"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:89
+#, c-format
+msgid "Profit"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:91
+#, c-format
+msgid "Sold"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:59
+#, c-format
+msgid "product updated successfully"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:62
+#, c-format
+msgid "could not update the product"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:70
+#, c-format
+msgid "product delete successfully"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:73
+#, c-format
+msgid "could not delete the product"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:59
+#, c-format
+msgid "Tips"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:111
+#, c-format
+msgid "Committed amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:112
+#, c-format
+msgid "Exchange initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:113
+#, c-format
+msgid "Merchant initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:148
+#, c-format
+msgid "There is no tips yet, add more pressing the + sign"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:50
+#: src/paths/instance/transfers/create/CreatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:56
+#, c-format
+msgid "cannot be empty"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:51
+#, c-format
+msgid "check the id, doest look valid"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:52
+#, c-format
+msgid "should have 52 characters, current %1$s"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:57
+#, c-format
+msgid "URL doesn't have the right format"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:74
+#, c-format
+msgid "Transfer ID"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:76
+#, c-format
+msgid "Account Address"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:82
+#: src/paths/instance/transfers/list/Table.tsx:125
+#, c-format
+msgid "Exchange URL"
+msgstr ""
+
+#: src/paths/instance/transfers/create/index.tsx:49
+#, c-format
+msgid "could not inform transfer"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:118
+#, c-format
+msgid "load newer transfers"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:123
+#, c-format
+msgid "Credit"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:126
+#, c-format
+msgid "Confirmed"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:127
+#: src/paths/instance/transfers/list/index.tsx:60
+#, c-format
+msgid "Verified"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:128
+#, c-format
+msgid "Executed at"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "yes"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "no"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "unknown"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:145
+#, c-format
+msgid "load older transfers"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:154
+#, c-format
+msgid "There is no transfer yet, add more pressing the + sign"
+msgstr ""
diff --git 
a/packages/merchant-backend-ui/src/i18n/taler-merchant-backoffice.pot 
b/packages/merchant-backend-ui/src/i18n/taler-merchant-backoffice.pot
new file mode 100644
index 000000000..21fd863b0
--- /dev/null
+++ b/packages/merchant-backend-ui/src/i18n/taler-merchant-backoffice.pot
@@ -0,0 +1,1054 @@
+#  This file is part of GNU Taler
+#  (C) 2021 Taler Systems S.A.
+#  GNU Taler is free software; you can redistribute it and/or modify it under 
the
+#  terms of the GNU General Public License as published by the Free Software
+#  Foundation; either version 3, or (at your option) any later version.
+#  GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+#  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+#  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#  You should have received a copy of the GNU General Public License along with
+#  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Taler Wallet\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2016-11-23 00:00+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: src/ApplicationReadyRoutes.tsx:50 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:299
+#, c-format
+msgid "Access denied"
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:51 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:300
+#, c-format
+msgid "Check your token is valid"
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:72
+#, c-format
+msgid "Couldn't access the server."
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:73
+#, c-format
+msgid "Could not infer instance id from url %1$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:109
+#, c-format
+msgid "HTTP status #%1$s: Server reported a problem"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:110
+#, c-format
+msgid "Got message: \"%1$s\" from: %2$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:127
+#, c-format
+msgid "No default instance"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:128
+#, c-format
+msgid ""
+"in order to use merchant backoffice, you should create the default instance"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:288
+#, c-format
+msgid "Server reported a problem: HTTP status #%1$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:289
+#, c-format
+msgid "Got message: %1$s from: %2$s"
+msgstr ""
+
+#: src/components/exception/login.tsx:46
+#, c-format
+msgid "Login required"
+msgstr ""
+
+#: src/components/exception/login.tsx:49
+#, c-format
+msgid ""
+"Please enter your auth token. Token should have \"secret-token:\" and start "
+"with Bearer or ApiKey"
+msgstr ""
+
+#: src/components/exception/login.tsx:86 src/components/modal/index.tsx:53
+#: src/components/modal/index.tsx:75 src/paths/admin/create/CreatePage.tsx:115
+#: src/paths/instance/orders/create/CreatePage.tsx:325
+#: src/paths/instance/products/create/CreatePage.tsx:51
+#: src/paths/instance/products/list/Table.tsx:174
+#: src/paths/instance/products/list/Table.tsx:228
+#: src/paths/instance/products/update/UpdatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:134
+#, c-format
+msgid "Confirm"
+msgstr ""
+
+#: src/components/form/InputArray.tsx:72
+#, c-format
+msgid "The value %1$s is invalid for a payment url"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:67
+#: src/paths/instance/orders/list/index.tsx:123
+#, c-format
+msgid "pick a date"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:81
+#, c-format
+msgid "clear"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:83
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "never"
+msgstr ""
+
+#: src/components/form/InputImage.tsx:80
+#, c-format
+msgid "Image should be smaller than 1 MB"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:28
+#, c-format
+msgid "Country"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:30
+#: src/paths/admin/create/CreatePage.tsx:99
+#: src/paths/instance/transfers/list/Table.tsx:124
+#: src/paths/instance/update/UpdatePage.tsx:118
+#, c-format
+msgid "Address"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:34
+#, c-format
+msgid "Building number"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:35
+#, c-format
+msgid "Building name"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:36
+#, c-format
+msgid "Street"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:37
+#, c-format
+msgid "Post code"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:38
+#, c-format
+msgid "Town location"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:39
+#, c-format
+msgid "Town"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:40
+#, c-format
+msgid "District"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:41
+#, c-format
+msgid "Country subdivision"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:59
+#, c-format
+msgid "Product id"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:60
+#: src/components/product/ProductForm.tsx:99
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:122
+#: src/paths/instance/orders/list/Table.tsx:227
+#: src/paths/instance/products/list/Table.tsx:86
+#, c-format
+msgid "Description"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:73
+#: src/components/form/InputTaxes.tsx:81
+#: src/paths/admin/create/CreatePage.tsx:87 src/paths/admin/list/Table.tsx:110
+#: src/paths/instance/details/DetailPage.tsx:76
+#: src/paths/instance/update/UpdatePage.tsx:106
+#, c-format
+msgid "Name"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:102
+#, c-format
+msgid "loading..."
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:108
+#, c-format
+msgid "no products found"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:116
+#, c-format
+msgid "no results"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:33
+#, c-format
+msgid "Deleting"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:34
+#, c-format
+msgid "Changing"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:60
+#, c-format
+msgid "Manage token"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:83
+#, c-format
+msgid "Update"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:100
+#: src/paths/instance/orders/create/CreatePage.tsx:252
+#: src/paths/instance/orders/create/CreatePage.tsx:273
+#, c-format
+msgid "Remove"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:106 src/components/modal/index.tsx:52
+#: src/components/modal/index.tsx:73 src/paths/admin/create/CreatePage.tsx:114
+#: src/paths/instance/orders/create/CreatePage.tsx:324
+#: src/paths/instance/products/create/CreatePage.tsx:50
+#: src/paths/instance/products/list/Table.tsx:166
+#: src/paths/instance/products/list/Table.tsx:218
+#: src/paths/instance/products/update/UpdatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:88
+#: src/paths/instance/update/UpdatePage.tsx:133
+#, c-format
+msgid "Cancel"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:91
+#, c-format
+msgid "Manage stock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:93
+#, c-format
+msgid "Infinite"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:105
+#, c-format
+msgid "lost cannot be greater that current + incoming (max %1$s)"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:111
+#, c-format
+msgid "current stock will change from %1$s to %2$s"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:112
+#, c-format
+msgid "current stock will stay at %1$s"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:129
+#: src/paths/instance/products/list/Table.tsx:204
+#, c-format
+msgid "Incoming"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:130
+#: src/paths/instance/products/list/Table.tsx:205
+#, c-format
+msgid "Lost"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:142
+#, c-format
+msgid "Current"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:145
+#, c-format
+msgid "without stock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:150
+#, c-format
+msgid "Next restock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:152
+#, c-format
+msgid "Delivery address"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:73
+#, c-format
+msgid "this product has no taxes"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:77
+#: src/paths/instance/orders/details/DetailPage.tsx:145
+#: src/paths/instance/orders/details/DetailPage.tsx:296
+#: src/paths/instance/orders/list/Table.tsx:116
+#: src/paths/instance/transfers/create/CreatePage.tsx:84
+#, c-format
+msgid "Amount"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:78
+#, c-format
+msgid "currency and value separated with colon"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:84
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:78
+#, c-format
+msgid "Add"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:53
+#, c-format
+msgid "Instance"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:59
+#, c-format
+msgid "Settings"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:65
+#: src/paths/instance/orders/list/Table.tsx:60
+#, c-format
+msgid "Orders"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:71
+#: src/paths/instance/orders/create/CreatePage.tsx:258
+#: src/paths/instance/products/list/Table.tsx:48
+#, c-format
+msgid "Products"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:77
+#: src/paths/instance/transfers/list/Table.tsx:65
+#, c-format
+msgid "Transfers"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:87
+#, c-format
+msgid "Connection"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:112 src/paths/admin/list/Table.tsx:57
+#, c-format
+msgid "Instances"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:116
+#, c-format
+msgid "New"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:122
+#, c-format
+msgid "List"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:129
+#, c-format
+msgid "Log out"
+msgstr ""
+
+#: src/components/modal/index.tsx:74
+#, c-format
+msgid "Clear"
+msgstr ""
+
+#: src/components/modal/index.tsx:110 src/components/modal/index.tsx:111
+#, c-format
+msgid "should be the same"
+msgstr ""
+
+#: src/components/modal/index.tsx:111
+#, c-format
+msgid "cannot be the same as before"
+msgstr ""
+
+#: src/components/modal/index.tsx:114
+#, c-format
+msgid ""
+"You are updating the authorization token from instance %1$s with id %2$s"
+msgstr ""
+
+#: src/components/modal/index.tsx:124
+#, c-format
+msgid "Old token"
+msgstr ""
+
+#: src/components/modal/index.tsx:125
+#, c-format
+msgid "New token"
+msgstr ""
+
+#: src/components/modal/index.tsx:127
+#, c-format
+msgid "Clearing the auth token will mean public access to the instance"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:96
+#: src/paths/admin/create/CreatePage.tsx:85 src/paths/admin/list/Table.tsx:109
+#: src/paths/instance/transfers/list/Table.tsx:122
+#, c-format
+msgid "ID"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:98
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:121
+#: src/paths/instance/products/list/Table.tsx:85
+#, c-format
+msgid "Image"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:100
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:123
+#, c-format
+msgid "Unit"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:101
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:124
+#: src/paths/instance/products/list/Table.tsx:162
+#: src/paths/instance/products/list/Table.tsx:214
+#, c-format
+msgid "Price"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:103
+#: src/paths/instance/products/list/Table.tsx:90
+#, c-format
+msgid "Stock"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:105
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:128
+#: src/paths/instance/products/list/Table.tsx:88
+#, c-format
+msgid "Taxes"
+msgstr ""
+
+#: src/index.tsx:75
+#, c-format
+msgid "Server not found"
+msgstr ""
+
+#: src/index.tsx:85
+#, c-format
+msgid "Couldn't access the server"
+msgstr ""
+
+#: src/index.tsx:87 src/index.tsx:99
+#, c-format
+msgid "Got message %1$s from %2$s"
+msgstr ""
+
+#: src/index.tsx:97
+#, c-format
+msgid "Unexpected Error"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:108
+#, c-format
+msgid "Auth token"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:91
+#: src/paths/instance/details/DetailPage.tsx:77
+#: src/paths/instance/update/UpdatePage.tsx:110
+#, c-format
+msgid "Account address"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:93
+#: src/paths/instance/update/UpdatePage.tsx:112
+#, c-format
+msgid "Default max deposit fee"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:95
+#: src/paths/instance/update/UpdatePage.tsx:114
+#, c-format
+msgid "Default max wire fee"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:97
+#: src/paths/instance/update/UpdatePage.tsx:116
+#, c-format
+msgid "Default wire fee amortization"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:103
+#: src/paths/instance/update/UpdatePage.tsx:122
+#, c-format
+msgid "Jurisdiction"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:107
+#: src/paths/instance/update/UpdatePage.tsx:126
+#, c-format
+msgid "Default pay delay"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:109
+#: src/paths/instance/update/UpdatePage.tsx:128
+#, c-format
+msgid "Default wire transfer delay"
+msgstr ""
+
+#: src/paths/admin/create/index.tsx:58
+#, c-format
+msgid "could not create instance"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:63 src/paths/admin/list/Table.tsx:131
+#: src/paths/instance/transfers/list/Table.tsx:71
+#, c-format
+msgid "Delete"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:128
+#, c-format
+msgid "Edit"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:149
+#: src/paths/instance/products/list/Table.tsx:245
+#, c-format
+msgid "There is no instances yet, add more pressing the + sign"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:237
+#, c-format
+msgid "Inventory products"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:286
+#, c-format
+msgid "Total price"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:287
+#, c-format
+msgid "Total tax"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:289
+#: src/paths/instance/orders/create/CreatePage.tsx:297
+#, c-format
+msgid "Order price"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:295
+#, c-format
+msgid "Net"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:300
+#: src/paths/instance/orders/details/DetailPage.tsx:144
+#: src/paths/instance/orders/details/DetailPage.tsx:295
+#: src/paths/instance/orders/list/Table.tsx:117
+#, c-format
+msgid "Summary"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:302
+#, c-format
+msgid "Payments options"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:303
+#, c-format
+msgid "Auto refund deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:304
+#, c-format
+msgid "Refund deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:305
+#, c-format
+msgid "Pay deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:307
+#, c-format
+msgid "Delivery date"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:308
+#, c-format
+msgid "Location"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:312
+#, c-format
+msgid "Max fee"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:313
+#, c-format
+msgid "Max wire fee"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:314
+#, c-format
+msgid "Wire fee amortization"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:315
+#, c-format
+msgid "Fullfilment url"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:318
+#, c-format
+msgid "Extra information"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:44
+#, c-format
+msgid "select a product first"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:51
+#, c-format
+msgid "should be greater than 0"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:58
+#, c-format
+msgid ""
+"cannot be greater than current stock and quantity previously added. max: %1$s"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:64
+#, c-format
+msgid "cannot be greater than current stock %1$s"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:76
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:126
+#, c-format
+msgid "Quantity"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:92
+#: src/paths/instance/orders/details/DetailPage.tsx:235
+#: src/paths/instance/orders/details/DetailPage.tsx:333
+#, c-format
+msgid "Order"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:93
+#, c-format
+msgid "claimed"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:110
+#: src/paths/instance/orders/details/DetailPage.tsx:261
+#: src/paths/instance/orders/list/Table.tsx:136
+#, c-format
+msgid "copy url"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:126
+#: src/paths/instance/orders/details/DetailPage.tsx:349
+#, c-format
+msgid "pay at"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:127
+#: src/paths/instance/orders/details/DetailPage.tsx:350
+#, c-format
+msgid "created at"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:138
+#: src/paths/instance/orders/details/DetailPage.tsx:289
+#, c-format
+msgid "Timeline"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:142
+#: src/paths/instance/orders/details/DetailPage.tsx:293
+#, c-format
+msgid "Payment details"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:146
+#: src/paths/instance/orders/details/DetailPage.tsx:299
+#: src/paths/instance/orders/details/DetailPage.tsx:363
+#, c-format
+msgid "Order status"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:156
+#: src/paths/instance/orders/details/DetailPage.tsx:308
+#, c-format
+msgid "Product list"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:236
+#, c-format
+msgid "paid"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:238
+#, c-format
+msgid "wired"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:241
+#, c-format
+msgid "refunded"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:258
+#, c-format
+msgid "refund"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:297
+#, c-format
+msgid "Refunded amount"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:298
+#, c-format
+msgid "Deposit total"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:336
+#, c-format
+msgid "unpaid"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:364
+#, c-format
+msgid "Order status URL"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:365
+#, c-format
+msgid "Pay URI"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:383
+#, c-format
+msgid ""
+"Unknown order status. This is an error, please contact the administrator."
+msgstr ""
+
+#: src/paths/instance/orders/details/index.tsx:56
+#: src/paths/instance/orders/list/index.tsx:147
+#, c-format
+msgid "refund created successfully"
+msgstr ""
+
+#: src/paths/instance/orders/details/index.tsx:59
+#: src/paths/instance/orders/list/index.tsx:150
+#, c-format
+msgid "could not create the refund"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:111
+#, c-format
+msgid "load newer orders"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:115
+#, c-format
+msgid "Date"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:131
+#: src/paths/instance/orders/list/Table.tsx:223
+#, c-format
+msgid "Refund"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:145
+#, c-format
+msgid "load older orders"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:154
+#, c-format
+msgid "No orders has been found"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:202
+#, c-format
+msgid "date"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:203
+#, c-format
+msgid "amount"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:204
+#, c-format
+msgid "reason"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:224
+#, c-format
+msgid "Max refundable:"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "Reason"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "duplicated"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "requested by the customer"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "other"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:91
+#, c-format
+msgid "go to order id"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:107
+#, c-format
+msgid "Paid"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:108
+#, c-format
+msgid "Refunded"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:109
+#, c-format
+msgid "Not wired"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:110
+#, c-format
+msgid "All"
+msgstr ""
+
+#: src/paths/instance/products/create/index.tsx:48
+#: src/paths/instance/products/update/index.tsx:64
+#, c-format
+msgid "could not create product"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:87
+#, c-format
+msgid "Sell"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:89
+#, c-format
+msgid "Profit"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:91
+#, c-format
+msgid "Sold"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:59
+#, c-format
+msgid "product updated successfully"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:62
+#, c-format
+msgid "could not update the product"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:70
+#, c-format
+msgid "product delete successfully"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:73
+#, c-format
+msgid "could not delete the product"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:59
+#, c-format
+msgid "Tips"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:111
+#, c-format
+msgid "Committed amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:112
+#, c-format
+msgid "Exchange initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:113
+#, c-format
+msgid "Merchant initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:148
+#, c-format
+msgid "There is no tips yet, add more pressing the + sign"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:50
+#: src/paths/instance/transfers/create/CreatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:56
+#, c-format
+msgid "cannot be empty"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:51
+#, c-format
+msgid "check the id, doest look valid"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:52
+#, c-format
+msgid "should have 52 characters, current %1$s"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:57
+#, c-format
+msgid "URL doesn't have the right format"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:74
+#, c-format
+msgid "Transfer ID"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:76
+#, c-format
+msgid "Account Address"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:82
+#: src/paths/instance/transfers/list/Table.tsx:125
+#, c-format
+msgid "Exchange URL"
+msgstr ""
+
+#: src/paths/instance/transfers/create/index.tsx:49
+#, c-format
+msgid "could not inform transfer"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:118
+#, c-format
+msgid "load newer transfers"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:123
+#, c-format
+msgid "Credit"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:126
+#, c-format
+msgid "Confirmed"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:127
+#: src/paths/instance/transfers/list/index.tsx:60
+#, c-format
+msgid "Verified"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:128
+#, c-format
+msgid "Executed at"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "yes"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "no"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "unknown"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:145
+#, c-format
+msgid "load older transfers"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:154
+#, c-format
+msgid "There is no transfer yet, add more pressing the + sign"
+msgstr ""
diff --git a/packages/merchant-backend-ui/src/index.tsx 
b/packages/merchant-backend-ui/src/index.tsx
new file mode 100644
index 000000000..275f63371
--- /dev/null
+++ b/packages/merchant-backend-ui/src/index.tsx
@@ -0,0 +1,61 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode, Fragment } from 'preact';
+import { BackendContextProvider } from './context/backend';
+import { TranslationProvider } from './context/translation';
+// import { Page as RequestPayment } from './RequestPayment';
+import "./css/pure-min.css"
+import { Route, Router } from 'preact-router';
+import { Footer } from './components/Footer';
+// import OfferTip from './pages/OfferTip';
+// import {OfferRefund} from './pages/OfferRefund';
+// import DepletedTip from './pages/DepletedTip';
+// import RequestPayment from './pages/RequestPayment';
+// import ShowOrderDetails from './pages/ShowOrderDetails';
+
+export default function Application(): VNode {
+  return (
+    // <FetchContextProvider>
+    <BackendContextProvider>
+      <TranslationProvider>
+        <ApplicationStatusRoutes />
+      </TranslationProvider>
+    </BackendContextProvider>
+    // </FetchContextProvider>
+  );
+}
+
+function ApplicationStatusRoutes(): VNode {
+  return <Fragment>
+    <Router>
+      {/* <Route path="offer_tip" component={OfferTip} />
+      <Route path="offer_refund" component={OfferRefund} />
+      <Route path="depleted_tip" component={DepletedTip} />
+      <Route path="request_payment" component={RequestPayment} />
+      <Route path="show_order_details" component={ShowOrderDetails} /> */}
+      <Route default component={() => <div>
+        hello!
+      </div>} />
+    </Router>
+    <Footer />
+  </Fragment>
+}
diff --git a/packages/merchant-backend-ui/src/pages/DepletedTip.stories.tsx 
b/packages/merchant-backend-ui/src/pages/DepletedTip.stories.tsx
new file mode 100644
index 000000000..c20f6dc18
--- /dev/null
+++ b/packages/merchant-backend-ui/src/pages/DepletedTip.stories.tsx
@@ -0,0 +1,40 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode, FunctionalComponent } from 'preact';
+import { DepletedTip as TestedComponent } from './DepletedTip';
+
+
+export default {
+  title: 'DepletedTip',
+  component: TestedComponent,
+  argTypes: {
+  },
+};
+
+function createExample<Props>(Component: FunctionalComponent<Props>, props: 
Partial<Props>) {
+  const r = (args: any) => <Component {...args} />
+  r.args = props
+  return r
+}
+
+export const Example = createExample(TestedComponent, {
+});
diff --git a/packages/merchant-backend-ui/src/pages/DepletedTip.tsx 
b/packages/merchant-backend-ui/src/pages/DepletedTip.tsx
new file mode 100644
index 000000000..756b08d6a
--- /dev/null
+++ b/packages/merchant-backend-ui/src/pages/DepletedTip.tsx
@@ -0,0 +1,60 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import { Fragment, h, render, VNode } from 'preact';
+import { render as renderToString } from 'preact-render-to-string';
+import { Footer } from '../components/Footer';
+import "../css/pure-min.css";
+import "../css/style.css";
+import { Page } from '../styled';
+
+function Head(): VNode {
+  return <title>Status of your tip</title>
+}
+
+export function DepletedTip(): VNode {
+  return <Page>
+    <section>
+      <h1>Tip already collected</h1>
+      <div>
+        You have already collected this tip.
+      </div>
+    </section>
+    <Footer />
+  </Page>
+}
+
+export function mount(): void {
+  try {
+    render(<DepletedTip />, document.body);
+  } catch (e) {
+    console.error("got error", e);
+    if (e instanceof Error) {
+      document.body.innerText = `Fatal error: "${e.message}".  Please report 
this bug at https://bugs.gnunet.org/.`;
+    }
+  }
+}
+
+export function buildTimeRendering(): { head: string, body: string } {
+  return {
+    head: renderToString(<Head />),
+    body: renderToString(<DepletedTip />)
+  }
+}
diff --git a/packages/merchant-backend-ui/src/pages/OfferRefund.stories.tsx 
b/packages/merchant-backend-ui/src/pages/OfferRefund.stories.tsx
new file mode 100644
index 000000000..92694f867
--- /dev/null
+++ b/packages/merchant-backend-ui/src/pages/OfferRefund.stories.tsx
@@ -0,0 +1,45 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode, FunctionalComponent } from 'preact';
+import { createSVG } from '../components/QR';
+import { OfferRefund as TestedComponent } from './OfferRefund';
+
+
+export default {
+  title: 'OfferRefund',
+  component: TestedComponent,
+  argTypes: {
+  },
+};
+
+function createExample<Props>(Component: FunctionalComponent<Props>, props: 
Partial<Props>) {
+  const r = (args: any) => <Component {...args} />
+  r.args = props
+  return r
+}
+
+const REFUND_URI_EXAMPLE = 
'taler://pay/backend.demo.taler.net/instances/blog/2021.249-022NW2KG88QGA/def537eb-00c2-4a8b-8a17-0be034d118d3?c=2Y4N4PMST7KYAPS83428GTPCD4'
+
+export const Example = createExample(TestedComponent, {
+  refundURI: REFUND_URI_EXAMPLE,
+  qr_code: createSVG(REFUND_URI_EXAMPLE)
+});
diff --git a/packages/merchant-backend-ui/src/pages/OfferRefund.tsx 
b/packages/merchant-backend-ui/src/pages/OfferRefund.tsx
new file mode 100644
index 000000000..14c9372c2
--- /dev/null
+++ b/packages/merchant-backend-ui/src/pages/OfferRefund.tsx
@@ -0,0 +1,154 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import { Fragment, h, render, VNode } from 'preact';
+import { render as renderToString } from 'preact-render-to-string';
+import { useEffect } from 'preact/hooks';
+import { Footer } from '../components/Footer';
+import { QR } from '../components/QR';
+import "../css/pure-min.css";
+import "../css/style.css";
+import { Page, QRPlaceholder, WalletLink } from '../styled';
+
+/**
+ * This page creates a refund offer QR code
+ * 
+ * It will build into a mustache html template for server side rendering
+ * 
+ * server side rendering params:
+ *  - order_status_url
+ *  - taler_refund_qrcode_svg
+ *  - taler_refund_uri
+ * 
+ * request params:
+ *  - refund_uri
+ *  - order_status_url
+ */
+
+interface Props {
+  refundURI?: string;
+  order_status_url?: string;
+  qr_code?: string;
+}
+
+function Head({ order_summary }: { order_summary?: string }): VNode {
+  return <Fragment>
+    <meta charSet="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <noscript>
+      <meta http-equiv="refresh" content="1" />
+    </noscript>
+    <title>Refund available for {order_summary ? order_summary : `{{ 
order_summary }}`}</title>
+  </Fragment>
+}
+
+export function OfferRefund({ refundURI, qr_code, order_status_url }: Props): 
VNode {
+  useEffect(() => {
+    let checkUrl: URL;
+    try {
+      checkUrl = new URL(order_status_url ? order_status_url : "{{& 
order_status_url }}");
+    } catch (e) {
+      return;
+    }
+    checkUrl.searchParams.set("await_refund_obtained", "yes");
+    const delayMs = 500;
+    function check() {
+      let retried = false;
+      function retryOnce() {
+        if (!retried) {
+          retried = true;
+          check();
+        }
+      }
+      const req = new XMLHttpRequest();
+      req.onreadystatechange = function () {
+        if (req.readyState === XMLHttpRequest.DONE) {
+          if (req.status === 200) {
+            try {
+              const resp = JSON.parse(req.responseText);
+              if (!resp.refund_pending) {
+                window.location.reload();
+              }
+            } catch (e) {
+              console.error("could not parse response:", e);
+            }
+          }
+          setTimeout(retryOnce, delayMs);
+        }
+      };
+      req.onerror = function () {
+        setTimeout(retryOnce, delayMs);
+      }
+      req.open("GET", checkUrl.href);
+      req.send();
+    }
+
+    setTimeout(check, delayMs);
+  })
+  return <Page>
+    <section>
+      <h1>Collect Taler refund</h1>
+      <p>
+        Scan this QR code with your Taler mobile wallet:
+      </p>
+      <QRPlaceholder dangerouslySetInnerHTML={{ __html: qr_code ? qr_code : 
`{{{ taler_refund_qrcode_svg }}}` }} />
+      <p>
+        <WalletLink href={refundURI ? refundURI : `{{ taler_refund_uri }}`}>
+          Or open your Taller wallet
+        </WalletLink>
+      </p>
+      <p>
+        <a href="https://wallet.taler.net/";>Don't have a Taler wallet yet? 
Install it!</a>
+      </p>
+    </section>
+    <Footer />
+  </Page>
+}
+
+export function mount(): void {
+  try {
+    const fromLocation = new URL(window.location.href).searchParams
+    const os = fromLocation.get('order_summary') || undefined;
+    if (os) {
+      render(<Head order_summary={os} />, document.head);
+    }
+
+    const uri = fromLocation.get('refund_uri') || undefined;
+    const osu = fromLocation.get('order_status_url') || undefined;
+    const qr_code = uri ? renderToString(<QR text={uri} />) : undefined;
+
+    render(<OfferRefund
+      refundURI={uri} order_status_url={osu}
+      qr_code={qr_code}
+    />, document.body);
+  } catch (e) {
+    console.error("got error", e);
+    if (e instanceof Error) {
+      document.body.innerText = `Fatal error: "${e.message}".  Please report 
this bug at https://bugs.gnunet.org/.`;
+    }
+  }
+}
+
+export function buildTimeRendering(): { head: string, body: string } {
+  return {
+    head: renderToString(<Head />),
+    body: renderToString(<OfferRefund />)
+  }
+}
diff --git a/packages/merchant-backend-ui/src/pages/OfferTip.stories.tsx 
b/packages/merchant-backend-ui/src/pages/OfferTip.stories.tsx
new file mode 100644
index 000000000..dfbf71fff
--- /dev/null
+++ b/packages/merchant-backend-ui/src/pages/OfferTip.stories.tsx
@@ -0,0 +1,45 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode, FunctionalComponent } from 'preact';
+import { createSVG } from '../components/QR';
+import { OfferTip as TestedComponent } from './OfferTip';
+
+
+export default {
+  title: 'OfferTip',
+  component: TestedComponent,
+  argTypes: {
+  },
+};
+
+function createExample<Props>(Component: FunctionalComponent<Props>, props: 
Partial<Props>) {
+  const r = (args: any) => <Component {...args} />
+  r.args = props
+  return r
+}
+
+const TIP_URI_EXAMPLE = 
'taler+http://tip/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0'
+
+export const Example = createExample(TestedComponent, {
+  tipURI: TIP_URI_EXAMPLE,
+  qr_code: createSVG(TIP_URI_EXAMPLE)
+});
diff --git a/packages/merchant-backend-ui/src/pages/OfferTip.tsx 
b/packages/merchant-backend-ui/src/pages/OfferTip.tsx
new file mode 100644
index 000000000..ace1059ca
--- /dev/null
+++ b/packages/merchant-backend-ui/src/pages/OfferTip.tsx
@@ -0,0 +1,141 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import { Fragment, h, render, VNode } from 'preact';
+import { render as renderToString } from 'preact-render-to-string';
+import { useEffect } from 'preact/hooks';
+import { Footer } from '../components/Footer';
+import { QR } from '../components/QR';
+import "../css/pure-min.css";
+import "../css/style.css";
+import { Page, QRPlaceholder, WalletLink } from '../styled';
+import { ShowOrderDetails } from './ShowOrderDetails';
+
+
+/**
+ * This page creates a tip offer QR code
+ * 
+ * It will build into a mustache html template for server side rendering
+ * 
+ * server side rendering params:
+ *  - tip_status_url
+ *  - taler_tip_qrcode_svg
+ *  - taler_tip_uri
+ * 
+ * request params:
+ *  - tip_uri
+ *  - tip_status_url
+ */
+
+interface Props {
+  tipURI?: string,
+  tip_status_url?: string,
+  qr_code?: string,
+}
+
+export function Head(): VNode {
+  return <Fragment>
+    <meta charSet="UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <noscript>
+      <meta http-equiv="refresh" content="1" />
+    </noscript>
+    <title>Tip available</title>
+  </Fragment>
+}
+
+export function OfferTip({ tipURI, qr_code, tip_status_url }: Props): VNode {
+  useEffect(() => {
+    let checkUrl: URL;
+    try {
+      checkUrl = new URL(tip_status_url ? tip_status_url : "{{& tip_status_url 
}}");
+    } catch (e) {
+      return;
+    }
+
+    const delayMs = 500;
+    function check() {
+      let retried = false;
+      function retryOnce() {
+        if (!retried) {
+          retried = true;
+          check();
+        }
+      }
+      const req = new XMLHttpRequest();
+      req.onreadystatechange = function () {
+        if (req.readyState === XMLHttpRequest.DONE) {
+          if (req.status === 410) {
+            window.location.reload();
+          }
+          setTimeout(retryOnce, delayMs);
+        }
+      };
+      req.onerror = function () {
+        setTimeout(retryOnce, delayMs);
+      }
+      req.open("GET", checkUrl.href);
+      req.send();
+    }
+
+    setTimeout(check, delayMs);
+  })
+  return <Page>
+    <section>
+      <h1 >Collect Taler tip</h1>
+      <p>
+        Scan this QR code with your Taler mobile wallet:
+      </p>
+      <QRPlaceholder dangerouslySetInnerHTML={{ __html: qr_code ? qr_code : 
`{{{ taler_tip_qrcode_svg }}}` }} />
+      <p>
+        <WalletLink href={tipURI ? tipURI : `{{ taler_tip_uri }}`}>
+          Or open your Taller wallet
+        </WalletLink>
+      </p>
+      <p>
+        <a href="https://wallet.taler.net/";>Don't have a Taler wallet yet? 
Install it!</a>
+      </p>
+    </section>
+    <Footer />
+  </Page>
+}
+
+export function mount(): void {
+  try {
+    const fromLocation = new URL(window.location.href).searchParams
+
+    const uri = fromLocation.get('tip_uri') || undefined
+    const tsu = fromLocation.get('tip_status_url') || undefined
+
+    render(<OfferTip tipURI={uri} tip_status_url={tsu} />, document.body);
+  } catch (e) {
+    console.error("got error", e);
+    if (e instanceof Error) {
+      document.body.innerText = `Fatal error: "${e.message}".  Please report 
this bug at https://bugs.gnunet.org/.`;
+    }
+  }
+}
+
+export function buildTimeRendering(): { head: string, body: string } {
+  return {
+    head: renderToString(<Head />),
+    body: renderToString(<ShowOrderDetails />)
+  }
+}
diff --git a/packages/merchant-backend-ui/src/pages/RequestPayment.stories.tsx 
b/packages/merchant-backend-ui/src/pages/RequestPayment.stories.tsx
new file mode 100644
index 000000000..5d6d79adf
--- /dev/null
+++ b/packages/merchant-backend-ui/src/pages/RequestPayment.stories.tsx
@@ -0,0 +1,45 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { FunctionalComponent, h } from 'preact';
+import { createSVG } from '../components/QR';
+import { RequestPayment as TestedComponent } from './RequestPayment';
+
+
+export default {
+  title: 'RequestPayment',
+  component: TestedComponent,
+  argTypes: {
+  },
+};
+
+function createExample<Props>(Component: FunctionalComponent<Props>, props: 
Partial<Props>) {
+  const r = (args: any) => <Component {...args} />
+  r.args = props
+  return r
+}
+
+const PAYTO_URI_EXAMPLE = 
'taler+http://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0'
+
+export const Example = createExample(TestedComponent, {
+  payURI: 
'taler+http://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0',
+  qr_code: createSVG(PAYTO_URI_EXAMPLE)
+});
diff --git a/packages/merchant-backend-ui/src/pages/RequestPayment.tsx 
b/packages/merchant-backend-ui/src/pages/RequestPayment.tsx
new file mode 100644
index 000000000..050755dfb
--- /dev/null
+++ b/packages/merchant-backend-ui/src/pages/RequestPayment.tsx
@@ -0,0 +1,196 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { Fragment, h, render, VNode } from "preact";
+import { render as renderToString } from "preact-render-to-string";
+import { useEffect } from "preact/hooks";
+import { Footer } from "../components/Footer";
+import "../css/pure-min.css";
+import "../css/style.css";
+import { QR } from "../components/QR";
+import { Page, QRPlaceholder, WalletLink } from "../styled";
+
+/**
+ * This page creates a payment request QR code
+ *
+ * It will build into a mustache html template for server side rendering
+ *
+ * server side rendering params:
+ *  - order_status_url
+ *  - taler_pay_qrcode_svg
+ *  - taler_pay_uri
+ *  - order_summary
+ *
+ * request params:
+ *  - pay_uri
+ *  - order_summary
+ *  - order_status_url
+ */
+
+interface Props {
+  payURI?: string;
+  order_status_url?: string;
+  qr_code?: string;
+}
+
+function Head({ order_summary }: { order_summary?: string }): VNode {
+  return (
+    <Fragment>
+      <meta charSet="UTF-8" />
+      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+      <noscript>
+        <meta http-equiv="refresh" content="1" />
+      </noscript>
+      <title>
+        Payment requested for{" "}
+        {order_summary ? order_summary : `{{ order_summary }}`}
+      </title>
+    </Fragment>
+  );
+}
+
+export function RequestPayment({
+  payURI,
+  qr_code,
+  order_status_url,
+}: Props): VNode {
+  useEffect(() => {
+    const longpollDelayMs = 60 * 1000;
+    let checkUrl: URL;
+    try {
+      checkUrl = new URL(
+        order_status_url ? order_status_url : "{{& order_status_url }}"
+      );
+    } catch (e) {
+      return;
+    }
+    checkUrl.searchParams.set("timeout_s", longpollDelayMs.toString());
+    function check() {
+      let retried = false;
+      function retryOnce() {
+        if (!retried) {
+          retried = true;
+          check();
+        }
+      }
+      const req = new XMLHttpRequest();
+      req.onreadystatechange = function () {
+        if (req.readyState === XMLHttpRequest.DONE) {
+          if (req.status === 200) {
+            try {
+              const resp = JSON.parse(req.responseText);
+              if (resp.fulfillment_url) {
+                window.location.replace(resp.fulfillment_url);
+              }
+            } catch (e) {
+              console.error("could not parse response:", e);
+            }
+          }
+          if (req.status === 202) {
+            try {
+              const resp = JSON.parse(req.responseText);
+              if (resp.fulfillment_url) {
+                window.location.replace(resp.fulfillment_url);
+              }
+            } catch (e) {
+              console.error("could not parse response:", e);
+            }
+          }
+          if (req.status === 402) {
+            try {
+              const resp = JSON.parse(req.responseText);
+              if (resp.already_paid_order_id && resp.fulfillment_url) {
+                window.location.replace(resp.fulfillment_url);
+              }
+            } catch (e) {
+              console.error("could not parse response:", e);
+            }
+          }
+          setTimeout(retryOnce, 500);
+        }
+      };
+      req.onerror = function () {
+        setTimeout(retryOnce, 500);
+      };
+      req.ontimeout = function () {
+        setTimeout(retryOnce, 500);
+      };
+      req.timeout = longpollDelayMs;
+      req.open("GET", checkUrl.href);
+      req.send();
+    }
+    setTimeout(check, 500);
+  });
+  return (
+    <Page>
+      <section>
+        <h1>Pay with Taler</h1>
+        <p>Scan this QR code with your mobile wallet:</p>
+        <QRPlaceholder
+          dangerouslySetInnerHTML={{
+            __html: qr_code ? qr_code : `{{{ taler_pay_qrcode_svg }}}`,
+          }}
+        />
+        <p>
+          <WalletLink href={payURI ? payURI : `{{ taler_pay_uri }}`}>
+            Or open your Taller wallet
+          </WalletLink>
+        </p>
+        <p>
+          <a href="https://wallet.taler.net/";>
+            Don't have a Taler wallet yet? Install it!
+          </a>
+        </p>
+      </section>
+      <Footer />
+    </Page>
+  );
+}
+
+export function mount(): void {
+  try {
+    const fromLocation = new URL(window.location.href).searchParams;
+    const os = fromLocation.get("order_summary") || undefined;
+    if (os) {
+      render(<Head order_summary={os} />, document.head);
+    }
+
+    const uri = fromLocation.get("pay_uri") || undefined;
+    const osu = fromLocation.get("order_status_url") || undefined;
+    const qr_code = uri ? renderToString(<QR text={uri} />) : undefined;
+
+    render(
+      <RequestPayment payURI={uri} order_status_url={osu} qr_code={qr_code} />,
+      document.body
+    );
+  } catch (e) {
+    console.error("got error", e);
+    if (e instanceof Error) {
+      document.body.innerText = `Fatal error: "${e.message}".  Please report 
this bug at https://bugs.gnunet.org/.`;
+    }
+  }
+}
+
+export function buildTimeRendering(): { head: string; body: string } {
+  return {
+    head: renderToString(<Head />),
+    body: renderToString(<RequestPayment />),
+  };
+}
diff --git 
a/packages/merchant-backend-ui/src/pages/ShowOrderDetails.examples.ts 
b/packages/merchant-backend-ui/src/pages/ShowOrderDetails.examples.ts
new file mode 100644
index 000000000..ba68397ee
--- /dev/null
+++ b/packages/merchant-backend-ui/src/pages/ShowOrderDetails.examples.ts
@@ -0,0 +1,219 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { MerchantBackend } from '../declaration';
+import { Props } from './ShowOrderDetails';
+
+
+const defaultContractTerms: MerchantBackend.ContractTerms = {
+  order_id: 'XRS8876388373',
+  amount: 'USD:10',
+  summary: 'this is a short summary',
+  pay_deadline: {
+    t_s: new Date().getTime() + 6 * 24 * 60 * 60 * 1000
+  },
+  merchant: {
+    name: 'the merchant (inc)',
+    address: {
+      country_subdivision: 'Buenos Aires',
+      town: 'CABA',
+      country: 'Argentina'
+    },
+    jurisdiction: {
+      country_subdivision: 'Cordoba',
+      town: 'Capital',
+      country: 'Argentina'
+    },
+  },
+  max_fee: 'USD:0.1',
+  max_wire_fee: 'USD:0.2',
+  wire_fee_amortization: 1,
+  products: [],
+  timestamp: {
+    t_s: new Date().getTime()
+  },
+  auditors: [],
+  exchanges: [],
+  h_wire: '',
+  merchant_base_url: 'http://merchant.base.url/',
+  merchant_pub: 'QWEASDQWEASD',
+  nonce: 'NONCE',
+  refund_deadline: {
+    t_s: new Date().getTime() + 6 * 24 * 60 * 60 * 1000
+  },
+  wire_method: 'x-taler-bank',
+  wire_transfer_deadline: {
+    t_s: new Date().getTime() + 3 * 24 * 60 * 60 * 1000
+  },
+};
+
+const inSixDays = new Date().getTime() + 6 * 24 * 60 * 60 * 1000
+const in10Minutes = new Date().getTime() + 10 * 60 * 1000
+const in15Minutes = new Date().getTime() + 15 * 60 * 1000
+const in20Minutes = new Date().getTime() + 20 * 60 * 1000
+
+export const exampleData: { [name: string]: Props } = {
+  Simplest: {
+    order_summary: 'here goes the order summary',
+    contract_terms: defaultContractTerms,
+  },
+  WithRefundAmount: {
+    order_summary: 'here goes the order summary',
+    refund_amount: 'USD:10',
+    contract_terms: defaultContractTerms,
+  },
+  WithDeliveryDate: {
+    order_summary: 'here goes the order summary',
+    contract_terms: {
+      ...defaultContractTerms,
+      delivery_date: {
+        t_s: inSixDays
+      },
+    },
+  },
+  WithDeliveryLocation: {
+    order_summary: 'here goes the order summary',
+    contract_terms: {
+      ...defaultContractTerms,
+      delivery_location: {
+        address_lines: ['addr line 1', 'addr line 2', 'addr line 3', 'addr 
line 4', 'addr line 5', 'addr line 6', 'addr line 7'],
+        building_name: 'building-name',
+        building_number: 'building-number',
+        country: 'country',
+        country_subdivision: 'country sub',
+        district: 'district',
+        post_code: 'post-code',
+        street: 'street',
+        town: 'town',
+        town_location: 'town loc',
+      },
+    },
+  },
+  WithDeliveryLocationAndDate: {
+    order_summary: 'here goes the order summary',
+    contract_terms: {
+      ...defaultContractTerms,
+      delivery_location: {
+        address_lines: ['addr1', 'addr2', 'addr3', 'addr4', 'addr5', 'addr6', 
'addr7'],
+        building_name: 'building-name',
+        building_number: 'building-number',
+        country: 'country',
+        country_subdivision: 'country sub',
+        district: 'district',
+        post_code: 'post-code',
+        street: 'street',
+        town: 'town',
+        town_location: 'town loc',
+      },
+      delivery_date: {
+        t_s: inSixDays
+      },
+    },
+  },
+  WithThreeProducts: {
+    order_summary: 'here goes the order summary',
+    contract_terms: {
+      ...defaultContractTerms,
+      products: [{
+        description: 'description of the first product',
+        price: '5:USD',
+        quantity: 1,
+        delivery_date: { t_s: in10Minutes },
+        product_id: '12333',
+      }, {
+        description: 'another description',
+        price: '10:USD',
+        quantity: 5,
+        unit: 't-shirt',
+      }, {
+        description: 'one last description',
+        price: '10:USD',
+        quantity: 5
+      }]
+    } as MerchantBackend.ContractTerms
+  },
+  WithProductWithTaxes: {
+    order_summary: 'here goes the order summary',
+    contract_terms: {
+      ...defaultContractTerms,
+      products: [{
+        description: 'description of the first product',
+        price: '5:USD',
+        quantity: 1,
+        unit: 'beer',
+        delivery_date: { t_s: in10Minutes },
+        product_id: '456',
+        taxes: [{
+          name: 'VAT', tax: 'USD:1'
+        }],
+      }, {
+        description: 'one last description',
+        price: '10:USD',
+        quantity: 5,
+        product_id: '123',
+        unit: 'beer',
+        taxes: [{
+          name: 'VAT', tax: 'USD:1'
+        }],
+      }]
+    } as MerchantBackend.ContractTerms
+  },
+  WithExchangeList: {
+    order_summary: 'here goes the order summary',
+    contract_terms: {
+      ...defaultContractTerms,
+      exchanges: [{
+        master_pub: 'ABCDEFGHIJKLMNO',
+        url: 'http://exchange0.taler.net'
+      }, {
+        master_pub: 'AAAAAAAAAAAAAAA',
+        url: 'http://exchange1.taler.net'
+      }, {
+        master_pub: 'BBBBBBBBBBBBBBB',
+        url: 'http://exchange2.taler.net'
+      }]
+    },
+  },
+  WithAuditorList: {
+    order_summary: 'here goes the order summary',
+    contract_terms: {
+      ...defaultContractTerms,
+      auditors: [{
+        auditor_pub: 'ABCDEFGHIJKLMNO',
+        name: 'the USD auditor',
+        url: 'http://auditor-usd.taler.net'
+      }, {
+        auditor_pub: 'OPQRSTUVWXYZABCD',
+        name: 'the EUR auditor',
+        url: 'http://auditor-eur.taler.net'
+      }]
+    },
+  },
+  WithAutoRefund: {
+    order_summary: 'here goes the order summary',
+    contract_terms: {
+      ...defaultContractTerms,
+      auto_refund: {
+        d_us: 1000 * 60 * 60 * 26 + 1000 * 60 * 30
+      }
+    },
+  },
+}
diff --git 
a/packages/merchant-backend-ui/src/pages/ShowOrderDetails.stories.tsx 
b/packages/merchant-backend-ui/src/pages/ShowOrderDetails.stories.tsx
new file mode 100644
index 000000000..6a902cc9e
--- /dev/null
+++ b/packages/merchant-backend-ui/src/pages/ShowOrderDetails.stories.tsx
@@ -0,0 +1,49 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { FunctionalComponent, h } from 'preact';
+import { ShowOrderDetails as TestedComponent } from './ShowOrderDetails';
+import { exampleData } from './ShowOrderDetails.examples';
+
+export default {
+  title: 'ShowOrderDetails',
+  component: TestedComponent,
+  argTypes: {
+  },
+  excludeStories: /.*Data$/,
+};
+
+function createExample<Props>(Component: FunctionalComponent<Props>, props: 
Partial<Props>) {
+  const r = (args: any) => <Component {...args} />
+  r.args = props
+  return r
+}
+
+export const Simplest = createExample(TestedComponent, exampleData.Simplest);
+export const WithRefundAmount = createExample(TestedComponent, 
exampleData.WithRefundAmount);
+export const WithDeliveryDate = createExample(TestedComponent, 
exampleData.WithDeliveryDate);
+export const WithDeliveryLocation = createExample(TestedComponent, 
exampleData.WithDeliveryLocation);
+export const WithDeliveryLocationAndDate = createExample(TestedComponent, 
exampleData.WithDeliveryLocationAndDate);
+export const WithThreeProducts = createExample(TestedComponent, 
exampleData.WithThreeProducts);
+export const WithAuditorList = createExample(TestedComponent, 
exampleData.WithAuditorList);
+export const WithExchangeList = createExample(TestedComponent, 
exampleData.WithExchangeList);
+export const WithAutoRefund = createExample(TestedComponent, 
exampleData.WithAutoRefund);
+export const WithProductWithTaxes = createExample(TestedComponent, 
exampleData.WithProductWithTaxes);
diff --git a/packages/merchant-backend-ui/src/pages/ShowOrderDetails.tsx 
b/packages/merchant-backend-ui/src/pages/ShowOrderDetails.tsx
new file mode 100644
index 000000000..aa62c2932
--- /dev/null
+++ b/packages/merchant-backend-ui/src/pages/ShowOrderDetails.tsx
@@ -0,0 +1,551 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { format, formatDuration } from "date-fns";
+import { intervalToDuration } from "date-fns/esm";
+import { Fragment, h, render, VNode } from "preact";
+import { render as renderToString } from "preact-render-to-string";
+import { Footer } from "../components/Footer";
+import "../css/pure-min.css";
+import "../css/style.css";
+import { MerchantBackend } from "../declaration";
+import { Page, InfoBox, TableExpanded, TableSimple } from "../styled";
+
+/**
+ * This page creates a payment request QR code
+ *
+ * It will build into a mustache html template for server side rendering
+ *
+ * server side rendering params:
+ *  - order_summary
+ *  - contract_terms
+ *  - refund_amount
+ *
+ * request params:
+ *  - refund_amount
+ *  - contract_terms
+ *  - order_summary
+ */
+
+export interface Props {
+  btr?: boolean; // build time rendering flag
+  order_summary?: string;
+  refund_amount?: string;
+  contract_terms?: MerchantBackend.ContractTerms;
+}
+
+function Head({ order_summary }: { order_summary?: string }): VNode {
+  return (
+    <Fragment>
+      <meta charSet="UTF-8" />
+      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+      <noscript>
+        <meta http-equiv="refresh" content="1" />
+      </noscript>
+      <title>
+        Status of your order for{" "}
+        {order_summary ? order_summary : `{{ order_summary }}`}
+      </title>
+      <script>{`
+      var contractTermsStr = '{{{contract_terms_json}}}';
+    `}</script>
+    </Fragment>
+  );
+}
+
+function Location({
+  templateName,
+  location,
+  btr,
+}: {
+  templateName: string;
+  location: MerchantBackend.Location | undefined;
+  btr?: boolean;
+}) {
+  //FIXME: mustache strings show be constructed in a way that ends in the 
final output of the html but is not present in the
+  // javascript code, otherwise when mustache render engine run over the html 
it will also replace string in the javascript code
+  // that is made to run when the browser has javascript enable leading into 
undefined behavior.
+  // that's why in the next fields we are using concatenations to build the 
mustache placeholder.
+  return (
+    <Fragment>
+      {btr && `{{` + `#${templateName}.building_name}}`}
+      <dd>
+        {location?.building_name ||
+          (btr && `{{ ${templateName}.building_name }}`)}{" "}
+        {location?.building_number ||
+          (btr && `{{ ${templateName}.building_number }}`)}
+      </dd>
+      {btr && `{{` + `/${templateName}.building_name}}`}
+
+      {btr && `{{` + `#${templateName}.country}}`}
+      <dd>
+        {location?.country || (btr && `{{ ${templateName}.country }}`)}{" "}
+        {location?.country_subdivision ||
+          (btr && `{{ ${templateName}.country_subdivision }}`)}
+      </dd>
+      {btr && `{{` + `/${templateName}.country}}`}
+
+      {btr && `{{` + `#${templateName}.district}}`}
+      <dd>{location?.district || (btr && `{{ ${templateName}.district 
}}`)}</dd>
+      {btr && `{{` + `/${templateName}.district}}`}
+
+      {btr && `{{` + `#${templateName}.post_code}}`}
+      <dd>
+        {location?.post_code || (btr && `{{ ${templateName}.post_code }}`)}
+      </dd>
+      {btr && `{{` + `/${templateName}.post_code}}`}
+
+      {btr && `{{` + `#${templateName}.street}}`}
+      <dd>{location?.street || (btr && `{{ ${templateName}.street }}`)}</dd>
+      {btr && `{{` + `/${templateName}.street}}`}
+
+      {btr && `{{` + `#${templateName}.town}}`}
+      <dd>{location?.town || (btr && `{{ ${templateName}.town }}`)}</dd>
+      {btr && `{{` + `/${templateName}.town}}`}
+
+      {btr && `{{` + `#${templateName}.town_location}}`}
+      <dd>
+        {location?.town_location ||
+          (btr && `{{ ${templateName}.town_location }}`)}
+      </dd>
+      {btr && `{{` + `/${templateName}.town_location}}`}
+    </Fragment>
+  );
+}
+
+export function ShowOrderDetails({
+  order_summary,
+  refund_amount,
+  contract_terms,
+  btr,
+}: Props): VNode {
+  const productList = btr
+    ? [{} as MerchantBackend.Product]
+    : contract_terms?.products || [];
+  const auditorsList = btr
+    ? [{} as MerchantBackend.Auditor]
+    : contract_terms?.auditors || [];
+  const exchangesList = btr
+    ? [{} as MerchantBackend.Exchange]
+    : contract_terms?.exchanges || [];
+  const hasDeliveryInfo =
+    btr ||
+    !!contract_terms?.delivery_date ||
+    !!contract_terms?.delivery_location;
+
+  return (
+    <Page>
+      <header>
+        <h1>
+          Details of order{" "}
+          {contract_terms?.order_id || `{{ contract_terms.order_id }}`}
+        </h1>
+      </header>
+
+      <section>
+        {btr && `{{#refund_amount}}`}
+        {(btr || refund_amount) && (
+          <section>
+            <InfoBox>
+              <b>Refunded:</b> The merchant refunded you{" "}
+              <b>{refund_amount || `{{ refund_amount }}`}</b>.
+            </InfoBox>
+          </section>
+        )}
+        {btr && `{{/refund_amount}}`}
+
+        <section>
+          <TableExpanded>
+            <dt>Order summary:</dt>
+            <dd>{contract_terms?.summary || `{{ contract_terms.summary 
}}`}</dd>
+            <dt>Amount paid:</dt>
+            <dd>{contract_terms?.amount || `{{ contract_terms.amount }}`}</dd>
+            <dt>Order date:</dt>
+            <dd>
+              {contract_terms?.timestamp
+                ? contract_terms?.timestamp.t_s != "never"
+                  ? format(
+                      contract_terms?.timestamp.t_s,
+                      "dd MMM yyyy HH:mm:ss"
+                    )
+                  : "never"
+                : `{{ contract_terms.timestamp_str }}`}{" "}
+            </dd>
+            <dt>Merchant name:</dt>
+            <dd>
+              {contract_terms?.merchant.name ||
+                `{{ contract_terms.merchant.name }}`}
+            </dd>
+          </TableExpanded>
+        </section>
+
+        {btr && `{{#contract_terms.hasProducts}}`}
+        {!productList.length ? null : (
+          <section>
+            <h2>Products purchased</h2>
+            <TableSimple>
+              {btr && "{{" + "#contract_terms.products" + "}}"}
+              {productList.map((p, i) => {
+                const taxList = btr
+                  ? [{} as MerchantBackend.Tax]
+                  : p.taxes || [];
+
+                return (
+                  <Fragment key={i}>
+                    <p>{p.description || `{{description}}`}</p>
+                    <dl>
+                      <dt>Quantity:</dt>
+                      <dd>{p.quantity || `{{quantity}}`}</dd>
+
+                      <dt>Price:</dt>
+                      <dd>{p.price || `{{price}}`}</dd>
+
+                      {btr && `{{#hasTaxes}}`}
+                      {!taxList.length ? null : (
+                        <Fragment>
+                          {btr && "{{" + "#taxes" + "}}"}
+                          {taxList.map((t, i) => {
+                            return (
+                              <Fragment key={i}>
+                                <dt>{t.name || `{{name}}`}</dt>
+                                <dd>{t.tax || `{{tax}}`}</dd>
+                              </Fragment>
+                            );
+                          })}
+                          {btr && "{{" + "/taxes" + "}}"}
+                        </Fragment>
+                      )}
+                      {btr && `{{/hasTaxes}}`}
+
+                      {btr && `{{#delivery_date}}`}
+                      {(btr || p.delivery_date) && (
+                        <Fragment>
+                          <dt>Delivered on:</dt>
+                          <dd>
+                            {p.delivery_date
+                              ? p.delivery_date.t_s != "never"
+                                ? format(
+                                    p.delivery_date.t_s,
+                                    "dd MMM yyyy HH:mm:ss"
+                                  )
+                                : "never"
+                              : `{{ delivery_date_str }}`}{" "}
+                          </dd>
+                        </Fragment>
+                      )}
+                      {btr && `{{/delivery_date}}`}
+
+                      {btr && `{{#unit}}`}
+                      {(btr || p.unit) && (
+                        <Fragment>
+                          <dt>Product unit:</dt>
+                          <dd>{p.unit || `{{.}}`}</dd>
+                        </Fragment>
+                      )}
+                      {btr && `{{/unit}}`}
+
+                      {btr && `{{#product_id}}`}
+                      {(btr || p.product_id) && (
+                        <Fragment>
+                          <dt>Product ID:</dt>
+                          <dd>{p.product_id || `{{.}}`}</dd>
+                        </Fragment>
+                      )}
+                      {btr && `{{/product_id}}`}
+                    </dl>
+                  </Fragment>
+                );
+              })}
+              {btr && "{{" + "/contract_terms.products" + "}}"}
+            </TableSimple>
+          </section>
+        )}
+        {btr && `{{/contract_terms.hasProducts}}`}
+
+        {btr && `{{#contract_terms.has_delivery_info}}`}
+        {!hasDeliveryInfo ? null : (
+          <section>
+            <h2>Delivery information</h2>
+            <TableExpanded>
+              {btr && `{{#contract_terms.delivery_date}}`}
+              {(btr || contract_terms?.delivery_date) && (
+                <Fragment>
+                  <dt>Delivery date:</dt>
+                  <dd>
+                    {contract_terms?.delivery_date
+                      ? contract_terms?.delivery_date.t_s != "never"
+                        ? format(
+                            contract_terms?.delivery_date.t_s,
+                            "dd MMM yyyy HH:mm:ss"
+                          )
+                        : "never"
+                      : `{{ contract_terms.delivery_date_str }}`}{" "}
+                  </dd>
+                </Fragment>
+              )}
+              {btr && `{{/contract_terms.delivery_date}}`}
+
+              {btr && `{{#contract_terms.delivery_location}}`}
+              {(btr || contract_terms?.delivery_location) && (
+                <Fragment>
+                  <dt>Delivery address:</dt>
+                  <Location
+                    btr={btr}
+                    location={contract_terms?.delivery_location}
+                    templateName="contract_terms.delivery_location"
+                  />
+                </Fragment>
+              )}
+              {btr && `{{/contract_terms.delivery_location}}`}
+            </TableExpanded>
+          </section>
+        )}
+        {btr && `{{/contract_terms.has_delivery_info}}`}
+
+        <section>
+          <h2>Full payment information</h2>
+          <TableExpanded>
+            <dt>Amount paid:</dt>
+            <dd>{contract_terms?.amount || `{{ contract_terms.amount }}`}</dd>
+            <dt>Wire transfer method:</dt>
+            <dd>
+              {contract_terms?.wire_method ||
+                `{{ contract_terms.wire_method }}`}
+            </dd>
+            <dt>Payment deadline:</dt>
+            <dd>
+              {contract_terms?.pay_deadline
+                ? contract_terms?.pay_deadline.t_s != "never"
+                  ? format(
+                      contract_terms?.pay_deadline.t_s,
+                      "dd MMM yyyy HH:mm:ss"
+                    )
+                  : "never"
+                : `{{ contract_terms.pay_deadline_str }}`}{" "}
+            </dd>
+            <dt>Exchange transfer deadline:</dt>
+            <dd>
+              {contract_terms?.wire_transfer_deadline
+                ? contract_terms?.wire_transfer_deadline.t_s != "never"
+                  ? format(
+                      contract_terms?.wire_transfer_deadline.t_s,
+                      "dd MMM yyyy HH:mm:ss"
+                    )
+                  : "never"
+                : `{{ contract_terms.wire_transfer_deadline_str }}`}{" "}
+            </dd>
+            <dt>Maximum deposit fee:</dt>
+            <dd>{contract_terms?.max_fee || `{{ contract_terms.max_fee 
}}`}</dd>
+            <dt>Maximum wire fee:</dt>
+            <dd>
+              {contract_terms?.max_wire_fee ||
+                `{{ contract_terms.max_wire_fee }}`}
+            </dd>
+            <dt>Wire fee amortization:</dt>
+            <dd>
+              {contract_terms?.wire_fee_amortization ||
+                `{{ contract_terms.wire_fee_amortization }}`}{" "}
+              transactions
+            </dd>
+          </TableExpanded>
+        </section>
+
+        <section>
+          <h2>Refund information</h2>
+          <TableExpanded>
+            <dt>Refund deadline:</dt>
+            <dd>
+              {contract_terms?.refund_deadline
+                ? contract_terms?.refund_deadline.t_s != "never"
+                  ? format(
+                      contract_terms?.refund_deadline.t_s,
+                      "dd MMM yyyy HH:mm:ss"
+                    )
+                  : "never"
+                : `{{ contract_terms.refund_deadline_str }}`}{" "}
+            </dd>
+
+            {btr && `{{#contract_terms.auto_refund}}`}
+            {(btr || contract_terms?.auto_refund) && (
+              <Fragment>
+                <dt>Attempt autorefund for:</dt>
+                <dd>
+                  {contract_terms?.auto_refund
+                    ? contract_terms?.auto_refund.d_us != "forever"
+                      ? formatDuration(
+                          intervalToDuration({
+                            start: 0,
+                            end: contract_terms?.auto_refund.d_us,
+                          })
+                        )
+                      : "forever"
+                    : `{{ contract_terms.auto_refund_str }}`}{" "}
+                </dd>
+              </Fragment>
+            )}
+            {btr && `{{/contract_terms.auto_refund}}`}
+          </TableExpanded>
+        </section>
+
+        <section>
+          <h2>Additional order details</h2>
+          <TableExpanded>
+            <dt>Public reorder URL:</dt>
+            <dd> -- not defined yet -- </dd>
+            {btr && `{{#contract_terms.fulfillment_url}}`}
+            {(btr || contract_terms?.fulfillment_url) && (
+              <Fragment>
+                <dt>Fulfillment URL:</dt>
+                <dd>
+                  {contract_terms?.fulfillment_url ||
+                    (btr && `{{ contract_terms.fulfillment_url }}`)}
+                </dd>
+              </Fragment>
+            )}
+            {btr && `{{/contract_terms.fulfillment_url}}`}
+            {/* <dt>Fulfillment message:</dt>
+          <dd> -- not defined yet -- </dd> */}
+          </TableExpanded>
+        </section>
+
+        <section>
+          <h2>Full merchant information</h2>
+          <TableExpanded>
+            <dt>Merchant name:</dt>
+            <dd>
+              {contract_terms?.merchant.name ||
+                `{{ contract_terms.merchant.name }}`}
+            </dd>
+            <dt>Merchant address:</dt>
+            <Location
+              btr={btr}
+              location={contract_terms?.merchant.address}
+              templateName="contract_terms.merchant.address"
+            />
+            <dt>Merchant's jurisdiction:</dt>
+            <Location
+              btr={btr}
+              location={contract_terms?.merchant.jurisdiction}
+              templateName="contract_terms.merchant.jurisdiction"
+            />
+            <dt>Merchant URI:</dt>
+            <dd>
+              {contract_terms?.merchant_base_url ||
+                `{{ contract_terms.merchant_base_url }}`}
+            </dd>
+            <dt>Merchant's public key:</dt>
+            <dd>
+              {contract_terms?.merchant_pub ||
+                `{{ contract_terms.merchant_pub }}`}
+            </dd>
+            {/* <dt>Merchant's hash:</dt>
+          <dd> -- not defined yet -- </dd> */}
+          </TableExpanded>
+        </section>
+
+        {btr && `{{#contract_terms.hasAuditors}}`}
+        {!auditorsList.length ? null : (
+          <section>
+            <h2>Auditors accepted by the merchant</h2>
+            <TableExpanded>
+              {btr && "{{" + "#contract_terms.auditors" + "}}"}
+              {auditorsList.map((p, i) => {
+                return (
+                  <Fragment key={i}>
+                    <p>{p.name || `{{name}}`}</p>
+                    <dt>Auditor's public key:</dt>
+                    <dd>{p.auditor_pub || `{{auditor_pub}}`}</dd>
+                    <dt>Auditor's URL:</dt>
+                    <dd>{p.url || `{{url}}`}</dd>
+                  </Fragment>
+                );
+              })}
+              {btr && "{{" + "/contract_terms.auditors" + "}}"}
+            </TableExpanded>
+          </section>
+        )}
+        {btr && `{{/contract_terms.hasAuditors}}`}
+
+        {btr && `{{#contract_terms.hasExchanges}}`}
+        {!exchangesList.length ? null : (
+          <section>
+            <h2>Exchanges accepted by the merchant</h2>
+            <TableExpanded>
+              {btr && "{{" + "#contract_terms.exchanges" + "}}"}
+              {exchangesList.map((p, i) => {
+                return (
+                  <Fragment key={i}>
+                    <dt>Exchange's URL:</dt>
+                    <dd>{p.url || `{{url}}`}</dd>
+                    <dt>Public key:</dt>
+                    <dd>{p.master_pub || `{{master_pub}}`}</dd>
+                  </Fragment>
+                );
+              })}
+              {btr && "{{" + "/contract_terms.exchanges" + "}}"}
+            </TableExpanded>
+          </section>
+        )}
+        {btr && `{{/contract_terms.hasExchanges}}`}
+      </section>
+
+      <Footer />
+    </Page>
+  );
+}
+
+export function mount(): void {
+  try {
+    const fromLocation = new URL(window.location.href).searchParams;
+    const os = fromLocation.get("order_summary") || undefined;
+    if (os) {
+      render(<Head order_summary={os} />, document.head);
+    }
+
+    const ra = fromLocation.get("refund_amount") || undefined;
+    const ct = fromLocation.get("contract_terms") || undefined;
+
+    let contractTerms: MerchantBackend.ContractTerms | undefined;
+    try {
+      contractTerms = JSON.parse((window as any).contractTermsStr);
+    } catch {}
+
+    render(
+      <ShowOrderDetails
+        contract_terms={contractTerms}
+        order_summary={os}
+        refund_amount={ra}
+      />,
+      document.body
+    );
+  } catch (e) {
+    console.error("got error", e);
+    if (e instanceof Error) {
+      document.body.innerText = `Fatal error: "${e.message}".  Please report 
this bug at https://bugs.gnunet.org/.`;
+    }
+  }
+}
+
+export function buildTimeRendering(): { head: string; body: string } {
+  return {
+    head: renderToString(<Head />),
+    body: renderToString(<ShowOrderDetails btr />),
+  };
+}
diff --git a/packages/merchant-backend-ui/src/styled/index.tsx 
b/packages/merchant-backend-ui/src/styled/index.tsx
new file mode 100644
index 000000000..55803b9cd
--- /dev/null
+++ b/packages/merchant-backend-ui/src/styled/index.tsx
@@ -0,0 +1,178 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import { styled } from '@linaria/react'
+
+export const QRPlaceholder = styled.div`
+  margin: auto;
+  text-align: center;
+  width: 340px; 
+`
+
+export const FooterBar = styled.footer`
+  text-align: center;
+  background-color: #033;
+  color: white;
+  padding: 1em;
+  overflow: auto;
+
+  & > p > a:link,
+  & > p > a:visited,
+  & > p > a:hover,
+  & > p > a:active {
+    color: white;
+  }
+`
+
+export const Page = styled.div`
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  min-height: 100vh;
+  align-items: center;
+  
+  a:link,
+  a:visited,
+  a:hover,
+  a:active {
+    color: black;
+  }
+  
+  section {
+    text-align: center;
+    width: 600px;
+    /* margin: auto; */
+    /* margin-top: 0px; */
+    margin-bottom: auto;
+    /* overflow: auto; */
+  }
+  section:not(:first-of-type) {
+    margin-top: 2em;
+  }
+  & > header {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    text-align: center;
+  }
+  & > footer {
+    display: flex;    
+    flex-direction: row;
+    justify-content: space-around;
+    width: 100%;
+    margin-bottom: 0px;
+  }
+`
+export const Center = styled.div`
+  display: flex;
+  justify-content: center;
+`
+
+export const WalletLink = styled.a<{ upperCased?: boolean }>`
+  display: inline-block;
+  zoom: 1;
+  line-height: normal;
+  white-space: nowrap;
+  vertical-align: middle;
+  text-align: center;
+  cursor: pointer;
+  user-select: none;
+  box-sizing: border-box;
+  text-transform: ${({ upperCased }) => upperCased ? 'uppercase' : 'none'};
+
+  font-family: inherit;
+  font-size: 100%;
+  padding: 0.5em 1em;
+  color: #444; /* rgba not supported (IE 8) */
+  color: rgba(0, 0, 0, 0.8); /* rgba supported */
+  border: 1px solid #999; /*IE 6/7/8*/
+  border: none rgba(0, 0, 0, 0); /*IE9 + everything else*/
+  background-color: '#e6e6e6';
+  text-decoration: none;
+  border-radius: 2px;
+
+  :focus {
+    outline: 0;
+  }
+
+  &:disabled {
+    border: none;
+    background-image: none;
+    /* csslint ignore:start */
+    filter: alpha(opacity=40);
+    /* csslint ignore:end */
+    opacity: 0.4;
+    cursor: not-allowed;
+    box-shadow: none;
+    pointer-events: none;
+  }
+
+  :hover {
+    filter: alpha(opacity=90);
+    background-image: linear-gradient(
+      transparent,
+      rgba(0, 0, 0, 0.05) 40%,
+      rgba(0, 0, 0, 0.1)
+    );
+  }
+
+  background-color: #e6e6e6;
+  border-radius: 4px;
+  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
+  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.15) inset,
+    0 0 6px rgba(0, 0, 0, 0.2) inset;
+  border-color: #000;
+`;
+
+export const InfoBox = styled.div`
+  border-radius: 0.25em;
+  flex-direction: column;
+  /* margin: 0.5em; */
+  padding: 1em;
+  /* width: 100%; */
+  border:solid 1px #b8daff;
+  background-color:#cce5ff;
+  color:#004085;
+`
+
+export const TableExpanded = styled.dl`
+  text-align: left;
+  dt {
+    font-weight: bold;
+    margin-top: 1em;
+  }
+  dd {
+    margin-inline-start: 0px;
+  }
+`
+
+export const TableSimple = styled.dl`
+  text-align: left;
+  dt {
+    font-weight: bold;
+    display: inline-block;
+    width:30%;
+  }
+  dd {
+    margin-inline-start: 0px;
+    display: inline-block;
+    width:70%;
+  }
+`
\ No newline at end of file
diff --git a/packages/merchant-backend-ui/src/utils/amount.ts 
b/packages/merchant-backend-ui/src/utils/amount.ts
new file mode 100644
index 000000000..85f230427
--- /dev/null
+++ b/packages/merchant-backend-ui/src/utils/amount.ts
@@ -0,0 +1,69 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+import { amountFractionalBase, AmountJson, Amounts } from 
"@gnu-taler/taler-util";
+import { MerchantBackend } from "../declaration";
+
+/**
+ * sums two prices, 
+ * @param one 
+ * @param two 
+ * @returns 
+ */
+const sumPrices = (one: string, two: string) => {
+  const [currency, valueOne] = one.split(':')
+  const [, valueTwo] = two.split(':')
+  return `${currency}:${parseInt(valueOne, 10) + parseInt(valueTwo, 10)}`
+}
+
+/**
+ * merge refund with the same description and a difference less than one minute
+ * @param prev list of refunds that will hold the merged refunds 
+ * @param cur new refund to add to the list
+ * @returns list with the new refund, may be merged with the last
+ */
+export function mergeRefunds(prev: MerchantBackend.Orders.RefundDetails[], 
cur: MerchantBackend.Orders.RefundDetails) {
+  let tail;
+
+  if (prev.length === 0 ||  //empty list
+    cur.timestamp.t_s === 'never' || //current doesnt have timestamp
+    (tail = prev[prev.length - 1]).timestamp.t_s === 'never' || // last doesnt 
have timestamp
+    cur.reason !== tail.reason || //different reason
+    Math.abs(cur.timestamp.t_s - tail.timestamp.t_s) > 1000 * 60) {//more than 
1 minute difference
+
+    prev.push(cur)
+    return prev
+  }
+
+  prev[prev.length - 1] = {
+    ...tail,
+    amount: sumPrices(tail.amount, cur.amount)
+  }
+
+  return prev
+}
+
+export const rate = (one: string, two: string) => {
+  const a = Amounts.parseOrThrow(one)
+  const b = Amounts.parseOrThrow(two)
+  const af = toFloat(a)
+  const bf = toFloat(b)
+  if (bf === 0) return 0
+  return af / bf
+}
+
+function toFloat(amount: AmountJson) {
+  return amount.value + (amount.fraction / amountFractionalBase);
+}
diff --git a/packages/merchant-backend-ui/src/utils/constants.ts 
b/packages/merchant-backend-ui/src/utils/constants.ts
new file mode 100644
index 000000000..37c46e4c2
--- /dev/null
+++ b/packages/merchant-backend-ui/src/utils/constants.ts
@@ -0,0 +1,47 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+//https://tools.ietf.org/html/rfc8905
+export const PAYTO_REGEX = 
/^payto:\/\/[a-zA-Z][a-zA-Z0-9-.]+(\/[a-zA-Z0-9\-\.\~\(\)@_%:!$&'*+,;=]*)*\??((amount|receiver-name|sender-name|instruction|message)=[a-zA-Z0-9\-\.\~\(\)@_%:!$'*+,;=]*&?)*$/
+export const PAYTO_WIRE_METHOD_LOOKUP = 
/payto:\/\/([a-zA-Z][a-zA-Z0-9-.]+)\/.*/
+
+export const AMOUNT_REGEX = /^[a-zA-Z][a-zA-Z]*:[0-9][0-9,]*\.?[0-9,]*$/
+
+export const INSTANCE_ID_LOOKUP = /^\/instances\/([^/]*)\/?$/
+
+export const AMOUNT_ZERO_REGEX = /^[a-zA-Z][a-zA-Z]*:0$/
+
+export const CROCKFORD_BASE32_REGEX = 
/^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]+[*~$=U]*$/
+
+export const URL_REGEX = 
/^((https?:)(\/\/\/?)([\w]*(?::[\w]*)?@)?([\d\w\.-]+)(?::(\d+))?)\/$/
+
+// how much rows we add every time user hit load more
+export const PAGE_SIZE = 20
+// how bigger can be the result set
+// after this threshold, load more with move the cursor
+export const MAX_RESULT_SIZE = PAGE_SIZE * 2 - 1;
+
+// how much we will wait for all request, in seconds
+export const DEFAULT_REQUEST_TIMEOUT = 10;
+
+export const MAX_IMAGE_SIZE = 1024 * 1024;
+
+export const INSTANCE_ID_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9_.@-]+$/
diff --git a/packages/merchant-backend-ui/src/utils/table.ts 
b/packages/merchant-backend-ui/src/utils/table.ts
new file mode 100644
index 000000000..3d713a6f7
--- /dev/null
+++ b/packages/merchant-backend-ui/src/utils/table.ts
@@ -0,0 +1,37 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+import { WithId } from "../declaration";
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+export interface Actions<T extends WithId> {
+  element: T;
+  type: 'DELETE' | 'UPDATE';
+}
+
+function notEmpty<TValue>(value: TValue | null | undefined): value is TValue {
+  return value !== null && value !== undefined;
+}
+
+export function buildActions<T extends WithId>(intances: T[], selected: 
string[], action: 'DELETE'): Actions<T>[] {
+  return selected.map(id => intances.find(i => i.id === id))
+    .filter(notEmpty)
+    .map(id => ({ element: id, type: action }))
+}
diff --git a/packages/merchant-backend-ui/src/utils/types.ts 
b/packages/merchant-backend-ui/src/utils/types.ts
new file mode 100644
index 000000000..9e49d39e1
--- /dev/null
+++ b/packages/merchant-backend-ui/src/utils/types.ts
@@ -0,0 +1,31 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+import { VNode } from "preact"
+
+export interface KeyValue {
+  [key: string]: string;
+}
+
+export interface Notification {
+  message: string;
+  description?: string | VNode;
+  type: MessageType;
+}
+
+export type ValueOrFunction<T> = T | ((p: T) => T)
+export type MessageType = 'INFO' | 'WARN' | 'ERROR' | 'SUCCESS'
+
diff --git a/packages/merchant-backend-ui/tests/__mocks__/browserMocks.ts 
b/packages/merchant-backend-ui/tests/__mocks__/browserMocks.ts
new file mode 100644
index 000000000..ee6bba505
--- /dev/null
+++ b/packages/merchant-backend-ui/tests/__mocks__/browserMocks.ts
@@ -0,0 +1,42 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+// Mock Browser API's which are not supported by JSDOM, e.g. ServiceWorker, 
LocalStorage
+/**
+ * An example how to mock localStorage is given below 👇
+ */
+
+/* 
+// Mocks localStorage
+const localStorageMock = (function() {
+       let store = {};
+
+       return {
+               getItem: (key) => store[key] || null,
+               setItem: (key, value) => store[key] = value.toString(),
+               clear: () => store = {}
+       };
+
+})();
+
+Object.defineProperty(window, 'localStorage', {
+       value: localStorageMock
+}); */
diff --git a/packages/merchant-backend-ui/tests/__mocks__/fileMocks.ts 
b/packages/merchant-backend-ui/tests/__mocks__/fileMocks.ts
new file mode 100644
index 000000000..0c045e9d1
--- /dev/null
+++ b/packages/merchant-backend-ui/tests/__mocks__/fileMocks.ts
@@ -0,0 +1,24 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+// This fixed an error related to the CSS and loading gif breaking my Jest test
+// See 
https://facebook.github.io/jest/docs/en/webpack.html#handling-static-assets
+export default 'test-file-stub';
diff --git a/packages/merchant-backend-ui/tests/__mocks__/fileTransformer.js 
b/packages/merchant-backend-ui/tests/__mocks__/fileTransformer.js
new file mode 100644
index 000000000..51ebbfa62
--- /dev/null
+++ b/packages/merchant-backend-ui/tests/__mocks__/fileTransformer.js
@@ -0,0 +1,31 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+// fileTransformer.js
+
+// eslint-disable-next-line @typescript-eslint/no-var-requires
+const path = require('path');
+
+module.exports = {
+    process(src, filename, config, options) {
+        return `module.exports = ${  JSON.stringify(path.basename(filename))  
};`;
+    },
+};
+
diff --git a/packages/merchant-backend-ui/tests/__mocks__/setupTests.ts 
b/packages/merchant-backend-ui/tests/__mocks__/setupTests.ts
new file mode 100644
index 000000000..ab0f08b2f
--- /dev/null
+++ b/packages/merchant-backend-ui/tests/__mocks__/setupTests.ts
@@ -0,0 +1,28 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import 'regenerator-runtime/runtime'
+import { configure } from 'enzyme';
+import Adapter from 'enzyme-adapter-preact-pure';
+
+configure({
+    adapter: new Adapter()
+});
diff --git a/packages/merchant-backend-ui/tests/funcitons/regex.test.ts 
b/packages/merchant-backend-ui/tests/funcitons/regex.test.ts
new file mode 100644
index 000000000..fc8a6a42f
--- /dev/null
+++ b/packages/merchant-backend-ui/tests/funcitons/regex.test.ts
@@ -0,0 +1,87 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { AMOUNT_REGEX, PAYTO_REGEX } from "../../src/utils/constants";
+
+describe('payto uri format', () => {
+  const valids = [
+    'payto://iban/DE75512108001245126199?amount=EUR:200.0&message=hello',
+    'payto://ach/122000661/1234',
+    'payto://upi/alice@example.com?receiver-name=Alice&amount=INR:200',
+    'payto://void/?amount=EUR:10.5',
+    'payto://ilp/g.acme.bob'
+  ]
+  
+  test('should be valid', () => {
+    valids.forEach(v => expect(v).toMatch(PAYTO_REGEX))
+  });
+  
+  const invalids = [
+    // has two question marks
+    'payto://iban/DE75?512108001245126199?amount=EUR:200.0&message=hello',
+    // has a space
+    'payto://ach /122000661/1234',
+    // has a space
+    'payto://upi/alice@ example.com?receiver-name=Alice&amount=INR:200',
+    // invalid field name (mount instead of amount)
+    'payto://void/?mount=EUR:10.5',
+    // payto:// is incomplete
+    'payto: //ilp/g.acme.bob'
+  ]
+  
+  test('should not be valid', () => {
+    invalids.forEach(v => expect(v).not.toMatch(PAYTO_REGEX))
+  });  
+})
+
+describe('amount format', () => {
+  const valids = [
+    'ARS:10',
+    'COL:10.2',
+    'UY:1,000.2',
+    'ARS:10.123,123',
+    'ARS:1,000,000',
+    'ARSCOL:10',
+    'THISISTHEMOTHERCOIN:1,000,000.123,123',
+  ]
+  
+  test('should be valid', () => {
+    valids.forEach(v => expect(v).toMatch(AMOUNT_REGEX))
+  });
+  
+  const invalids = [
+    //no currency name
+    ':10',
+    //use . instead of ,
+    'ARS:1.000.000',
+    //currency name with numbers
+    '1ARS:10',
+    //currency name with numbers
+    'AR5:10',
+    //missing value
+    'USD:',
+  ]
+  
+  test('should not be valid', () => {
+    invalids.forEach(v => expect(v).not.toMatch(AMOUNT_REGEX))
+  });  
+
+})
\ No newline at end of file
diff --git a/packages/merchant-backend-ui/tests/util.ts 
b/packages/merchant-backend-ui/tests/util.ts
new file mode 100644
index 000000000..14b82b51c
--- /dev/null
+++ b/packages/merchant-backend-ui/tests/util.ts
@@ -0,0 +1,62 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import * as axios from 'axios';
+
+type Query<Req, Res> = (GetQuery | PostQuery | DeleteQuery | PatchQuery) & 
RequestResponse<Req, Res>
+
+interface RequestResponse<Req, Res> {
+  request?: Req,
+  params?: any,
+  response?: Res,
+}
+interface GetQuery { get: string }
+interface PostQuery { post: string }
+interface DeleteQuery { delete: string }
+interface PatchQuery { patch: string }
+
+export function simulateBackendResponse<R, T>(query: Query<R, T>): void {
+  (axios.default as 
jest.MockedFunction<axios.AxiosStatic>).mockImplementationOnce(function (opt?: 
axios.AxiosRequestConfig): axios.AxiosPromise {
+      // console.log(opt, JSON.stringify(query,undefined,2))
+      expect(opt).toBeDefined();
+      if (!opt)
+        return Promise.reject();
+
+      // expect(query.request).toStrictEqual(opt.data);
+      // expect(query.params).toStrictEqual(opt.params);
+      if ('get' in query) {
+        expect(opt.method).toBe('get');
+        expect(opt.url).toBe(query.get);
+      }
+      if ('post' in query) {
+        expect(opt.method).toBe('post');
+        expect(opt.url).toBe(query.post);
+      }
+      if ('delete' in query) {
+        expect(opt.method).toBe('delete');
+        expect(opt.url).toBe(query.delete);
+      }
+      if ('patch' in query) {
+        expect(opt.method).toBe('patch');
+        expect(opt.url).toBe(query.patch);
+      }
+      return ({ data: query.response, config: {} } as any);
+    } as any)
+}
diff --git a/packages/merchant-backend-ui/tsconfig.back.json 
b/packages/merchant-backend-ui/tsconfig.back.json
new file mode 100644
index 000000000..9ac5a3c25
--- /dev/null
+++ b/packages/merchant-backend-ui/tsconfig.back.json
@@ -0,0 +1,23 @@
+{
+    "compilerOptions": {
+      "composite": true,
+      "lib": ["es6", "DOM"],
+      "jsx": "react",
+      "jsxFactory": "h",
+      "jsxFragmentFactory": "Fragment",
+      "moduleResolution": "Node",
+      "module": "ESNext",
+      "target": "ES6",
+      "noImplicitAny": true,
+      "noEmitOnError": true,
+      "strict": true,
+      "incremental": true,
+      "sourceMap": true,
+      "esModuleInterop": true,
+      "importHelpers": true,
+      "rootDir": "./src",
+      "typeRoots": ["./node_modules/@types"]
+    },
+    "include": ["src/**/*"]
+  }
+  
\ No newline at end of file
diff --git a/packages/merchant-backend-ui/tsconfig.json 
b/packages/merchant-backend-ui/tsconfig.json
new file mode 100644
index 000000000..7a4d70a17
--- /dev/null
+++ b/packages/merchant-backend-ui/tsconfig.json
@@ -0,0 +1,61 @@
+{
+  "compilerOptions": {
+      /* Basic Options */
+      "target": "ES6",                          /* Specify ECMAScript target 
version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
+      "module": "ESNext",                       /* Specify module code 
generation: 'none', commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
+      // "lib": [],                             /* Specify library files to be 
included in the compilation:  */
+      "allowJs": true,                          /* Allow javascript files to 
be compiled. */
+      // "checkJs": true,                       /* Report errors in .js files. 
*/
+      "jsx": "react",                           /* Specify JSX code 
generation: 'preserve', 'react-native', or 'react'. */
+      "jsxFactory": "h",                        /* Specify the JSX factory 
function to use when targeting react JSX emit, e.g. React.createElement or h. */
+      "jsxFragmentFactory": "Fragment",         // 
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-0.html#custom-jsx-factories
+      // "declaration": true,                   /* Generates corresponding 
'.d.ts' file. */
+      // "sourceMap": true,                     /* Generates corresponding 
'.map' file. */
+      // "outFile": "./",                       /* Concatenate and emit output 
to single file. */
+      // "outDir": "./",                        /* Redirect output structure 
to the directory. */
+      // "rootDir": "./",                       /* Specify the root directory 
of input files. Use to control the output directory structure with --outDir. */
+      // "removeComments": true,                /* Do not emit comments to 
output. */
+      "noEmit": true,                           /* Do not emit outputs. */
+      // "importHelpers": true,                 /* Import emit helpers from 
'tslib'. */
+      // "downlevelIteration": true,            /* Provide full support for 
iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. 
*/
+      // "isolatedModules": true,               /* Transpile each file as a 
separate module (similar to 'ts.transpileModule'). */
+
+      /* Strict Type-Checking Options */
+      "strict": true,                           /* Enable all strict 
type-checking options. */
+      // "noImplicitAny": true,                 /* Raise error on expressions 
and declarations with an implied 'any' type. */
+      // "strictNullChecks": true,              /* Enable strict null checks. 
*/
+      // "noImplicitThis": true,                /* Raise error on 'this' 
expressions with an implied 'any' type. */
+      // "alwaysStrict": true,                  /* Parse in strict mode and 
emit "use strict" for each source file. */
+
+      /* Additional Checks */
+      // "noUnusedLocals": true,                /* Report errors on unused 
locals. */
+      // "noUnusedParameters": true,            /* Report errors on unused 
parameters. */
+      // "noImplicitReturns": true,             /* Report error when not all 
code paths in function return a value. */
+      // "noFallthroughCasesInSwitch": true,    /* Report errors for 
fallthrough cases in switch statement. */
+
+      /* Module Resolution Options */
+      "moduleResolution": "node",               /* Specify module resolution 
strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
+      "esModuleInterop": true,                  /* */
+      // "baseUrl": "./",                       /* Base directory to resolve 
non-absolute module names. */
+      // "paths": {},                           /* A series of entries which 
re-map imports to lookup locations relative to the 'baseUrl'. */
+      // "rootDirs": [],                        /* List of root folders whose 
combined content represents the structure of the project at runtime. */
+      // "typeRoots": [],                       /* List of folders to include 
type definitions from. */
+      // "types": [],                           /* Type declaration files to 
be included in compilation. */
+      // "allowSyntheticDefaultImports": true,  /* Allow default imports from 
modules with no default export. This does not affect code emit, just 
typechecking. */
+      // "preserveSymlinks": true,              /* Do not resolve the real 
path of symlinks. */
+
+      /* Source Map Options */
+      // "sourceRoot": "./",                    /* Specify the location where 
debugger should locate TypeScript files instead of source locations. */
+      // "mapRoot": "./",                       /* Specify the location where 
debugger should locate map files instead of generated locations. */
+      // "inlineSourceMap": true,               /* Emit a single file with 
source maps instead of having a separate file. */
+      // "inlineSources": true,                 /* Emit the source alongside 
the sourcemaps within a single file; requires '--inlineSourceMap' or 
'--sourceMap' to be set. */
+
+      /* Experimental Options */
+      // "experimentalDecorators": true,        /* Enables experimental 
support for ES7 decorators. */
+      // "emitDecoratorMetadata": true,         /* Enables experimental 
support for emitting type metadata for decorators. */
+
+      /* Advanced Options */
+      "skipLibCheck": true                      /* Skip type checking of 
declaration files. */
+  },
+  "include": ["src/**/*", "tests/**/*"]
+}
diff --git a/packages/merchant-backoffice-ui/.gitignore 
b/packages/merchant-backoffice-ui/.gitignore
new file mode 100644
index 000000000..df149101c
--- /dev/null
+++ b/packages/merchant-backoffice-ui/.gitignore
@@ -0,0 +1,6 @@
+/build
+/size-plugin.json
+/storybook-static
+/docs
+/single
+/coverage
diff --git a/packages/merchant-backoffice-ui/.storybook/.babelrc 
b/packages/merchant-backoffice-ui/.storybook/.babelrc
new file mode 100644
index 000000000..610b6f339
--- /dev/null
+++ b/packages/merchant-backoffice-ui/.storybook/.babelrc
@@ -0,0 +1,25 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+{
+    "presets": [
+        "preact-cli/babel"
+    ]
+}
\ No newline at end of file
diff --git a/packages/merchant-backoffice-ui/.storybook/main.js 
b/packages/merchant-backoffice-ui/.storybook/main.js
new file mode 100644
index 000000000..f8e4bbcc7
--- /dev/null
+++ b/packages/merchant-backoffice-ui/.storybook/main.js
@@ -0,0 +1,57 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+
+module.exports = {
+  "stories": [
+    "../src/**/*.stories.mdx",
+    "../src/**/*.stories.@(js|jsx|ts|tsx)"
+  ],
+  "addons": [
+    "@storybook/preset-scss",
+    "@storybook/addon-a11y",
+    "@storybook/addon-essentials" //docs, control, actions, viewpot, toolbar, 
background
+  ],
+  // sb does not yet support new jsx transform by default
+  // https://github.com/storybookjs/storybook/issues/12881
+  // https://github.com/storybookjs/storybook/issues/12952
+  babel: async (options) => ({
+    ...options,
+    presets: [
+      ...options.presets,
+      [
+        '@babel/preset-react', {
+          runtime: 'automatic',
+        },
+        'preset-react-jsx-transform' 
+      ],
+    ],
+  }),
+  webpackFinal: (config) => {
+    // should be removed after storybook 6.3
+    // 
https://github.com/storybookjs/storybook/issues/12853#issuecomment-821576113
+    config.resolve.alias = {
+      react: "preact/compat",
+      "react-dom": "preact/compat",
+    };
+    return config;
+  },
+}
\ No newline at end of file
diff --git a/packages/merchant-backoffice-ui/.storybook/preview.js 
b/packages/merchant-backoffice-ui/.storybook/preview.js
new file mode 100644
index 000000000..d13103ac9
--- /dev/null
+++ b/packages/merchant-backoffice-ui/.storybook/preview.js
@@ -0,0 +1,74 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+import "../src/scss/main.scss"
+import { ConfigContextProvider } from '../src/context/config'
+import { InstanceContextProvider } from '../src/context/instance'
+import { TranslationProvider } from '../src/context/translation'
+import { BackendContextProvider } from '../src/context/backend'
+import { h } from 'preact';
+
+const mockConfig = {
+  backendURL: 'http://demo.taler.net',
+  currency: 'TESTKUDOS'
+}
+
+const mockInstance = {
+  id: 'instance-id',
+  token: 'instance-token',
+  admin: false,
+}
+
+const mockBackend = {
+  url: 'http://merchant.url',
+  token: 'default-token',
+  triedToLog: false,
+}
+
+export const parameters = {
+  controls: { expanded: true },
+  // actions: { argTypesRegex: "^on.*" },
+}
+
+export const globalTypes = {
+  locale: {
+    name: 'Locale',
+    description: 'Internationalization locale',
+    defaultValue: 'en',
+    toolbar: {
+      icon: 'globe',
+      items: [
+        { value: 'en', right: '🇺🇸', title: 'English' },
+        { value: 'es', right: '🇪🇸', title: 'Spanish' },
+      ],
+    },
+  },
+};
+
+export const decorators = [
+  (Story, { globals }) => <TranslationProvider initial='en' 
forceLang={globals.locale}>
+    <Story />
+  </TranslationProvider>,
+  (Story) => <ConfigContextProvider value={mockConfig}>
+    <Story />
+  </ConfigContextProvider>,
+  (Story) => <InstanceContextProvider value={mockInstance}>
+    <Story />
+  </InstanceContextProvider>,
+  (Story) => <BackendContextProvider defaultUrl={mockBackend.url}>
+    <Story />
+  </BackendContextProvider>,
+];
diff --git a/contrib/po2ts b/packages/merchant-backoffice-ui/contrib/po2ts
similarity index 100%
copy from contrib/po2ts
copy to packages/merchant-backoffice-ui/contrib/po2ts
diff --git a/packages/merchant-backoffice-ui/copyleft-header.js 
b/packages/merchant-backoffice-ui/copyleft-header.js
new file mode 100644
index 000000000..0794cb839
--- /dev/null
+++ b/packages/merchant-backoffice-ui/copyleft-header.js
@@ -0,0 +1,15 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
diff --git a/packages/merchant-backoffice-ui/package.json 
b/packages/merchant-backoffice-ui/package.json
new file mode 100644
index 000000000..ac90dd5cb
--- /dev/null
+++ b/packages/merchant-backoffice-ui/package.json
@@ -0,0 +1,123 @@
+{
+  "private": true,
+  "name": "merchant-backoffice",
+  "version": "0.0.4",
+  "license": "MIT",
+  "scripts": {
+    "build": "preact build --no-sw --no-esm",
+    "compile": "tsc",
+    "serve": "sirv build --port ${PORT:=8080} --cors --single",
+    "dev": "preact watch --port ${PORT:=8080} --no-sw --no-esm",
+    "lint-check": "eslint '{src,tests}/**/*.{js,jsx,ts,tsx}'",
+    "lint-fix": "eslint --fix '{src,tests}/**/*.{js,jsx,ts,tsx}'",
+    "test": "jest ./tests",
+    "dev-test": "jest ./tests --watch",
+    "typedoc": "typedoc src",
+    "clean": "rimraf build storybook-static docs single",
+    "build-single": "preact build --no-sw --no-esm -c preact.single-config.js 
--dest single && sh remove-link-stylesheet.sh",
+    "serve-single": "sirv single --port ${PORT:=8080} --cors --single",
+    "build-storybook": "build-storybook",
+    "storybook": "start-storybook -p 6006"
+  },
+  "engines": {
+    "node": ">=12",
+    "pnpm": ">=5"
+  },
+  "eslintConfig": {
+    "parser": "@typescript-eslint/parser",
+    "extends": [
+      "preact",
+      "plugin:@typescript-eslint/recommended"
+    ],
+    "plugins": [
+      "header"
+    ],
+    "rules": {
+      "header/header": [
+        2,
+        "copyleft-header.js"
+      ]
+    },
+    "ignorePatterns": [
+      "build/"
+    ]
+  },
+  "dependencies": {
+    "@gnu-taler/taler-util": "workspace:*",
+    "axios": "^0.21.1",
+    "date-fns": "^2.21.1",
+    "history": "4.10.1",
+    "jed": "^1.1.1",
+    "preact": "10.6.1",
+    "preact-router": "^3.2.1",
+    "qrcode-generator": "^1.4.4",
+    "swr": "1.1.0",
+    "yup": "^0.32.9"
+  },
+  "devDependencies": {
+    "@babel/core": "^7.13.16",
+    "@babel/plugin-transform-react-jsx-source": "^7.12.13",
+    "@creativebulma/bulma-tooltip": "^1.2.0",
+    "@gnu-taler/pogen": "^0.0.5",
+    "@storybook/addon-a11y": "^6.2.9",
+    "@storybook/addon-actions": "^6.2.9",
+    "@storybook/addon-essentials": "^6.2.9",
+    "@storybook/addon-links": "^6.2.9",
+    "@storybook/preact": "^6.2.9",
+    "@storybook/preset-scss": "^1.0.3",
+    "@testing-library/preact": "^2.0.1",
+    "@testing-library/preact-hooks": "^1.1.0",
+    "@types/history": "^4.7.8",
+    "@types/jest": "^26.0.23",
+    "@types/mocha": "^8.2.2",
+    "@typescript-eslint/eslint-plugin": "^4.22.0",
+    "@typescript-eslint/parser": "^4.22.0",
+    "babel-loader": "^8.2.2",
+    "base64-inline-loader": "^1.1.1",
+    "bulma": "^0.9.2",
+    "bulma-checkbox": "^1.1.1",
+    "bulma-radio": "^1.1.1",
+    "bulma-responsive-tables": "^1.2.3",
+    "bulma-switch-control": "^1.1.1",
+    "bulma-timeline": "^3.0.4",
+    "bulma-upload-control": "^1.2.0",
+    "dotenv": "^8.2.0",
+    "eslint": "^7.25.0",
+    "eslint-config-preact": "^1.1.4",
+    "eslint-plugin-header": "^3.1.1",
+    "html-webpack-inline-chunk-plugin": "^1.1.1",
+    "html-webpack-inline-source-plugin": "0.0.10",
+    "html-webpack-skip-assets-plugin": "^1.0.1",
+    "inline-chunk-html-plugin": "^1.1.1",
+    "jest": "^26.6.3",
+    "jest-preset-preact": "^4.0.2",
+    "po2json": "^0.4.5",
+    "preact-cli": "^3.0.5",
+    "preact-render-to-json": "^3.6.6",
+    "preact-render-to-string": "^5.1.19",
+    "rimraf": "^3.0.2",
+    "sass": "^1.32.13",
+    "sass-loader": "10.1.1",
+    "script-ext-html-webpack-plugin": "^2.1.5",
+    "sirv-cli": "^1.0.11",
+    "typedoc": "^0.20.36",
+    "typescript": "^4.2.4"
+  },
+  "jest": {
+    "preset": "jest-preset-preact",
+    "transformIgnorePatterns": [
+      "node_modules/.pnpm/(?!(@gnu-taler\\+taler-util))",
+      "\\.pnp\\.[^\\/]+$"
+    ],
+    "setupFiles": [
+      "<rootDir>/tests/__mocks__/browserMocks.ts",
+      "<rootDir>/tests/__mocks__/setupTests.ts"
+    ],
+    "moduleNameMapper": {
+      "\\.(css|less)$": "identity-obj-proxy"
+    },
+    "transform": {
+      
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga|po)$":
 "<rootDir>/tests/__mocks__/fileTransformer.js"
+    }
+  }
+}
diff --git a/packages/merchant-backoffice-ui/preact.config.js 
b/packages/merchant-backoffice-ui/preact.config.js
new file mode 100644
index 000000000..8e640f3ff
--- /dev/null
+++ b/packages/merchant-backoffice-ui/preact.config.js
@@ -0,0 +1,70 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { DefinePlugin } from 'webpack';
+
+import pack from './package.json';
+import * as cp from 'child_process';
+
+const commitHash = cp.execSync('git rev-parse --short HEAD').toString();
+
+export default {
+  webpack(config, env, helpers) {
+    // ensure that process.env will not be undefined on runtime
+    config.node.process = 'mock'
+
+    // add __VERSION__ to be use in the html
+    config.plugins.push(
+      new DefinePlugin({
+        'process.env.__VERSION__': JSON.stringify(env.isProd ? pack.version : 
`dev-${commitHash}`) ,
+      }),
+    );
+
+    // suddenly getting out of memory error from build process, error below [1]
+    // FIXME: remove preact-cli, use rollup
+    let { index } = helpers.getPluginsByName(config, 
'WebpackFixStyleOnlyEntriesPlugin')[0]
+    config.plugins.splice(index, 1)   
+  }
+}
+
+
+
+/* [1] from this error decided to remove plugin 'webpack-fix-style-only-entries
+   leaving this error for future reference
+
+
+<--- Last few GCs --->
+
+[32479:0x2e01870]    19969 ms: Mark-sweep 1869.4 (1950.2) -> 1443.1 (1504.1) 
MB, 497.5 / 0.0 ms  (average mu = 0.631, current mu = 0.455) allocation failure 
scavenge might not succeed
+[32479:0x2e01870]    21907 ms: Mark-sweep 2016.9 (2077.9) -> 1628.6 (1681.4) 
MB, 1596.0 / 0.0 ms  (average mu = 0.354, current mu = 0.176) allocation 
failure scavenge might not succeed
+
+<--- JS stacktrace --->
+
+==== JS stack trace =========================================
+
+    0: ExitFrame [pc: 0x13cf099]
+Security context: 0x2f4ca66c08d1 <JSObject>
+    1: /* anonymous * / [0x35d05555b4b9] 
[...path/merchant-backoffice/node_modules/.pnpm/webpack-fix-style-only-entries@0.5.2/node_modules/webpack-fix-style-only-entries/index.js:~80]
 [pc=0x2145e699d1a4](this=0x1149465410e9 <GlobalObject Object map = 
0xff481b5b5f9>,0x047e52e36a49 <Dependency map = 0x1ed1fe41cd19>)
+    2: arguments adaptor frame: 3...
+
+FATAL ERROR: invalid array length Allocation failed - JavaScript heap out of 
memory
+ 
+*/
\ No newline at end of file
diff --git a/packages/merchant-backoffice-ui/preact.single-config.js 
b/packages/merchant-backoffice-ui/preact.single-config.js
new file mode 100644
index 000000000..61a79bb8a
--- /dev/null
+++ b/packages/merchant-backoffice-ui/preact.single-config.js
@@ -0,0 +1,62 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import defaultConfig from './preact.config'
+
+export default {
+  webpack(config, env, helpers, options) {
+    defaultConfig.webpack(config, env, helpers, options)
+
+    //1. check no file is under /routers or /component/{routers,async} to 
prevent async components
+    // https://github.com/preactjs/preact-cli#route-based-code-splitting
+
+    //2. remove devtools to prevent sourcemaps
+    config.devtool = false
+
+    //3. change assetLoader to load assets inline
+    const loaders = helpers.getLoaders(config)
+    const assetsLoader = loaders.find(lo => 
lo.rule.test.test('something.woff'))
+    if (assetsLoader) {
+      assetsLoader.rule.use = 'base64-inline-loader'
+      assetsLoader.rule.loader = undefined
+    }
+
+    //4. remove critters
+    //critters remove the css bundle from htmlWebpackPlugin.files.css
+    //for now, pushing all the content into the html is enough
+    const crittersWrapper = helpers.getPluginsByName(config, 'Critters')
+    if (crittersWrapper && crittersWrapper.length > 0) {
+      const [{ index }] = crittersWrapper
+      config.plugins.splice(index, 1)
+    }
+
+    //5. remove favicon from src/assets
+
+    //6. remove performance hints since we now that this is going to be big
+    if (config.performance) {
+      config.performance.hints = false
+    }
+
+    //7. template.html should have a favicon and add js/css content
+
+    //last, after building remove the mysterious link to stylesheet with 
remove-link-stylesheet.sh
+  }
+}
diff --git a/packages/merchant-backoffice-ui/remove-link-stylesheet.sh 
b/packages/merchant-backoffice-ui/remove-link-stylesheet.sh
new file mode 100644
index 000000000..fdf8f241c
--- /dev/null
+++ b/packages/merchant-backoffice-ui/remove-link-stylesheet.sh
@@ -0,0 +1,8 @@
+# This script has been placed in the public domain.
+
+FILE=$(ls single/bundle.*.css)
+BUNDLE=${FILE#single}
+grep -q '<link href="'$BUNDLE'" rel="stylesheet">' single/index.html || { echo 
bundle $BUNDLE not found in index.html; exit 1; }
+echo -n Removing link from index.html ...
+sed 's_<link href="'$BUNDLE'" rel="stylesheet">__' -i single/index.html
+echo done
diff --git a/packages/merchant-backoffice-ui/src/.babelrc 
b/packages/merchant-backoffice-ui/src/.babelrc
new file mode 100644
index 000000000..3ec8a6291
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/.babelrc
@@ -0,0 +1,26 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+{
+    "presets": [ 
+        "preact-cli/babel"
+    ]
+}
diff --git a/packages/merchant-backoffice-ui/src/AdminRoutes.tsx 
b/packages/merchant-backoffice-ui/src/AdminRoutes.tsx
new file mode 100644
index 000000000..a3ffbe2e6
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/AdminRoutes.tsx
@@ -0,0 +1,58 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+import { h, VNode } from "preact";
+import Router, { route, Route } from "preact-router";
+import InstanceCreatePage from "./paths/admin/create";
+import InstanceListPage from './paths/admin/list';
+
+
+export enum AdminPaths {
+  list_instances = '/instances',
+  new_instance = '/instance/new',
+}
+
+export function AdminRoutes(): VNode {
+  
+  return <Router>
+
+    <Route path={AdminPaths.list_instances} component={InstanceListPage}
+
+      onCreate={() => {
+        route(AdminPaths.new_instance);
+      }}
+
+      onUpdate={(id: string): void => {
+        route(`/instance/${id}/update`);
+      }}
+
+    />
+
+    <Route path={AdminPaths.new_instance} component={InstanceCreatePage}
+
+      onBack={() => route(AdminPaths.list_instances)}
+
+      onConfirm={() => {
+        // route(AdminPaths.list_instances);
+      }}
+
+      // onError={(error: any) => {
+      // }}
+      
+    />
+
+
+  </Router>
+}
\ No newline at end of file
diff --git a/packages/merchant-backoffice-ui/src/ApplicationReadyRoutes.tsx 
b/packages/merchant-backoffice-ui/src/ApplicationReadyRoutes.tsx
new file mode 100644
index 000000000..ebc3d1d95
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/ApplicationReadyRoutes.tsx
@@ -0,0 +1,120 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { Fragment, h, VNode } from "preact";
+import Router, { Route, route } from "preact-router";
+import { useBackendContext } from "./context/backend";
+import { useBackendInstancesTestForAdmin } from "./hooks/backend";
+import { InstanceRoutes } from "./InstanceRoutes";
+import LoginPage from "./paths/login";
+import { INSTANCE_ID_LOOKUP } from "./utils/constants";
+import { NotYetReadyAppMenu, Menu, NotificationCard } from "./components/menu";
+import { useTranslator } from "./i18n";
+import { createHashHistory } from "history";
+import { useState } from "preact/hooks";
+
+export function ApplicationReadyRoutes(): VNode {
+  const i18n = useTranslator();
+  const {
+    url: backendURL,
+    updateLoginStatus,
+    clearAllTokens,
+  } = useBackendContext();
+
+  const result = useBackendInstancesTestForAdmin();
+
+  const clearTokenAndGoToRoot = () => {
+    clearAllTokens();
+    route("/");
+  };
+
+  if (result.clientError && result.isUnauthorized) {
+    return (
+      <Fragment>
+        <NotYetReadyAppMenu title="Login" onLogout={clearTokenAndGoToRoot} />
+        <NotificationCard
+          notification={{
+            message: i18n`Access denied`,
+            description: i18n`Check your token is valid`,
+            type: "ERROR",
+          }}
+        />
+        <LoginPage onConfirm={updateLoginStatus} />
+      </Fragment>
+    );
+  }
+
+  if (result.loading) return <NotYetReadyAppMenu title="Loading..." />;
+
+  let admin = true;
+  let instanceNameByBackendURL;
+
+  if (!result.ok) {
+    const path = new URL(backendURL).pathname;
+    const match = INSTANCE_ID_LOOKUP.exec(path);
+    if (!match || !match[1]) {
+      // this should be rare because
+      // query to /config is ok but the URL
+      // does not match our pattern
+      return (
+        <Fragment>
+          <NotYetReadyAppMenu title="Error" onLogout={clearTokenAndGoToRoot} />
+          <NotificationCard
+            notification={{
+              message: i18n`Couldn't access the server.`,
+              description: i18n`Could not infer instance id from url 
${backendURL}`,
+              type: "ERROR",
+            }}
+          />
+          <LoginPage onConfirm={updateLoginStatus} />
+        </Fragment>
+      );
+    }
+
+    admin = false;
+    instanceNameByBackendURL = match[1];
+  }
+
+  const history = createHashHistory();
+  return (
+    <Router history={history}>
+      <Route
+        default
+        component={DefaultMainRoute}
+        admin={admin}
+        instanceNameByBackendURL={instanceNameByBackendURL}
+      />
+    </Router>
+  );
+}
+
+function DefaultMainRoute({ instance, admin, instanceNameByBackendURL }: any) {
+  const [instanceName, setInstanceName] = useState(
+    instanceNameByBackendURL || instance || "default"
+  );
+
+  return (
+    <InstanceRoutes
+      admin={admin}
+      id={instanceName}
+      setInstanceName={setInstanceName}
+    />
+  );
+}
diff --git a/packages/merchant-backoffice-ui/src/InstanceRoutes.tsx 
b/packages/merchant-backoffice-ui/src/InstanceRoutes.tsx
new file mode 100644
index 000000000..06f1db17c
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/InstanceRoutes.tsx
@@ -0,0 +1,528 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { Fragment, FunctionComponent, h, VNode } from "preact";
+import { Route, route, Router } from "preact-router";
+import { useCallback, useEffect, useMemo, useState } from "preact/hooks";
+import { Loading } from "./components/exception/loading";
+import { Menu, NotificationCard } from "./components/menu";
+import { useBackendContext } from "./context/backend";
+import { InstanceContextProvider } from "./context/instance";
+import {
+  useBackendDefaultToken,
+  useBackendInstanceToken,
+  useLocalStorage,
+} from "./hooks";
+import { HttpError } from "./hooks/backend";
+import { Translate, useTranslator } from "./i18n";
+import InstanceCreatePage from "./paths/admin/create";
+import InstanceListPage from "./paths/admin/list";
+import OrderCreatePage from "./paths/instance/orders/create";
+import OrderDetailsPage from "./paths/instance/orders/details";
+import OrderListPage from "./paths/instance/orders/list";
+import ProductCreatePage from "./paths/instance/products/create";
+import ProductListPage from "./paths/instance/products/list";
+import ProductUpdatePage from "./paths/instance/products/update";
+import TransferListPage from "./paths/instance/transfers/list";
+import TransferCreatePage from "./paths/instance/transfers/create";
+import ReservesCreatePage from "./paths/instance/reserves/create";
+import ReservesDetailsPage from "./paths/instance/reserves/details";
+import ReservesListPage from "./paths/instance/reserves/list";
+import ListKYCPage from "./paths/instance/kyc/list";
+import InstanceUpdatePage, {
+  Props as InstanceUpdatePageProps,
+  AdminUpdate as InstanceAdminUpdatePage,
+} from "./paths/instance/update";
+import LoginPage from "./paths/login";
+import NotFoundPage from "./paths/notfound";
+import { Notification } from "./utils/types";
+import { useInstanceKYCDetails } from "./hooks/instance";
+import { format } from "date-fns";
+
+export enum InstancePaths {
+  // details = '/',
+  error = "/error",
+  update = "/update",
+
+  product_list = "/products",
+  product_update = "/product/:pid/update",
+  product_new = "/product/new",
+
+  order_list = "/orders",
+  order_new = "/order/new",
+  order_details = "/order/:oid/details",
+
+  reserves_list = "/reserves",
+  reserves_details = "/reserves/:rid/details",
+  reserves_new = "/reserves/new",
+
+  kyc = "/kyc",
+
+  transfers_list = "/transfers",
+  transfers_new = "/transfer/new",
+}
+
+// eslint-disable-next-line @typescript-eslint/no-empty-function
+const noop = () => {};
+
+export enum AdminPaths {
+  list_instances = "/instances",
+  new_instance = "/instance/new",
+  update_instance = "/instance/:id/update",
+}
+
+export interface Props {
+  id: string;
+  admin?: boolean;
+  setInstanceName: (s: string) => void;
+}
+
+export function InstanceRoutes({ id, admin, setInstanceName }: Props): VNode {
+  const [_, updateDefaultToken] = useBackendDefaultToken();
+  const [token, updateToken] = useBackendInstanceToken(id);
+  const {
+    updateLoginStatus: changeBackend,
+    addTokenCleaner,
+    clearAllTokens,
+  } = useBackendContext();
+  const cleaner = useCallback(() => {
+    updateToken(undefined);
+  }, [id]);
+  const i18n = useTranslator();
+
+  type GlobalNotifState = (Notification & { to: string }) | undefined;
+  const [globalNotification, setGlobalNotification] =
+    useState<GlobalNotifState>(undefined);
+
+  useEffect(() => {
+    addTokenCleaner(cleaner);
+  }, [addTokenCleaner, cleaner]);
+
+  const changeToken = (token?: string) => {
+    if (admin) {
+      updateToken(token);
+    } else {
+      updateDefaultToken(token);
+    }
+  };
+  const updateLoginStatus = (url: string, token?: string) => {
+    changeBackend(url);
+    if (!token) return;
+    changeToken(token);
+  };
+
+  const value = useMemo(
+    () => ({ id, token, admin, changeToken }),
+    [id, token, admin]
+  );
+
+  function ServerErrorRedirectTo(to: InstancePaths | AdminPaths) {
+    return function ServerErrorRedirectToImpl(error: HttpError) {
+      setGlobalNotification({
+        message: i18n`The backend reported a problem: HTTP status 
#${error.status}`,
+        description: i18n`Diagnostic from ${error.info?.url} is 
"${error.message}"`,
+        details:
+          error.clientError || error.serverError
+            ? error.error?.detail
+            : undefined,
+        type: "ERROR",
+        to,
+      });
+      return <Redirect to={to} />;
+    };
+  }
+
+  const LoginPageAccessDenied = () => (
+    <Fragment>
+      <NotificationCard
+        notification={{
+          message: i18n`Access denied`,
+          description: i18n`The access token provided is invalid.`,
+          type: "ERROR",
+        }}
+      />
+      <LoginPage onConfirm={updateLoginStatus} />
+    </Fragment>
+  );
+
+  function IfAdminCreateDefaultOr<T>(Next: FunctionComponent<any>) {
+    return function IfAdminCreateDefaultOrImpl(props?: T) {
+      if (admin && id === "default") {
+        return (
+          <Fragment>
+            <NotificationCard
+              notification={{
+                message: i18n`No 'default' instance configured yet.`,
+                description: i18n`Create a 'default' instance to begin using 
the merchant backoffice.`,
+                type: "INFO",
+              }}
+            />
+            <InstanceCreatePage
+              forceId="default"
+              onConfirm={() => {
+                route(AdminPaths.list_instances);
+              }}
+            />
+          </Fragment>
+        );
+      }
+      if (props) {
+        return <Next {...props} />;
+      }
+      return <Next />;
+    };
+  }
+
+  const clearTokenAndGoToRoot = () => {
+    clearAllTokens();
+    route("/");
+  };
+
+  return (
+    <InstanceContextProvider value={value}>
+      <Menu
+        instance={id}
+        admin={admin}
+        onLogout={clearTokenAndGoToRoot}
+        setInstanceName={setInstanceName}
+      />
+      <KycBanner />
+      <NotificationCard notification={globalNotification} />
+
+      <Router
+        onChange={(e) => {
+          const movingOutFromNotification =
+            globalNotification && e.url !== globalNotification.to;
+          if (movingOutFromNotification) {
+            setGlobalNotification(undefined);
+          }
+        }}
+      >
+        <Route path="/" component={Redirect} to={InstancePaths.order_list} />
+
+        {/**
+         * Admin pages
+         */}
+        {admin && (
+          <Route
+            path={AdminPaths.list_instances}
+            component={InstanceListPage}
+            onCreate={() => {
+              route(AdminPaths.new_instance);
+            }}
+            onUpdate={(id: string): void => {
+              route(`/instance/${id}/update`);
+            }}
+            setInstanceName={setInstanceName}
+            onUnauthorized={LoginPageAccessDenied}
+            onLoadError={ServerErrorRedirectTo(InstancePaths.error)}
+          />
+        )}
+
+        {admin && (
+          <Route
+            path={AdminPaths.new_instance}
+            component={InstanceCreatePage}
+            onBack={() => route(AdminPaths.list_instances)}
+            onConfirm={() => {
+              route(AdminPaths.list_instances);
+            }}
+          />
+        )}
+
+        {admin && (
+          <Route
+            path={AdminPaths.update_instance}
+            component={AdminInstanceUpdatePage}
+            onBack={() => route(AdminPaths.list_instances)}
+            onConfirm={() => {
+              route(AdminPaths.list_instances);
+            }}
+            onUpdateError={ServerErrorRedirectTo(AdminPaths.list_instances)}
+            onLoadError={ServerErrorRedirectTo(AdminPaths.list_instances)}
+            onNotFound={NotFoundPage}
+          />
+        )}
+
+        {/**
+         * Update instance page
+         */}
+        <Route
+          path={InstancePaths.update}
+          component={InstanceUpdatePage}
+          onBack={() => {
+            route(`/`);
+          }}
+          onConfirm={() => {
+            route(`/`);
+          }}
+          onUpdateError={noop}
+          onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
+          onUnauthorized={LoginPageAccessDenied}
+          onLoadError={ServerErrorRedirectTo(InstancePaths.error)}
+        />
+
+        {/**
+         * Product pages
+         */}
+        <Route
+          path={InstancePaths.product_list}
+          component={ProductListPage}
+          onUnauthorized={LoginPageAccessDenied}
+          onLoadError={ServerErrorRedirectTo(InstancePaths.update)}
+          onCreate={() => {
+            route(InstancePaths.product_new);
+          }}
+          onSelect={(id: string) => {
+            route(InstancePaths.product_update.replace(":pid", id));
+          }}
+          onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
+        />
+        <Route
+          path={InstancePaths.product_update}
+          component={ProductUpdatePage}
+          onUnauthorized={LoginPageAccessDenied}
+          onLoadError={ServerErrorRedirectTo(InstancePaths.product_list)}
+          onConfirm={() => {
+            route(InstancePaths.product_list);
+          }}
+          onBack={() => {
+            route(InstancePaths.product_list);
+          }}
+          onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
+        />
+        <Route
+          path={InstancePaths.product_new}
+          component={ProductCreatePage}
+          onConfirm={() => {
+            route(InstancePaths.product_list);
+          }}
+          onBack={() => {
+            route(InstancePaths.product_list);
+          }}
+        />
+
+        {/**
+         * Order pages
+         */}
+        <Route
+          path={InstancePaths.order_list}
+          component={OrderListPage}
+          onCreate={() => {
+            route(InstancePaths.order_new);
+          }}
+          onSelect={(id: string) => {
+            route(InstancePaths.order_details.replace(":oid", id));
+          }}
+          onUnauthorized={LoginPageAccessDenied}
+          onLoadError={ServerErrorRedirectTo(InstancePaths.update)}
+          onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
+        />
+        <Route
+          path={InstancePaths.order_details}
+          component={OrderDetailsPage}
+          onUnauthorized={LoginPageAccessDenied}
+          onLoadError={ServerErrorRedirectTo(InstancePaths.order_list)}
+          onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
+          onBack={() => {
+            route(InstancePaths.order_list);
+          }}
+        />
+        <Route
+          path={InstancePaths.order_new}
+          component={OrderCreatePage}
+          onConfirm={() => {
+            route(InstancePaths.order_list);
+          }}
+          onBack={() => {
+            route(InstancePaths.order_list);
+          }}
+        />
+
+        {/**
+         * Transfer pages
+         */}
+        <Route
+          path={InstancePaths.transfers_list}
+          component={TransferListPage}
+          onUnauthorized={LoginPageAccessDenied}
+          onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
+          onLoadError={ServerErrorRedirectTo(InstancePaths.update)}
+          onCreate={() => {
+            route(InstancePaths.transfers_new);
+          }}
+        />
+
+        <Route
+          path={InstancePaths.transfers_new}
+          component={TransferCreatePage}
+          onConfirm={() => {
+            route(InstancePaths.transfers_list);
+          }}
+          onBack={() => {
+            route(InstancePaths.transfers_list);
+          }}
+        />
+
+        {/**
+         * reserves pages
+         */}
+        <Route
+          path={InstancePaths.reserves_list}
+          component={ReservesListPage}
+          onUnauthorized={LoginPageAccessDenied}
+          onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
+          onLoadError={ServerErrorRedirectTo(InstancePaths.update)}
+          onSelect={(id: string) => {
+            route(InstancePaths.reserves_details.replace(":rid", id));
+          }}
+          onCreate={() => {
+            route(InstancePaths.reserves_new);
+          }}
+        />
+
+        <Route
+          path={InstancePaths.reserves_details}
+          component={ReservesDetailsPage}
+          onUnauthorized={LoginPageAccessDenied}
+          onLoadError={ServerErrorRedirectTo(InstancePaths.reserves_list)}
+          onNotFound={IfAdminCreateDefaultOr(NotFoundPage)}
+          onBack={() => {
+            route(InstancePaths.reserves_list);
+          }}
+        />
+
+        <Route
+          path={InstancePaths.reserves_new}
+          component={ReservesCreatePage}
+          onConfirm={() => {
+            route(InstancePaths.reserves_list);
+          }}
+          onBack={() => {
+            route(InstancePaths.reserves_list);
+          }}
+        />
+
+        <Route path={InstancePaths.kyc} component={ListKYCPage} />
+        {/**
+         * Example pages
+         */}
+        <Route path="/loading" component={Loading} />
+        <Route default component={NotFoundPage} />
+      </Router>
+    </InstanceContextProvider>
+  );
+}
+
+export function Redirect({ to }: { to: string }): null {
+  useEffect(() => {
+    route(to, true);
+  });
+  return null;
+}
+
+function AdminInstanceUpdatePage({
+  id,
+  ...rest
+}: { id: string } & InstanceUpdatePageProps) {
+  const [token, changeToken] = useBackendInstanceToken(id);
+  const { updateLoginStatus: changeBackend } = useBackendContext();
+  const updateLoginStatus = (url: string, token?: string) => {
+    changeBackend(url);
+    if (token) changeToken(token);
+  };
+  const value = useMemo(
+    () => ({ id, token, admin: true, changeToken }),
+    [id, token]
+  );
+  const i18n = useTranslator();
+
+  return (
+    <InstanceContextProvider value={value}>
+      <InstanceAdminUpdatePage
+        {...rest}
+        instanceId={id}
+        onLoadError={(error: HttpError) => {
+          return (
+            <Fragment>
+              <NotificationCard
+                notification={{
+                  message: i18n`The backend reported a problem: HTTP status 
#${error.status}`,
+                  description: i18n`Diagnostic from ${error.info?.url} is 
"${error.message}"`,
+                  details:
+                    error.clientError || error.serverError
+                      ? error.error?.detail
+                      : undefined,
+                  type: "ERROR",
+                }}
+              />
+              <LoginPage onConfirm={updateLoginStatus} />
+            </Fragment>
+          );
+        }}
+        onUnauthorized={() => {
+          return (
+            <Fragment>
+              <NotificationCard
+                notification={{
+                  message: i18n`Access denied`,
+                  description: i18n`The access token provided is invalid`,
+                  type: "ERROR",
+                }}
+              />
+              <LoginPage onConfirm={updateLoginStatus} />
+            </Fragment>
+          );
+        }}
+      />
+    </InstanceContextProvider>
+  );
+}
+
+function KycBanner(): VNode {
+  const kycStatus = useInstanceKYCDetails();
+  const today = format(new Date(), "yyyy-MM-dd");
+  const [lastHide, setLastHide] = useLocalStorage("kyc-last-hide");
+  const hasBeenHidden = today === lastHide;
+  const needsToBeShown = kycStatus.ok && kycStatus.data.type === "redirect";
+  if (hasBeenHidden || !needsToBeShown) return <Fragment />;
+  return (
+    <NotificationCard
+      notification={{
+        type: "WARN",
+        message: "KYC verification needed",
+        description: (
+          <div>
+            <p>
+              Some transfer are on hold until a KYC process is completed. Go to
+              the KYC section in the left panel for more information
+            </p>
+            <div class="buttons is-right">
+              <button class="button" onClick={() => setLastHide(today)}>
+                <Translate>Hide for today</Translate>
+              </button>
+            </div>
+          </div>
+        ),
+      }}
+    />
+  );
+}
diff --git a/packages/anastasis-webui/src/assets/empty.png 
b/packages/merchant-backoffice-ui/src/assets/empty.png
similarity index 100%
copy from packages/anastasis-webui/src/assets/empty.png
copy to packages/merchant-backoffice-ui/src/assets/empty.png
diff --git 
a/packages/anastasis-webui/src/assets/icons/android-chrome-192x192.png 
b/packages/merchant-backoffice-ui/src/assets/icons/android-chrome-192x192.png
similarity index 100%
copy from packages/anastasis-webui/src/assets/icons/android-chrome-192x192.png
copy to 
packages/merchant-backoffice-ui/src/assets/icons/android-chrome-192x192.png
diff --git 
a/packages/anastasis-webui/src/assets/icons/android-chrome-512x512.png 
b/packages/merchant-backoffice-ui/src/assets/icons/android-chrome-512x512.png
similarity index 100%
copy from packages/anastasis-webui/src/assets/icons/android-chrome-512x512.png
copy to 
packages/merchant-backoffice-ui/src/assets/icons/android-chrome-512x512.png
diff --git a/packages/anastasis-webui/src/assets/icons/apple-touch-icon.png 
b/packages/merchant-backoffice-ui/src/assets/icons/apple-touch-icon.png
similarity index 100%
copy from packages/anastasis-webui/src/assets/icons/apple-touch-icon.png
copy to packages/merchant-backoffice-ui/src/assets/icons/apple-touch-icon.png
diff --git a/packages/anastasis-webui/src/assets/icons/favicon-16x16.png 
b/packages/merchant-backoffice-ui/src/assets/icons/favicon-16x16.png
similarity index 100%
copy from packages/anastasis-webui/src/assets/icons/favicon-16x16.png
copy to packages/merchant-backoffice-ui/src/assets/icons/favicon-16x16.png
diff --git a/packages/anastasis-webui/src/assets/icons/favicon-32x32.png 
b/packages/merchant-backoffice-ui/src/assets/icons/favicon-32x32.png
similarity index 100%
copy from packages/anastasis-webui/src/assets/icons/favicon-32x32.png
copy to packages/merchant-backoffice-ui/src/assets/icons/favicon-32x32.png
diff --git a/packages/anastasis-webui/src/assets/icons/languageicon.svg 
b/packages/merchant-backoffice-ui/src/assets/icons/languageicon.svg
similarity index 100%
copy from packages/anastasis-webui/src/assets/icons/languageicon.svg
copy to packages/merchant-backoffice-ui/src/assets/icons/languageicon.svg
diff --git a/packages/anastasis-webui/src/assets/icons/mstile-150x150.png 
b/packages/merchant-backoffice-ui/src/assets/icons/mstile-150x150.png
similarity index 100%
copy from packages/anastasis-webui/src/assets/icons/mstile-150x150.png
copy to packages/merchant-backoffice-ui/src/assets/icons/mstile-150x150.png
diff --git a/packages/anastasis-webui/src/assets/logo.jpeg 
b/packages/merchant-backoffice-ui/src/assets/logo.jpeg
similarity index 100%
copy from packages/anastasis-webui/src/assets/logo.jpeg
copy to packages/merchant-backoffice-ui/src/assets/logo.jpeg
diff --git 
a/packages/merchant-backoffice-ui/src/components/exception/AsyncButton.tsx 
b/packages/merchant-backoffice-ui/src/components/exception/AsyncButton.tsx
new file mode 100644
index 000000000..92bab4bfb
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/exception/AsyncButton.tsx
@@ -0,0 +1,49 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { ComponentChildren, h } from "preact";
+import { LoadingModal } from "../modal";
+import { useAsync } from "../../hooks/async";
+import { Translate } from "../../i18n";
+
+type Props = {
+  children: ComponentChildren,
+  disabled: boolean;
+  onClick?: () => Promise<void>;
+  [rest:string]: any,
+};
+
+export function AsyncButton({ onClick, disabled, children, ...rest }: Props) {
+  const { isSlow, isLoading, request, cancel } = useAsync(onClick);
+
+  if (isSlow) {
+    return <LoadingModal onCancel={cancel} />;
+  }
+  if (isLoading) {
+    return <button class="button"><Translate>Loading...</Translate></button>;
+  }
+
+  return <span {...rest}>
+    <button class="button is-success" onClick={request} disabled={disabled}>
+      {children}
+    </button>
+  </span>;
+}
diff --git a/packages/merchant-backoffice-ui/src/components/exception/QR.tsx 
b/packages/merchant-backoffice-ui/src/components/exception/QR.tsx
new file mode 100644
index 000000000..bcb9964a5
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/exception/QR.tsx
@@ -0,0 +1,49 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+import { h, VNode } from "preact";
+import { useEffect, useRef } from "preact/hooks";
+import qrcode from "qrcode-generator";
+
+export function QR({ text }: { text: string }): VNode {
+  const divRef = useRef<HTMLDivElement>(null);
+  useEffect(() => {
+    const qr = qrcode(0, "L");
+    qr.addData(text);
+    qr.make();
+    if (divRef.current) {
+      divRef.current.innerHTML = qr.createSvgTag({
+        scalable: true,
+      });
+    }
+  });
+
+  return (
+    <div
+      style={{
+        width: "100%",
+        display: "flex",
+        flexDirection: "column",
+        alignItems: "center",
+      }}
+    >
+      <div
+        style={{ width: "50%", minWidth: 200, maxWidth: 300 }}
+        ref={divRef}
+      />
+    </div>
+  );
+}
diff --git 
a/packages/merchant-backoffice-ui/src/components/exception/loading.tsx 
b/packages/merchant-backoffice-ui/src/components/exception/loading.tsx
new file mode 100644
index 000000000..f2139a17e
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/exception/loading.tsx
@@ -0,0 +1,32 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode } from "preact";
+
+export function Loading(): VNode {
+  return <div class="columns is-centered is-vcentered" style={{ height: 
'calc(100% - 3rem)', position: 'absolute', width: '100%' }}>
+    <Spinner />
+  </div>
+}
+
+export function Spinner(): VNode {
+  return <div class="lds-ring"><div /><div /><div /><div /></div>
+}
\ No newline at end of file
diff --git a/packages/merchant-backoffice-ui/src/components/exception/login.tsx 
b/packages/merchant-backoffice-ui/src/components/exception/login.tsx
new file mode 100644
index 000000000..498d994ed
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/exception/login.tsx
@@ -0,0 +1,143 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { useBackendContext } from "../../context/backend";
+import { useInstanceContext } from "../../context/instance";
+import { Translate, useTranslator } from "../../i18n";
+import { Notification } from "../../utils/types";
+
+interface Props {
+  withMessage?: Notification;
+  onConfirm: (backend: string, token?: string) => void;
+}
+
+function getTokenValuePart(t?: string): string | undefined {
+  if (!t) return t;
+  const match = /secret-token:(.*)/.exec(t);
+  if (!match || !match[1]) return undefined;
+  return match[1];
+}
+
+function normalizeToken(r: string | undefined): string | undefined {
+  return r ? `secret-token:${encodeURIComponent(r)}` : undefined;
+}
+
+export function LoginModal({ onConfirm, withMessage }: Props): VNode {
+  const { url: backendUrl, token: baseToken } = useBackendContext();
+  const { admin, token: instanceToken } = useInstanceContext();
+  const currentToken = getTokenValuePart(
+    !admin ? baseToken : instanceToken || ""
+  );
+  const [token, setToken] = useState(currentToken);
+
+  const [url, setURL] = useState(backendUrl);
+  const i18n = useTranslator();
+
+  return (
+    <div class="columns is-centered">
+      <div class="column is-two-thirds ">
+        <div class="modal-card" style={{ width: "100%", margin: 0 }}>
+          <header
+            class="modal-card-head"
+            style={{ border: "1px solid", borderBottom: 0 }}
+          >
+            <p class="modal-card-title">{i18n`Login required`}</p>
+          </header>
+          <section
+            class="modal-card-body"
+            style={{ border: "1px solid", borderTop: 0, borderBottom: 0 }}
+          >
+            <Translate>Please enter your access token.</Translate>
+            <div class="field is-horizontal">
+              <div class="field-label is-normal">
+                <label class="label">URL</label>
+              </div>
+              <div class="field-body">
+                <div class="field">
+                  <p class="control is-expanded">
+                    <input
+                      class="input"
+                      type="text"
+                      placeholder="set new url"
+                      name="id"
+                      value={url}
+                      onKeyPress={(e) =>
+                        e.keyCode === 13
+                          ? onConfirm(url, normalizeToken(token))
+                          : null
+                      }
+                      onInput={(e): void => setURL(e?.currentTarget.value)}
+                    />
+                  </p>
+                </div>
+              </div>
+            </div>
+            <div class="field is-horizontal">
+              <div class="field-label is-normal">
+                <label class="label">
+                  <Translate>Access Token</Translate>
+                </label>
+              </div>
+              <div class="field-body">
+                <div class="field">
+                  <p class="control is-expanded">
+                    <input
+                      class="input"
+                      type="password"
+                      placeholder={"set new access token"}
+                      name="token"
+                      onKeyPress={(e) =>
+                        e.keyCode === 13
+                          ? onConfirm(url, normalizeToken(token))
+                          : null
+                      }
+                      value={token}
+                      onInput={(e): void => setToken(e?.currentTarget.value)}
+                    />
+                  </p>
+                </div>
+              </div>
+            </div>
+          </section>
+          <footer
+            class="modal-card-foot "
+            style={{
+              justifyContent: "flex-end",
+              border: "1px solid",
+              borderTop: 0,
+            }}
+          >
+            <button
+              class="button is-info"
+              onClick={(): void => {
+                onConfirm(url, normalizeToken(token));
+              }}
+            >
+              <Translate>Confirm</Translate>
+            </button>
+          </footer>
+        </div>
+      </div>
+    </div>
+  );
+}
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/FormProvider.tsx 
b/packages/merchant-backoffice-ui/src/components/form/FormProvider.tsx
new file mode 100644
index 000000000..aef410ce7
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/form/FormProvider.tsx
@@ -0,0 +1,81 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { ComponentChildren, createContext, h, VNode } from "preact";
+import { useContext, useMemo } from "preact/hooks";
+
+type Updater<S> = (value: ((prevState: S) => S) ) => void;
+
+export interface Props<T> {
+  object?: Partial<T>;
+  errors?: FormErrors<T>;
+  name?: string;
+  valueHandler: Updater<Partial<T>> | null;
+  children: ComponentChildren
+}
+
+const noUpdater: Updater<Partial<unknown>> = () => (s: unknown) => s
+
+export function FormProvider<T>({ object = {}, errors = {}, name = '', 
valueHandler, children }: Props<T>): VNode {
+  const initialObject = useMemo(() => object, []);
+  const value = useMemo<FormType<T>>(() => ({ errors, object, initialObject, 
valueHandler: valueHandler ? valueHandler : noUpdater, name, toStr: {}, 
fromStr: {} }), [errors, object, valueHandler]);
+
+  return <FormContext.Provider value={value}>
+    <form class="field" onSubmit={(e) => {
+      e.preventDefault();
+      // if (valueHandler) valueHandler(object);
+    }}>
+      {children}
+    </form>
+  </FormContext.Provider>;
+}
+
+export interface FormType<T> {
+  object: Partial<T>;
+  initialObject: Partial<T>;
+  errors: FormErrors<T>;
+  toStr: FormtoStr<T>;
+  name: string;
+  fromStr: FormfromStr<T>;
+  valueHandler: Updater<Partial<T>>;
+}
+
+const FormContext = createContext<FormType<unknown>>(null!)
+
+export function useFormContext<T>() {
+  return useContext<FormType<T>>(FormContext)
+}
+
+export type FormErrors<T> = {
+  [P in keyof T]?: string | FormErrors<T[P]>
+}
+
+export type FormtoStr<T> = {
+  [P in keyof T]?: ((f?: T[P]) => string)
+}
+
+export type FormfromStr<T> = {
+  [P in keyof T]?: ((f: string) => T[P])
+}
+
+export type FormUpdater<T> = {
+  [P in keyof T]?: (f: keyof T) => (v: T[P]) => void
+}
diff --git a/packages/merchant-backoffice-ui/src/components/form/Input.tsx 
b/packages/merchant-backoffice-ui/src/components/form/Input.tsx
new file mode 100644
index 000000000..9a9691e9b
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/form/Input.tsx
@@ -0,0 +1,71 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import { ComponentChildren, h, VNode } from "preact";
+import { useField, InputProps } from "./useField";
+
+interface Props<T> extends InputProps<T> {
+  inputType?: 'text' | 'number' | 'multiline' | 'password';
+  expand?: boolean;
+  toStr?: (v?: any) => string;
+  fromStr?: (s: string) => any;
+  inputExtra?: any,
+  side?: ComponentChildren;
+  children?: ComponentChildren;
+}
+
+const defaultToString = (f?: any): string => f || ''
+const defaultFromString = (v: string): any => v as any
+
+const TextInput = ({ inputType, error, ...rest }: any) => inputType === 
'multiline' ?
+  <textarea {...rest} class={error ? "textarea is-danger" : "textarea"} 
rows="3" /> :
+  <input {...rest} class={error ? "input is-danger" : "input"} 
type={inputType} />;
+
+export function Input<T>({ name, readonly, placeholder, tooltip, label, 
expand, help, children, inputType, inputExtra, side, fromStr = 
defaultFromString, toStr = defaultToString }: Props<keyof T>): VNode {
+  const { error, value, onChange, required } = useField<T>(name);
+  return <div class="field is-horizontal">
+    <div class="field-label is-normal">
+      <label class="label">
+        {label}
+        {tooltip && <span class="icon has-tooltip-right" 
data-tooltip={tooltip}>
+          <i class="mdi mdi-information" />
+        </span>}
+      </label>
+    </div>
+    <div class="field-body is-flex-grow-3">
+      <div class="field">
+        <p class={expand ? "control is-expanded has-icons-right" : "control 
has-icons-right"}>
+          <TextInput error={error} {...inputExtra}
+            inputType={inputType}
+            placeholder={placeholder} readonly={readonly}
+            name={String(name)} value={toStr(value)}
+            onChange={(e: h.JSX.TargetedEvent<HTMLInputElement>): void => 
onChange(fromStr(e.currentTarget.value))} />
+          {help}
+          {children}
+          { required && <span class="icon has-text-danger is-right">
+            <i class="mdi mdi-alert" />
+          </span> }
+        </p>
+        {error && <p class="help is-danger">{error}</p>}
+      </div>
+      {side}
+    </div>
+  </div>;
+}
diff --git a/packages/merchant-backoffice-ui/src/components/form/InputArray.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputArray.tsx
new file mode 100644
index 000000000..984c6dc49
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/form/InputArray.tsx
@@ -0,0 +1,97 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import { h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { Translate, useTranslator } from "../../i18n";
+import { InputProps, useField } from "./useField";
+
+export interface Props<T> extends InputProps<T> {
+  isValid?: (e: any) => boolean;
+  addonBefore?: string;
+  toStr?: (v?: any) => string;
+  fromStr?: (s: string) => any;
+}
+
+const defaultToString = (f?: any): string => f || ''
+const defaultFromString = (v: string): any => v as any
+
+export function InputArray<T>({ name, readonly, placeholder, tooltip, label, 
help, addonBefore, isValid = () => true, fromStr = defaultFromString, toStr = 
defaultToString }: Props<keyof T>): VNode {
+  const { error: formError, value, onChange, required } = useField<T>(name);
+  const [localError, setLocalError] = useState<string | null>(null)
+
+  const error = localError || formError
+
+  const array: any[] = (value ? value! : []) as any;
+  const [currentValue, setCurrentValue] = useState('');
+  const i18n = useTranslator();
+
+  return <div class="field is-horizontal">
+    <div class="field-label is-normal">
+      <label class="label">
+        {label}
+        {tooltip && <span class="icon has-tooltip-right" 
data-tooltip={tooltip}>
+          <i class="mdi mdi-information" />
+        </span>}
+      </label>
+    </div>
+    <div class="field-body is-flex-grow-3">
+      <div class="field">
+        <div class="field has-addons">
+          {addonBefore && <div class="control">
+            <a class="button is-static">{addonBefore}</a>
+          </div>}
+          <p class="control is-expanded has-icons-right">
+            <input class={error ? "input is-danger" : "input"} type="text"
+              placeholder={placeholder} readonly={readonly} disabled={readonly}
+              name={String(name)} value={currentValue}
+              onChange={(e): void => setCurrentValue(e.currentTarget.value)} />
+            {required && <span class="icon has-text-danger is-right">
+              <i class="mdi mdi-alert" />
+            </span>}
+          </p>
+          <p class="control">
+            <button class="button is-info has-tooltip-left" 
disabled={!currentValue} onClick={(): void => {
+              const v = fromStr(currentValue)
+              if (!isValid(v)) {
+                setLocalError(i18n`The value ${v} is invalid for a payment 
url`)
+                return;
+              }
+              setLocalError(null)
+              onChange([v, ...array] as any);
+              setCurrentValue('');
+            }} data-tooltip={i18n`add element to the 
list`}><Translate>add</Translate></button>
+          </p>
+        </div>
+        {help}
+        {error && <p class="help is-danger"> {error} </p>}
+        {array.map((v, i) => <div key={i} class="tags has-addons mt-3 mb-0">
+          <span class="tag is-medium is-info mb-0" style={{ maxWidth: '90%' 
}}>{v}</span>
+          <a class="tag is-medium is-danger is-delete mb-0" onClick={() => {
+            onChange(array.filter(f => f !== v) as any);
+            setCurrentValue(toStr(v));
+          }} />
+        </div>
+        )}
+      </div>
+
+    </div>
+  </div>;
+}
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputBoolean.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputBoolean.tsx
new file mode 100644
index 000000000..2771fe483
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/form/InputBoolean.tsx
@@ -0,0 +1,72 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import { h, VNode } from "preact";
+import { InputProps, useField } from "./useField";
+
+interface Props<T> extends InputProps<T> {
+  name: T;
+  readonly?: boolean;
+  expand?: boolean;
+  threeState?: boolean;
+  toBoolean?: (v?: any) => boolean | undefined;
+  fromBoolean?: (s: boolean | undefined) => any;
+}
+
+const defaultToBoolean = (f?: any): boolean | undefined => f || ''
+const defaultFromBoolean = (v: boolean | undefined): any => v as any
+
+
+export function InputBoolean<T>({ name, readonly, placeholder, tooltip, label, 
help, threeState, expand, fromBoolean = defaultFromBoolean, toBoolean = 
defaultToBoolean }: Props<keyof T>): VNode {
+  const { error, value, onChange } = useField<T>(name);
+
+  const onCheckboxClick = (): void => {
+    const c = toBoolean(value)
+    if (c === false && threeState) return onChange(undefined as any)
+    return onChange(fromBoolean(!c))
+  }
+
+  return <div class="field is-horizontal">
+    <div class="field-label is-normal">
+      <label class="label">
+        {label}
+        {tooltip && <span class="icon has-tooltip-right" 
data-tooltip={tooltip}>
+          <i class="mdi mdi-information" />
+        </span>}
+      </label>
+    </div>
+    <div class="field-body is-flex-grow-3">
+      <div class="field">
+        <p class={expand ? "control is-expanded" : "control"}>
+          <label class="b-checkbox checkbox">
+            <input type="checkbox" class={toBoolean(value) === undefined ? 
"is-indeterminate" : ""}
+              checked={toBoolean(value)}
+              placeholder={placeholder} readonly={readonly}
+              name={String(name)} disabled={readonly}
+              onChange={onCheckboxClick} />
+            <span class="check" />
+          </label>
+          {help}
+        </p>
+        {error && <p class="help is-danger">{error}</p>}
+      </div>
+    </div>
+  </div>;
+}
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputCurrency.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputCurrency.tsx
new file mode 100644
index 000000000..d3a46f483
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/form/InputCurrency.tsx
@@ -0,0 +1,47 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import { ComponentChildren, h } from "preact";
+import { useConfigContext } from "../../context/config";
+import { Amount } from "../../declaration";
+import { InputWithAddon } from "./InputWithAddon";
+import { InputProps } from "./useField";
+
+export interface Props<T> extends InputProps<T> {
+  expand?: boolean;
+  addonAfter?: ComponentChildren;
+  children?: ComponentChildren;
+  side?: ComponentChildren;
+}
+
+export function InputCurrency<T>({ name, readonly, label, placeholder, help, 
tooltip, expand, addonAfter, children, side }: Props<keyof T>) {
+  const config = useConfigContext()
+  return <InputWithAddon<T> name={name} readonly={readonly} 
addonBefore={config.currency}
+    side={side}
+    label={label} placeholder={placeholder} help={help} tooltip={tooltip}
+    addonAfter={addonAfter}
+    inputType='number' expand={expand}
+    toStr={(v?: Amount) => v?.split(':')[1] || ''}
+    fromStr={(v: string) => !v ? '' : `${config.currency}:${v}`}
+    inputExtra={{ min: 0 }}
+    children={children}
+  />
+}
+
diff --git a/packages/merchant-backoffice-ui/src/components/form/InputDate.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputDate.tsx
new file mode 100644
index 000000000..77199527f
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/form/InputDate.tsx
@@ -0,0 +1,159 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { format } from "date-fns";
+import { h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { Translate, useTranslator } from "../../i18n";
+import { DatePicker } from "../picker/DatePicker";
+import { InputProps, useField } from "./useField";
+
+export interface Props<T> extends InputProps<T> {
+  readonly?: boolean;
+  expand?: boolean;
+  //FIXME: create separated components InputDate and InputTimestamp
+  withTimestampSupport?: boolean;
+}
+
+export function InputDate<T>({
+  name,
+  readonly,
+  label,
+  placeholder,
+  help,
+  tooltip,
+  expand,
+  withTimestampSupport,
+}: Props<keyof T>): VNode {
+  const [opened, setOpened] = useState(false);
+  const i18n = useTranslator();
+
+  const { error, required, value, onChange } = useField<T>(name);
+
+  let strValue = "";
+  if (!value) {
+    strValue = withTimestampSupport ? "unknown" : "";
+  } else if (value instanceof Date) {
+    strValue = format(value, "yyyy/MM/dd");
+  } else if (value.t_s) {
+    strValue =
+      value.t_s === "never"
+        ? withTimestampSupport
+          ? "never"
+          : ""
+        : format(new Date(value.t_s * 1000), "yyyy/MM/dd");
+  }
+
+  return (
+    <div class="field is-horizontal">
+      <div class="field-label is-normal">
+        <label class="label">
+          {label}
+          {tooltip && (
+            <span class="icon has-tooltip-right" data-tooltip={tooltip}>
+              <i class="mdi mdi-information" />
+            </span>
+          )}
+        </label>
+      </div>
+      <div class="field-body is-flex-grow-3">
+        <div class="field">
+          <div class="field has-addons">
+            <p
+              class={
+                expand
+                  ? "control is-expanded has-icons-right"
+                  : "control has-icons-right"
+              }
+            >
+              <input
+                class="input"
+                type="text"
+                readonly
+                value={strValue}
+                placeholder={placeholder}
+                onClick={() => {
+                  if (!readonly) setOpened(true);
+                }}
+              />
+              {required && (
+                <span class="icon has-text-danger is-right">
+                  <i class="mdi mdi-alert" />
+                </span>
+              )}
+              {help}
+            </p>
+            <div
+              class="control"
+              onClick={() => {
+                if (!readonly) setOpened(true);
+              }}
+            >
+              <a class="button is-static">
+                <span class="icon">
+                  <i class="mdi mdi-calendar" />
+                </span>
+              </a>
+            </div>
+          </div>
+          {error && <p class="help is-danger">{error}</p>}
+        </div>
+
+        {!readonly && (
+          <span
+            data-tooltip={
+              withTimestampSupport
+                ? i18n`change value to unknown date`
+                : i18n`change value to empty`
+            }
+          >
+            <button
+              class="button is-info mr-3"
+              onClick={() => onChange(undefined as any)}
+            >
+              <Translate>clear</Translate>
+            </button>
+          </span>
+        )}
+        {withTimestampSupport && (
+          <span data-tooltip={i18n`change value to never`}>
+            <button
+              class="button is-info"
+              onClick={() => onChange({ t_s: "never" } as any)}
+            >
+              <Translate>never</Translate>
+            </button>
+          </span>
+        )}
+      </div>
+      <DatePicker
+        opened={opened}
+        closeFunction={() => setOpened(false)}
+        dateReceiver={(d) => {
+          if (withTimestampSupport) {
+            onChange({ t_s: d.getTime() / 1000 } as any);
+          } else {
+            onChange(d as any);
+          }
+        }}
+      />
+    </div>
+  );
+}
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputDuration.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputDuration.tsx
new file mode 100644
index 000000000..d5c208e25
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/form/InputDuration.tsx
@@ -0,0 +1,172 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { intervalToDuration, formatDuration } from "date-fns";
+import { h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { Translate, useTranslator } from "../../i18n";
+import { SimpleModal } from "../modal";
+import { DurationPicker } from "../picker/DurationPicker";
+import { InputProps, useField } from "./useField";
+
+export interface Props<T> extends InputProps<T> {
+  expand?: boolean;
+  readonly?: boolean;
+  withForever?: boolean;
+}
+
+export function InputDuration<T>({
+  name,
+  expand,
+  placeholder,
+  tooltip,
+  label,
+  help,
+  readonly,
+  withForever,
+}: Props<keyof T>): VNode {
+  const [opened, setOpened] = useState(false);
+  const i18n = useTranslator();
+
+  const { error, required, value, onChange } = useField<T>(name);
+  let strValue = "";
+  if (!value) {
+    strValue = "";
+  } else if (value.d_us === "forever") {
+    strValue = i18n`forever`;
+  } else {
+    strValue = formatDuration(
+      intervalToDuration({ start: 0, end: value.d_us / 1000 }),
+      {
+        locale: {
+          formatDistance: (name, value) => {
+            switch (name) {
+              case "xMonths":
+                return i18n`${value}M`;
+              case "xYears":
+                return i18n`${value}Y`;
+              case "xDays":
+                return i18n`${value}d`;
+              case "xHours":
+                return i18n`${value}h`;
+              case "xMinutes":
+                return i18n`${value}min`;
+              case "xSeconds":
+                return i18n`${value}sec`;
+            }
+          },
+          localize: {
+            day: () => "s",
+            month: () => "m",
+            ordinalNumber: () => "th",
+            dayPeriod: () => "p",
+            quarter: () => "w",
+            era: () => "e",
+          },
+        },
+      }
+    );
+  }
+
+  return (
+    <div class="field is-horizontal">
+      <div class="field-label is-normal">
+        <label class="label">
+          {label}
+          {tooltip && (
+            <span class="icon" data-tooltip={tooltip}>
+              <i class="mdi mdi-information" />
+            </span>
+          )}
+        </label>
+      </div>
+      <div class="field-body is-flex-grow-3">
+        <div class="field">
+          <div class="field has-addons">
+            <p class={expand ? "control is-expanded " : "control "}>
+              <input
+                class="input"
+                type="text"
+                readonly
+                value={strValue}
+                placeholder={placeholder}
+                onClick={() => {
+                  if (!readonly) setOpened(true);
+                }}
+              />
+              {required && (
+                <span class="icon has-text-danger is-right">
+                  <i class="mdi mdi-alert" />
+                </span>
+              )}
+              {help}
+            </p>
+            <div
+              class="control"
+              onClick={() => {
+                if (!readonly) setOpened(true);
+              }}
+            >
+              <a class="button is-static">
+                <span class="icon">
+                  <i class="mdi mdi-clock" />
+                </span>
+              </a>
+            </div>
+          </div>
+          {error && <p class="help is-danger">{error}</p>}
+        </div>
+        {withForever && (
+          <span data-tooltip={i18n`change value to never`}>
+            <button
+              class="button is-info mr-3"
+              onClick={() => onChange({ d_us: "forever" } as any)}
+            >
+              <Translate>forever</Translate>
+            </button>
+          </span>
+        )}
+        {!readonly && (
+          <span data-tooltip={i18n`change value to empty`}>
+            <button
+              class="button is-info "
+              onClick={() => onChange(undefined as any)}
+            >
+              <Translate>clear</Translate>
+            </button>
+          </span>
+        )}
+      </div>
+      {opened && (
+        <SimpleModal onCancel={() => setOpened(false)}>
+          <DurationPicker
+            days
+            hours
+            minutes
+            value={!value || value.d_us === "forever" ? 0 : value.d_us}
+            onChange={(v) => {
+              onChange({ d_us: v } as any);
+            }}
+          />
+        </SimpleModal>
+      )}
+    </div>
+  );
+}
diff --git a/packages/merchant-backoffice-ui/src/components/form/InputGroup.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputGroup.tsx
new file mode 100644
index 000000000..8af9c7d96
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/form/InputGroup.tsx
@@ -0,0 +1,66 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import { ComponentChildren, h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { useGroupField } from "./useGroupField";
+
+export interface Props<T> {
+  name: T;
+  children: ComponentChildren;
+  label: ComponentChildren;
+  tooltip?: ComponentChildren;
+  alternative?: ComponentChildren;
+  fixed?: boolean;
+  initialActive?: boolean;
+}
+
+export function InputGroup<T>({ name, label, children, tooltip, alternative, 
fixed, initialActive }: Props<keyof T>): VNode {
+  const [active, setActive] = useState(initialActive || fixed);
+  const group = useGroupField<T>(name);
+
+  return <div class="card">
+    <header class="card-header">
+      <p class="card-header-title">
+        {label}
+        {tooltip && <span class="icon has-tooltip-right" 
data-tooltip={tooltip}>
+          <i class="mdi mdi-information" />
+        </span>}
+        {group?.hasError && <span class="icon has-text-danger" 
data-tooltip={tooltip}>
+          <i class="mdi mdi-alert" />
+        </span>}
+      </p>
+      { !fixed && <button class="card-header-icon" aria-label="more options" 
onClick={(): void => setActive(!active)}>
+        <span class="icon">
+          {active ?
+            <i class="mdi mdi-arrow-up" /> :
+            <i class="mdi mdi-arrow-down" />}
+        </span>
+      </button> }
+    </header>
+    {active ? <div class="card-content">
+        {children}
+    </div> : (
+      alternative ? <div class="card-content">
+          {alternative}
+      </div> : undefined
+    )}
+  </div>;
+}
diff --git a/packages/merchant-backoffice-ui/src/components/form/InputImage.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputImage.tsx
new file mode 100644
index 000000000..6cc9b9dcc
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/form/InputImage.tsx
@@ -0,0 +1,95 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import { ComponentChildren, h, VNode } from "preact";
+import { useRef, useState } from "preact/hooks";
+import emptyImage from "../../assets/empty.png";
+import { Translate } from "../../i18n";
+import { MAX_IMAGE_SIZE as MAX_IMAGE_UPLOAD_SIZE } from 
"../../utils/constants";
+import { InputProps, useField } from "./useField";
+
+export interface Props<T> extends InputProps<T> {
+  expand?: boolean;
+  addonAfter?: ComponentChildren;
+  children?: ComponentChildren;
+}
+
+export function InputImage<T>({ name, readonly, placeholder, tooltip, label, 
help, children, expand }: Props<keyof T>): VNode {
+  const { error, value, onChange } = useField<T>(name);
+
+  const image = useRef<HTMLInputElement>(null)
+
+  const [sizeError, setSizeError] = useState(false)
+
+  return <div class="field is-horizontal">
+    <div class="field-label is-normal">
+      <label class="label">
+        {label}
+        {tooltip && <span class="icon has-tooltip-right" 
data-tooltip={tooltip}>
+          <i class="mdi mdi-information" />
+        </span>}
+      </label>
+    </div>
+    <div class="field-body is-flex-grow-3">
+      <div class="field">
+        <p class={expand ? "control is-expanded" : "control"}>
+          {value &&
+            <img src={value} style={{ width: 200, height: 200 }} onClick={() 
=> image.current?.click()} />
+          }
+          <input
+            ref={image} style={{ display: 'none' }}
+            type="file" name={String(name)}
+            placeholder={placeholder} readonly={readonly}
+            onChange={e => {
+              const f: FileList | null = e.currentTarget.files
+              if (!f || f.length != 1) {
+                return onChange(undefined!)
+              }
+              if (f[0].size > MAX_IMAGE_UPLOAD_SIZE) {
+                setSizeError(true)
+                return onChange(undefined!)
+              }
+              setSizeError(false)
+              return f[0].arrayBuffer().then(b => {
+                const b64 = btoa(
+                  new Uint8Array(b)
+                    .reduce((data, byte) => data + String.fromCharCode(byte), 
'')
+                )
+                return onChange(`data:${f[0].type};base64,${b64}` as any)
+              })
+            }} />
+          {help}
+          {children}
+        </p>
+        {error && <p class="help is-danger">{error}</p>}
+        {sizeError && <p class="help is-danger">
+          <Translate>Image should be smaller than 1 MB</Translate>
+        </p>}
+        {!value &&
+          <button class="button" onClick={() => image.current?.click()} 
><Translate>Add</Translate></button>
+        }
+        {value &&
+          <button class="button" onClick={() => onChange(undefined!)} 
><Translate>Remove</Translate></button>
+        }
+      </div>
+    </div>
+  </div>
+}
+
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputLocation.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputLocation.tsx
new file mode 100644
index 000000000..12755f47a
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/form/InputLocation.tsx
@@ -0,0 +1,43 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import { Fragment, h } from "preact";
+import { useTranslator } from "../../i18n";
+import { Input } from "./Input";
+
+export function InputLocation({name}:{name:string}) {
+  const i18n = useTranslator()
+  return <>
+    <Input name={`${name}.country`} label={i18n`Country`} />
+    <Input name={`${name}.address_lines`} inputType="multiline"
+      label={i18n`Address`}
+      toStr={(v: string[] | undefined) => !v ? '' : v.join('\n')}
+      fromStr={(v: string) => v.split('\n')}
+    />
+    <Input name={`${name}.building_number`} label={i18n`Building number`} />
+    <Input name={`${name}.building_name`} label={i18n`Building name`} />
+    <Input name={`${name}.street`} label={i18n`Street`} />
+    <Input name={`${name}.post_code`} label={i18n`Post code`} />
+    <Input name={`${name}.town_location`} label={i18n`Town location`} />
+    <Input name={`${name}.town`} label={i18n`Town`} />
+    <Input name={`${name}.district`} label={i18n`District`} />
+    <Input name={`${name}.country_subdivision`} label={i18n`Country 
subdivision`} />
+  </>
+}
\ No newline at end of file
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputNumber.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputNumber.tsx
new file mode 100644
index 000000000..046cda59e
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/form/InputNumber.tsx
@@ -0,0 +1,42 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import { ComponentChildren, h } from "preact";
+import { InputWithAddon } from "./InputWithAddon";
+import { InputProps } from "./useField";
+
+export interface Props<T> extends InputProps<T> {
+  readonly?: boolean;
+  expand?: boolean;
+  side?: ComponentChildren;
+  children?: ComponentChildren;
+}
+
+export function InputNumber<T>({ name, readonly, placeholder, tooltip, label, 
help, expand, children, side }: Props<keyof T>) {
+  return <InputWithAddon<T> name={name} readonly={readonly} 
+    fromStr={(v) => !v ? undefined : parseInt(v, 10) } toStr={(v) => `${v}`}
+    inputType='number' expand={expand}
+    label={label} placeholder={placeholder} help={help} tooltip={tooltip}
+    inputExtra={{ min: 0 }}
+    children={children}
+    side={side}
+  />
+}
+
diff --git a/packages/merchant-backoffice-ui/src/components/form/InputPayto.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputPayto.tsx
new file mode 100644
index 000000000..44252317e
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/form/InputPayto.tsx
@@ -0,0 +1,39 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import { h, VNode } from "preact";
+import { InputArray } from "./InputArray";
+import { PAYTO_REGEX } from "../../utils/constants";
+import { InputProps } from "./useField";
+
+export type Props<T> = InputProps<T>;
+
+const PAYTO_START_REGEX = /^payto:\/\//
+
+export function InputPayto<T>({ name, readonly, placeholder, tooltip, label, 
help }: Props<keyof T>): VNode {
+  return <InputArray<T> name={name} readonly={readonly} 
+    addonBefore="payto://" 
+    label={label} placeholder={placeholder} help={help} tooltip={tooltip}
+    isValid={(v) => v && PAYTO_REGEX.test(v) }
+    toStr={(v?: string) => !v ? '': v.replace(PAYTO_START_REGEX, '')}
+    fromStr={(v: string) => `payto://${v}` }
+  />
+}
+
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputPaytoForm.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputPaytoForm.tsx
new file mode 100644
index 000000000..9cfef07cf
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/form/InputPaytoForm.tsx
@@ -0,0 +1,392 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { h, VNode, Fragment } from "preact";
+import { useCallback, useState } from "preact/hooks";
+import { Translate, Translator, useTranslator } from "../../i18n";
+import { COUNTRY_TABLE } from "../../utils/constants";
+import { FormErrors, FormProvider } from "./FormProvider";
+import { Input } from "./Input";
+import { InputGroup } from "./InputGroup";
+import { InputSelector } from "./InputSelector";
+import { InputProps, useField } from "./useField";
+
+export interface Props<T> extends InputProps<T> {
+  isValid?: (e: any) => boolean;
+}
+
+// https://datatracker.ietf.org/doc/html/rfc8905
+type Entity = {
+  // iban, bitcoin, x-taler-bank. it defined the format
+  target: string;
+  // path1 if the first field to be used
+  path1: string;
+  // path2 if the second field to be used, optional
+  path2?: string;
+  // options of the payto uri
+  options: {
+    "receiver-name"?: string;
+    sender?: string;
+    message?: string;
+    amount?: string;
+    instruction?: string;
+    [name: string]: string | undefined;
+  };
+};
+
+function isEthereumAddress(address: string) {
+  if (!/^(0x)?[0-9a-f]{40}$/i.test(address)) {
+    return false;
+  } else if (
+    /^(0x|0X)?[0-9a-f]{40}$/.test(address) ||
+    /^(0x|0X)?[0-9A-F]{40}$/.test(address)
+  ) {
+    return true;
+  }
+  return checkAddressChecksum(address);
+}
+
+function checkAddressChecksum(address: string) {
+  //TODO implement ethereum checksum
+  return true;
+}
+
+function validateBitcoin(addr: string, i18n: Translator): string | undefined {
+  try {
+    const valid = /^(bc1|[13])[a-zA-HJ-NP-Z0-9]{25,39}$/.test(addr);
+    if (valid) return undefined;
+  } catch (e) {
+    console.log(e);
+  }
+  return i18n`This is not a valid bitcoin address.`;
+}
+
+function validateEthereum(addr: string, i18n: Translator): string | undefined {
+  try {
+    const valid = isEthereumAddress(addr);
+    if (valid) return undefined;
+  } catch (e) {
+    console.log(e);
+  }
+  return i18n`This is not a valid Ethereum address.`;
+}
+
+/**
+ * An IBAN is validated by converting it into an integer and performing a
+ * basic mod-97 operation (as described in ISO 7064) on it.
+ * If the IBAN is valid, the remainder equals 1.
+ *
+ * The algorithm of IBAN validation is as follows:
+ * 1.- Check that the total IBAN length is correct as per the country. If not, 
the IBAN is invalid
+ * 2.- Move the four initial characters to the end of the string
+ * 3.- Replace each letter in the string with two digits, thereby expanding 
the string, where A = 10, B = 11, ..., Z = 35
+ * 4.- Interpret the string as a decimal integer and compute the remainder of 
that number on division by 97
+ *
+ * If the remainder is 1, the check digit test is passed and the IBAN might be 
valid.
+ *
+ */
+function validateIBAN(iban: string, i18n: Translator): string | undefined {
+  // Check total length
+  if (iban.length < 4)
+    return i18n`IBAN numbers usually have more that 4 digits`;
+  if (iban.length > 34)
+    return i18n`IBAN numbers usually have less that 34 digits`;
+
+  const A_code = "A".charCodeAt(0);
+  const Z_code = "Z".charCodeAt(0);
+  const IBAN = iban.toUpperCase();
+  // check supported country
+  const code = IBAN.substr(0, 2);
+  const found = code in COUNTRY_TABLE;
+  if (!found) return i18n`IBAN country code not found`;
+
+  // 2.- Move the four initial characters to the end of the string
+  const step2 = IBAN.substr(4) + iban.substr(0, 4);
+  const step3 = Array.from(step2)
+    .map((letter) => {
+      const code = letter.charCodeAt(0);
+      if (code < A_code || code > Z_code) return letter;
+      return `${letter.charCodeAt(0) - "A".charCodeAt(0) + 10}`;
+    })
+    .join("");
+
+  function calculate_iban_checksum(str: string): number {
+    const numberStr = str.substr(0, 5);
+    const rest = str.substr(5);
+    const number = parseInt(numberStr, 10);
+    const result = number % 97;
+    if (rest.length > 0) {
+      return calculate_iban_checksum(`${result}${rest}`);
+    }
+    return result;
+  }
+
+  const checksum = calculate_iban_checksum(step3);
+  if (checksum !== 1) return i18n`IBAN number is not valid, checksum is wrong`;
+  return undefined;
+}
+
+// const targets = ['ach', 'bic', 'iban', 'upi', 'bitcoin', 'ilp', 'void', 
'x-taler-bank']
+const targets = [
+  "Choose one...",
+  "iban",
+  "x-taler-bank",
+  "bitcoin",
+  "ethereum",
+];
+const noTargetValue = targets[0];
+const defaultTarget = { target: noTargetValue, options: {} };
+
+function undefinedIfEmpty<T>(obj: T): T | undefined {
+  return Object.keys(obj).some((k) => (obj as any)[k] !== undefined)
+    ? obj
+    : undefined;
+}
+
+export function InputPaytoForm<T>({
+  name,
+  readonly,
+  label,
+  tooltip,
+}: Props<keyof T>): VNode {
+  const { value: paytos, onChange } = useField<T>(name);
+
+  const [value, valueHandler] = useState<Partial<Entity>>(defaultTarget);
+
+  let payToPath;
+  if (value.target === "iban" && value.path1) {
+    payToPath = `/${value.path1.toUpperCase()}`;
+  } else if (value.path1) {
+    if (value.path2) {
+      payToPath = `/${value.path1}/${value.path2}`;
+    } else {
+      payToPath = `/${value.path1}`;
+    }
+  }
+  const i18n = useTranslator();
+
+  const ops = value.options!;
+  const url = tryUrl(`payto://${value.target}${payToPath}`);
+  if (url) {
+    Object.keys(ops).forEach((opt_key) => {
+      const opt_value = ops[opt_key];
+      if (opt_value) url.searchParams.set(opt_key, opt_value);
+    });
+  }
+  const paytoURL = !url ? "" : url.toString();
+
+  const errors: FormErrors<Entity> = {
+    target: value.target === noTargetValue ? i18n`required` : undefined,
+    path1: !value.path1
+      ? i18n`required`
+      : value.target === "iban"
+      ? validateIBAN(value.path1, i18n)
+      : value.target === "bitcoin"
+      ? validateBitcoin(value.path1, i18n)
+      : value.target === "ethereum"
+      ? validateEthereum(value.path1, i18n)
+      : undefined,
+    path2:
+      value.target === "x-taler-bank"
+        ? !value.path2
+          ? i18n`required`
+          : undefined
+        : undefined,
+    options: undefinedIfEmpty({
+      "receiver-name": !value.options?.["receiver-name"]
+        ? i18n`required`
+        : undefined,
+    }),
+  };
+
+  const hasErrors = Object.keys(errors).some(
+    (k) => (errors as any)[k] !== undefined
+  );
+
+  const submit = useCallback((): void => {
+    const alreadyExists =
+      paytos.findIndex((x: string) => x === paytoURL) !== -1;
+    if (!alreadyExists) {
+      onChange([paytoURL, ...paytos] as any);
+    }
+    valueHandler(defaultTarget);
+  }, [value]);
+
+  //FIXME: translating plural singular
+  return (
+    <InputGroup name="payto" label={label} fixed tooltip={tooltip}>
+      <FormProvider<Entity>
+        name="tax"
+        errors={errors}
+        object={value}
+        valueHandler={valueHandler}
+      >
+        <InputSelector<Entity>
+          name="target"
+          label={i18n`Target type`}
+          tooltip={i18n`Method to use for wire transfer`}
+          values={targets}
+          toStr={(v) => (v === noTargetValue ? i18n`Choose one...` : v)}
+        />
+
+        {value.target === "ach" && (
+          <Fragment>
+            <Input<Entity>
+              name="path1"
+              label={i18n`Routing`}
+              tooltip={i18n`Routing number.`}
+            />
+            <Input<Entity>
+              name="path2"
+              label={i18n`Account`}
+              tooltip={i18n`Account number.`}
+            />
+          </Fragment>
+        )}
+        {value.target === "bic" && (
+          <Fragment>
+            <Input<Entity>
+              name="path1"
+              label={i18n`Code`}
+              tooltip={i18n`Business Identifier Code.`}
+            />
+          </Fragment>
+        )}
+        {value.target === "iban" && (
+          <Fragment>
+            <Input<Entity>
+              name="path1"
+              label={i18n`Account`}
+              tooltip={i18n`Bank Account Number.`}
+              inputExtra={{ style: { textTransform: "uppercase" } }}
+            />
+          </Fragment>
+        )}
+        {value.target === "upi" && (
+          <Fragment>
+            <Input<Entity>
+              name="path1"
+              label={i18n`Account`}
+              tooltip={i18n`Unified Payment Interface.`}
+            />
+          </Fragment>
+        )}
+        {value.target === "bitcoin" && (
+          <Fragment>
+            <Input<Entity>
+              name="path1"
+              label={i18n`Address`}
+              tooltip={i18n`Bitcoin protocol.`}
+            />
+          </Fragment>
+        )}
+        {value.target === "ethereum" && (
+          <Fragment>
+            <Input<Entity>
+              name="path1"
+              label={i18n`Address`}
+              tooltip={i18n`Ethereum protocol.`}
+            />
+          </Fragment>
+        )}
+        {value.target === "ilp" && (
+          <Fragment>
+            <Input<Entity>
+              name="path1"
+              label={i18n`Address`}
+              tooltip={i18n`Interledger protocol.`}
+            />
+          </Fragment>
+        )}
+        {value.target === "void" && <Fragment />}
+        {value.target === "x-taler-bank" && (
+          <Fragment>
+            <Input<Entity>
+              name="path1"
+              label={i18n`Host`}
+              tooltip={i18n`Bank host.`}
+            />
+            <Input<Entity>
+              name="path2"
+              label={i18n`Account`}
+              tooltip={i18n`Bank account.`}
+            />
+          </Fragment>
+        )}
+
+        {value.target !== noTargetValue && (
+          <Input
+            name="options.receiver-name"
+            label={i18n`Name`}
+            tooltip={i18n`Bank account owner's name.`}
+          />
+        )}
+
+        <div class="field is-horizontal">
+          <div class="field-label is-normal" />
+          <div class="field-body" style={{ display: "block" }}>
+            {paytos.map((v: any, i: number) => (
+              <div
+                key={i}
+                class="tags has-addons mt-3 mb-0 mr-3"
+                style={{ flexWrap: "nowrap" }}
+              >
+                <span
+                  class="tag is-medium is-info mb-0"
+                  style={{ maxWidth: "90%" }}
+                >
+                  {v}
+                </span>
+                <a
+                  class="tag is-medium is-danger is-delete mb-0"
+                  onClick={() => {
+                    onChange(paytos.filter((f: any) => f !== v) as any);
+                  }}
+                />
+              </div>
+            ))}
+            {!paytos.length && i18n`No accounts yet.`}
+          </div>
+        </div>
+
+        {value.target !== noTargetValue && (
+          <div class="buttons is-right mt-5">
+            <button
+              class="button is-info"
+              data-tooltip={i18n`add tax to the tax list`}
+              disabled={hasErrors}
+              onClick={submit}
+            >
+              <Translate>Add</Translate>
+            </button>
+          </div>
+        )}
+      </FormProvider>
+    </InputGroup>
+  );
+}
+
+function tryUrl(s: string): URL | undefined {
+  try {
+    return new URL(s);
+  } catch (e) {
+    return undefined;
+  }
+}
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputSearchProduct.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputSearchProduct.tsx
new file mode 100644
index 000000000..51f84fd12
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/form/InputSearchProduct.tsx
@@ -0,0 +1,139 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import { h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import emptyImage from "../../assets/empty.png";
+import { MerchantBackend, WithId } from "../../declaration";
+import { useInstanceProducts } from "../../hooks/product";
+import { Translate, useTranslator } from "../../i18n";
+import { FormErrors, FormProvider } from "./FormProvider";
+import { InputWithAddon } from "./InputWithAddon";
+
+type Entity = MerchantBackend.Products.ProductDetail & WithId
+
+export interface Props {
+  selected?: Entity;
+  onChange: (p?: Entity) => void;
+  products: (MerchantBackend.Products.ProductDetail & WithId)[],
+}
+
+interface ProductSearch {
+  name: string;
+}
+
+export function InputSearchProduct({ selected, onChange, products }: Props): 
VNode {
+  const [prodForm, setProdName] = useState<Partial<ProductSearch>>({ name: '' 
})
+
+  const errors: FormErrors<ProductSearch> = {
+    name: undefined
+  }
+  const i18n = useTranslator()
+
+
+  if (selected) {
+    return <article class="media">
+      <figure class="media-left">
+        <p class="image is-128x128">
+          <img src={selected.image ? selected.image : emptyImage} />
+        </p>
+      </figure>
+      <div class="media-content">
+        <div class="content">
+          <p class="media-meta"><Translate>Product id</Translate>: 
<b>{selected.id}</b></p>
+          <p><Translate>Description</Translate>: {selected.description}</p>
+          <div class="buttons is-right mt-5">
+            <button class="button is-info" onClick={() => 
onChange(undefined)}>clear</button>
+          </div>
+        </div>
+      </div>
+    </article>
+  }
+
+  return <FormProvider<ProductSearch> errors={errors} object={prodForm} 
valueHandler={setProdName} >
+
+    <InputWithAddon<ProductSearch>
+      name="name"
+      label={i18n`Product`}
+      tooltip={i18n`search products by it's description or id`}
+      addonAfter={<span class="icon" ><i class="mdi mdi-magnify" /></span>}
+    >
+      <div>
+        <ProductList
+          name={prodForm.name}
+          list={products}
+          onSelect={(p) => {
+            setProdName({ name: '' })
+            onChange(p)
+          }}
+        />
+      </div>
+    </InputWithAddon>
+
+  </FormProvider>
+
+}
+
+interface ProductListProps {
+  name?: string;
+  onSelect: (p: MerchantBackend.Products.ProductDetail & WithId) => void;
+  list: (MerchantBackend.Products.ProductDetail & WithId)[]
+}
+
+function ProductList({ name, onSelect, list }: ProductListProps) {
+  if (!name) {
+    /* FIXME
+      this BR is added to occupy the space that will be added when the 
+      dropdown appears
+    */
+    return <div ><br /></div>
+  }
+  const filtered = list.filter(p => p.id.includes(name) || 
p.description.includes(name))
+
+  return <div class="dropdown is-active">
+    <div class="dropdown-menu" id="dropdown-menu" role="menu" style={{ 
minWidth: '20rem' }}>
+      <div class="dropdown-content">
+        {!filtered.length ?
+          <div class="dropdown-item" >
+            <Translate>no products found with that description</Translate>
+          </div> :
+          filtered.map(p => (
+            <div key={p.id} class="dropdown-item" onClick={() => onSelect(p)} 
style={{ cursor: 'pointer' }}>
+              <article class="media">
+                <div class="media-left">
+                  <div class="image" style={{ minWidth: 64 }}><img 
src={p.image ? p.image : emptyImage} style={{ width: 64, height: 64 }} /></div>
+                </div>
+                <div class="media-content">
+                  <div class="content">
+                    <p>
+                      <strong>{p.id}</strong> <small>{p.price}</small>
+                      <br />
+                      {p.description}
+                    </p>
+                  </div>
+                </div>
+              </article>
+            </div>
+          ))
+        }
+      </div>
+    </div>
+  </div>
+}
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputSecured.stories.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputSecured.stories.tsx
new file mode 100644
index 000000000..1990eeeae
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/components/form/InputSecured.stories.tsx
@@ -0,0 +1,55 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode } from 'preact';
+import { useState } from 'preact/hooks';
+import { FormProvider } from "./FormProvider";
+import { InputSecured } from './InputSecured';
+
+export default {
+  title: 'Components/Form/InputSecured',
+  component: InputSecured,
+};
+
+type T = { auth_token: string | null }
+
+export const InitialValueEmpty = (): VNode => {
+  const [state, setState] = useState<Partial<T>>({ auth_token: '' })
+  return <FormProvider<T> object={state} errors={{}} valueHandler={setState}>
+    Initial value: ''
+    <InputSecured<T> name="auth_token" label="Access token" />
+  </FormProvider>
+}
+
+export const InitialValueToken = (): VNode => {
+  const [state, setState] = useState<Partial<T>>({ auth_token: 'token' })
+  return <FormProvider<T> object={state} errors={{}} valueHandler={setState}>
+    <InputSecured<T> name="auth_token" label="Access token" />
+  </FormProvider>
+}
+
+export const InitialValueNull = (): VNode => {
+  const [state, setState] = useState<Partial<T>>({ auth_token: null })
+  return <FormProvider<T> object={state} errors={{}} valueHandler={setState}>
+    Initial value: ''
+    <InputSecured<T> name="auth_token" label="Access token" />
+  </FormProvider>
+}
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputSecured.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputSecured.tsx
new file mode 100644
index 000000000..c9b0f43b9
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/form/InputSecured.tsx
@@ -0,0 +1,119 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import { Fragment, h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { Translate, useTranslator } from "../../i18n";
+import { InputProps, useField } from "./useField";
+
+export type Props<T> = InputProps<T>;
+
+const TokenStatus = ({ prev, post }: any) => {
+  if ((prev === undefined || prev === null) && (post === undefined || post === 
null))
+    return null
+  return (prev === post) ? null : (
+    post === null ?
+      <span class="tag is-danger is-align-self-center 
ml-2"><Translate>Deleting</Translate></span> :
+      <span class="tag is-warning is-align-self-center 
ml-2"><Translate>Changing</Translate></span>
+  )
+}
+
+export function InputSecured<T>({ name, readonly, placeholder, tooltip, label, 
help }: Props<keyof T>): VNode {
+  const { error, value, initial, onChange, toStr, fromStr } = 
useField<T>(name);
+
+  const [active, setActive] = useState(false);
+  const [newValue, setNuewValue] = useState("")
+
+  const i18n = useTranslator()
+
+  return <Fragment>
+    <div class="field is-horizontal">
+      <div class="field-label is-normal">
+        <label class="label">
+          {label}
+          {tooltip && <span class="icon has-tooltip-right" 
data-tooltip={tooltip}>
+            <i class="mdi mdi-information" />
+          </span>}
+        </label>
+      </div>
+      <div class="field-body is-flex-grow-3">
+        {!active ?
+          <Fragment>
+            <div class="field has-addons">
+              <button class="button" 
+                onClick={(): void => { setActive(!active); }} >
+                <div class="icon is-left"><i class="mdi mdi-lock-reset" 
/></div>
+                <span><Translate>Manage access token</Translate></span>
+              </button>
+              <TokenStatus prev={initial} post={value} />
+            </div>
+          </Fragment> :
+          <Fragment>
+            <div class="field has-addons">
+              <div class="control">
+                <a class="button is-static">secret-token:</a>
+              </div>
+              <div class="control is-expanded">
+                <input class="input" type="text"
+                  placeholder={placeholder} readonly={readonly || !active}
+                  disabled={readonly || !active}
+                  name={String(name)} value={newValue}
+                  onInput={(e): void => {
+                    setNuewValue(e.currentTarget.value)
+                  }} />
+                {help}
+              </div>
+              <div class="control">
+                <button class="button is-info" disabled={fromStr(newValue) === 
value} onClick={(): void => { onChange(fromStr(newValue)); setActive(!active); 
setNuewValue(""); }} >
+                  <div class="icon is-left"><i class="mdi mdi-lock-outline" 
/></div>
+                  <span><Translate>Update</Translate></span>
+                </button>
+              </div>
+            </div>
+          </Fragment>
+        }
+        {error ? <p class="help is-danger">{error}</p> : null}
+      </div>
+    </div>
+    {active &&
+      <div class="field is-horizontal">
+        <div class="field-body is-flex-grow-3">
+          <div class="level" style={{ width: '100%' }}>
+            <div class="level-right is-flex-grow-1">
+              <div class="level-item">
+                <button class="button is-danger" disabled={null === value || 
undefined === value} onClick={(): void => { onChange(null!); 
setActive(!active); setNuewValue(""); }} >
+                  <div class="icon is-left"><i class="mdi 
mdi-lock-open-variant" /></div>
+                  <span><Translate>Remove</Translate></span>
+                </button>
+              </div>
+              <div class="level-item">
+                <button class="button " onClick={(): void => { 
onChange(initial!); setActive(!active); setNuewValue(""); }} >
+                  <div class="icon is-left"><i class="mdi 
mdi-lock-open-variant" /></div>
+                  <span><Translate>Cancel</Translate></span>
+                </button>
+              </div>
+            </div>
+
+          </div>
+        </div>
+      </div>
+    }
+  </Fragment >;
+}
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputSelector.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputSelector.tsx
new file mode 100644
index 000000000..86f4de756
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/form/InputSelector.tsx
@@ -0,0 +1,86 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { h, VNode } from "preact";
+import { InputProps, useField } from "./useField";
+
+interface Props<T> extends InputProps<T> {
+  readonly?: boolean;
+  expand?: boolean;
+  values: string[];
+  toStr?: (v?: any) => string;
+  fromStr?: (s: string) => any;
+}
+
+const defaultToString = (f?: any): string => f || "";
+const defaultFromString = (v: string): any => v as any;
+
+export function InputSelector<T>({
+  name,
+  readonly,
+  expand,
+  placeholder,
+  tooltip,
+  label,
+  help,
+  values,
+  toStr = defaultToString,
+}: Props<keyof T>): VNode {
+  const { error, value, onChange } = useField<T>(name);
+
+  return (
+    <div class="field is-horizontal">
+      <div class="field-label is-normal">
+        <label class="label">
+          {label}
+          {tooltip && (
+            <span class="icon has-tooltip-right" data-tooltip={tooltip}>
+              <i class="mdi mdi-information" />
+            </span>
+          )}
+        </label>
+      </div>
+      <div class="field-body is-flex-grow-3">
+        <div class="field">
+          <p class={expand ? "control is-expanded select" : "control select"}>
+            <select
+              class={error ? "select is-danger" : "select"}
+              name={String(name)}
+              disabled={readonly}
+              readonly={readonly}
+              onChange={(e) => {
+                onChange(e.currentTarget.value as any);
+              }}
+            >
+              {placeholder && <option>{placeholder}</option>}
+              {values.map((v, i) => (
+                <option key={i} value={v} selected={value === v}>
+                  {toStr(v)}
+                </option>
+              ))}
+            </select>
+            {help}
+          </p>
+          {error && <p class="help is-danger">{error}</p>}
+        </div>
+      </div>
+    </div>
+  );
+}
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputStock.stories.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputStock.stories.tsx
new file mode 100644
index 000000000..63c7e4131
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/form/InputStock.stories.tsx
@@ -0,0 +1,162 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { addDays } from "date-fns";
+import { h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { FormProvider } from "./FormProvider";
+import { InputStock, Stock } from "./InputStock";
+
+export default {
+  title: "Components/Form/InputStock",
+  component: InputStock,
+};
+
+type T = { stock?: Stock };
+
+export const CreateStockEmpty = () => {
+  const [state, setState] = useState<Partial<T>>({});
+  return (
+    <FormProvider<T>
+      name="product"
+      object={state}
+      errors={{}}
+      valueHandler={setState}
+    >
+      <InputStock<T> name="stock" label="Stock" />
+      <div>
+        <pre>{JSON.stringify(state, undefined, 2)}</pre>
+      </div>
+    </FormProvider>
+  );
+};
+
+export const CreateStockUnknownRestock = () => {
+  const [state, setState] = useState<Partial<T>>({
+    stock: {
+      current: 10,
+      lost: 0,
+      sold: 0,
+    },
+  });
+  return (
+    <FormProvider<T>
+      name="product"
+      object={state}
+      errors={{}}
+      valueHandler={setState}
+    >
+      <InputStock<T> name="stock" label="Stock" />
+      <div>
+        <pre>{JSON.stringify(state, undefined, 2)}</pre>
+      </div>
+    </FormProvider>
+  );
+};
+
+export const CreateStockNoRestock = () => {
+  const [state, setState] = useState<Partial<T>>({
+    stock: {
+      current: 10,
+      lost: 0,
+      sold: 0,
+      nextRestock: { t_s: "never" },
+    },
+  });
+  return (
+    <FormProvider<T>
+      name="product"
+      object={state}
+      errors={{}}
+      valueHandler={setState}
+    >
+      <InputStock<T> name="stock" label="Stock" />
+      <div>
+        <pre>{JSON.stringify(state, undefined, 2)}</pre>
+      </div>
+    </FormProvider>
+  );
+};
+
+export const CreateStockWithRestock = () => {
+  const [state, setState] = useState<Partial<T>>({
+    stock: {
+      current: 15,
+      lost: 0,
+      sold: 0,
+      nextRestock: { t_s: addDays(new Date(), 1).getTime() / 1000 },
+    },
+  });
+  return (
+    <FormProvider<T>
+      name="product"
+      object={state}
+      errors={{}}
+      valueHandler={setState}
+    >
+      <InputStock<T> name="stock" label="Stock" />
+      <div>
+        <pre>{JSON.stringify(state, undefined, 2)}</pre>
+      </div>
+    </FormProvider>
+  );
+};
+
+export const UpdatingProductWithManagedStock = () => {
+  const [state, setState] = useState<Partial<T>>({
+    stock: {
+      current: 100,
+      lost: 0,
+      sold: 0,
+      nextRestock: { t_s: addDays(new Date(), 1).getTime() / 1000 },
+    },
+  });
+  return (
+    <FormProvider<T>
+      name="product"
+      object={state}
+      errors={{}}
+      valueHandler={setState}
+    >
+      <InputStock<T> name="stock" label="Stock" alreadyExist />
+      <div>
+        <pre>{JSON.stringify(state, undefined, 2)}</pre>
+      </div>
+    </FormProvider>
+  );
+};
+
+export const UpdatingProductWithInfiniteStock = () => {
+  const [state, setState] = useState<Partial<T>>({});
+  return (
+    <FormProvider<T>
+      name="product"
+      object={state}
+      errors={{}}
+      valueHandler={setState}
+    >
+      <InputStock<T> name="stock" label="Stock" alreadyExist />
+      <div>
+        <pre>{JSON.stringify(state, undefined, 2)}</pre>
+      </div>
+    </FormProvider>
+  );
+};
diff --git a/packages/merchant-backoffice-ui/src/components/form/InputStock.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputStock.tsx
new file mode 100644
index 000000000..158f44192
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/form/InputStock.tsx
@@ -0,0 +1,171 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import { Fragment, h } from "preact";
+import { MerchantBackend, Timestamp } from "../../declaration";
+import { InputProps, useField } from "./useField";
+import { FormProvider, FormErrors } from "./FormProvider";
+import { useLayoutEffect, useState } from "preact/hooks";
+import { Input } from "./Input";
+import { InputGroup } from "./InputGroup";
+import { InputNumber } from "./InputNumber";
+import { InputDate } from "./InputDate";
+import { Translate, useTranslator } from "../../i18n";
+import { InputLocation } from "./InputLocation";
+
+export interface Props<T> extends InputProps<T> {
+  alreadyExist?: boolean;
+}
+
+
+type Entity = Stock
+
+export interface Stock {
+  current: number;
+  lost: number;
+  sold: number;
+  address?: MerchantBackend.Location;
+  nextRestock?: Timestamp;
+}
+
+interface StockDelta {
+  incoming: number;
+  lost: number;
+}
+
+
+export function InputStock<T>({ name, tooltip, label, alreadyExist }: 
Props<keyof T>) {
+  const { error, value, onChange } = useField<T>(name);
+
+  const [errors, setErrors] = useState<FormErrors<Entity>>({})
+
+  const [formValue, valueHandler] = useState<Partial<Entity>>(value)
+  const [addedStock, setAddedStock] = useState<StockDelta>({ incoming: 0, 
lost: 0 })
+  const i18n = useTranslator()
+
+
+  useLayoutEffect(() => {
+    if (!formValue) {
+      onChange(undefined as any)
+    } else {
+      onChange({
+        ...formValue,
+        current: (formValue?.current || 0) + addedStock.incoming,
+        lost: (formValue?.lost || 0) + addedStock.lost
+      } as any)
+    }
+  }, [formValue, addedStock])
+
+  if (!formValue) {
+    return <Fragment>
+      <div class="field is-horizontal">
+        <div class="field-label is-normal">
+          <label class="label">
+            {label}
+            {tooltip && <span class="icon has-tooltip-right" 
data-tooltip={tooltip}>
+              <i class="mdi mdi-information" />
+            </span>}
+          </label>
+        </div>
+        <div class="field-body is-flex-grow-3">
+          <div class="field has-addons">
+            {!alreadyExist ?
+              <button class="button" 
+                data-tooltip={i18n`click here to configure the stock of the 
product, leave it as is and the backend will not control stock`}
+                onClick={(): void => { valueHandler({ current: 0, lost: 0, 
sold: 0 } as Stock as any); }} >
+                <span><Translate>Manage stock</Translate></span>
+              </button> : <button class="button" 
+                data-tooltip={i18n`this product has been configured without 
stock control`}
+                disabled >
+                <span><Translate>Infinite</Translate></span>
+              </button>
+            }
+          </div>
+        </div>
+      </div>
+    </Fragment >
+  }
+
+  const currentStock = (formValue.current || 0) - (formValue.lost || 0) - 
(formValue.sold || 0)
+
+  const stockAddedErrors: FormErrors<typeof addedStock> = {
+    lost: currentStock + addedStock.incoming < addedStock.lost ?
+      i18n`lost cannot be greater than current and incoming (max 
${currentStock + addedStock.incoming})`
+      : undefined
+  }
+
+  // const stockUpdateDescription = stockAddedErrors.lost ? '' : (
+  //   !!addedStock.incoming || !!addedStock.lost ?
+  //     i18n`current stock will change from ${currentStock} to ${currentStock 
+ addedStock.incoming - addedStock.lost}` :
+  //     i18n`current stock will stay at ${currentStock}`
+  // )
+
+  return <Fragment>
+    <div class="card">
+      <header class="card-header">
+        <p class="card-header-title">
+          {label}
+          {tooltip && <span class="icon" data-tooltip={tooltip}>
+            <i class="mdi mdi-information" />
+          </span>}
+        </p>
+      </header>
+      <div class="card-content">
+        <FormProvider<Entity> name="stock" errors={errors} object={formValue} 
valueHandler={valueHandler}>
+          {alreadyExist ? <Fragment>
+
+            <FormProvider name="added" errors={stockAddedErrors} 
object={addedStock} valueHandler={setAddedStock as any}>
+              <InputNumber name="incoming" label={i18n`Incoming`} />
+              <InputNumber name="lost" label={i18n`Lost`} />
+            </FormProvider>
+
+            {/* <div class="field is-horizontal">
+              <div class="field-label is-normal" />
+              <div class="field-body is-flex-grow-3">
+                <div class="field">
+                  {stockUpdateDescription}
+                </div>
+              </div>
+            </div> */}
+
+          </Fragment> : <InputNumber<Entity> name="current"
+            label={i18n`Current`}
+            side={
+              <button class="button is-danger" 
+                data-tooltip={i18n`remove stock control for this product`}
+                onClick={(): void => { valueHandler(undefined as any) }} >
+                <span><Translate>without stock</Translate></span>
+              </button>
+            }
+          />}
+
+          <InputDate<Entity> name="nextRestock" label={i18n`Next restock`} 
withTimestampSupport />
+
+          <InputGroup<Entity> name="address" label={i18n`Delivery address`}>
+            <InputLocation name="address" />
+          </InputGroup>
+        </FormProvider>
+      </div>
+    </div>
+  </Fragment>
+}
+  // (
+
+
diff --git a/packages/merchant-backoffice-ui/src/components/form/InputTaxes.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputTaxes.tsx
new file mode 100644
index 000000000..507a61242
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/form/InputTaxes.tsx
@@ -0,0 +1,97 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import { h, VNode } from "preact";
+import { useCallback, useState } from "preact/hooks";
+import * as yup from 'yup';
+import { MerchantBackend } from "../../declaration";
+import { Translate, useTranslator } from "../../i18n";
+import { TaxSchema as schema } from '../../schemas';
+import { FormErrors, FormProvider } from "./FormProvider";
+import { Input } from "./Input";
+import { InputGroup } from "./InputGroup";
+import { InputProps, useField } from "./useField";
+
+export interface Props<T> extends InputProps<T> {
+  isValid?: (e: any) => boolean;
+}
+
+type Entity = MerchantBackend.Tax
+export function InputTaxes<T>({ name, readonly, label }: Props<keyof T>): 
VNode {
+  const { value: taxes, onChange, } = useField<T>(name);
+
+  const [value, valueHandler] = useState<Partial<Entity>>({})
+  // const [errors, setErrors] = useState<FormErrors<Entity>>({})
+
+  let errors: FormErrors<Entity> = {}
+
+  try {
+    schema.validateSync(value, { abortEarly: false })
+  } catch (err) {
+    if (err instanceof yup.ValidationError) {
+      const yupErrors = err.inner as yup.ValidationError[]
+      errors = yupErrors.reduce((prev, cur) => !cur.path ? prev : ({ ...prev, 
[cur.path]: cur.message }), {})      
+    }
+  }
+  const hasErrors = Object.keys(errors).some(k => (errors as any)[k] !== 
undefined)
+
+  const submit = useCallback((): void => {
+    onChange([value as any, ...taxes] as any)
+    valueHandler({})
+  }, [value])
+
+  const i18n = useTranslator()
+
+  //FIXME: translating plural singular
+  return (
+    <InputGroup name="tax" label={label} alternative={taxes.length > 0 && 
<p>This product has {taxes.length} applicable taxes configured.</p>}>
+      <FormProvider<Entity> name="tax" errors={errors} object={value} 
valueHandler={valueHandler} >
+
+        <div class="field is-horizontal">
+          <div class="field-label is-normal" />
+          <div class="field-body" style={{ display: 'block' }}>
+            {taxes.map((v: any, i: number) => <div key={i} class="tags 
has-addons mt-3 mb-0 mr-3" style={{ flexWrap: 'nowrap' }}>
+              <span class="tag is-medium is-info mb-0" style={{ maxWidth: 
'90%' }}><b>{v.tax}</b>: {v.name}</span>
+              <a class="tag is-medium is-danger is-delete mb-0" onClick={() => 
{
+                onChange(taxes.filter((f: any) => f !== v) as any);
+                valueHandler(v);
+              }} />
+            </div>
+            )}
+            {!taxes.length && i18n`No taxes configured for this product.`}
+          </div>
+        </div>
+
+        <Input<Entity> name="tax" label={i18n`Amount`} tooltip={i18n`Taxes can 
be in currencies that differ from the main currency used by the merchant.`}>
+          <Translate>Enter currency and value separated with a colon, e.g. 
"USD:2.3".</Translate>
+        </Input>
+
+        <Input<Entity> name="name" label={i18n`Description`} 
tooltip={i18n`Legal name of the tax, e.g. VAT or import duties.`} />
+
+        <div class="buttons is-right mt-5">
+          <button class="button is-info"
+            data-tooltip={i18n`add tax to the tax list`}
+            disabled={hasErrors}
+            onClick={submit}><Translate>Add</Translate></button>
+        </div>
+      </FormProvider>
+    </InputGroup>
+  )
+}
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/InputWithAddon.tsx 
b/packages/merchant-backoffice-ui/src/components/form/InputWithAddon.tsx
new file mode 100644
index 000000000..a16ebc2e9
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/form/InputWithAddon.tsx
@@ -0,0 +1,77 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import { ComponentChildren, h, VNode } from "preact";
+import { InputProps, useField } from "./useField";
+
+export interface Props<T> extends InputProps<T> {
+  expand?: boolean;
+  inputType?: 'text' | 'number';
+  addonBefore?: ComponentChildren;
+  addonAfter?: ComponentChildren;
+  toStr?: (v?: any) => string;
+  fromStr?: (s: string) => any;
+  inputExtra?: any,
+  children?: ComponentChildren,
+  side?: ComponentChildren;
+}
+
+const defaultToString = (f?: any): string => f || ''
+const defaultFromString = (v: string): any => v as any
+
+export function InputWithAddon<T>({ name, readonly, addonBefore, children, 
expand, label, placeholder, help, tooltip, inputType, inputExtra, side, 
addonAfter, toStr = defaultToString, fromStr = defaultFromString }: Props<keyof 
T>): VNode {
+  const { error, value, onChange, required } = useField<T>(name);
+
+  return <div class="field is-horizontal">
+    <div class="field-label is-normal">
+      <label class="label">
+        {label}
+        {tooltip && <span class="icon has-tooltip-right" 
data-tooltip={tooltip}>
+          <i class="mdi mdi-information" />
+        </span>}
+      </label>
+    </div>
+    <div class="field-body is-flex-grow-3">
+      <div class="field">
+        <div class="field has-addons">
+          {addonBefore && <div class="control">
+            <a class="button is-static">{addonBefore}</a>
+          </div>}
+          <p class={`control${expand ? " is-expanded" :""}${required ? " 
has-icons-right" : ''}`}>
+            <input {...(inputExtra || {})} class={error ? "input is-danger" : 
"input"} type={inputType}
+              placeholder={placeholder} readonly={readonly}
+              name={String(name)} value={toStr(value)}
+              onChange={(e): void => onChange(fromStr(e.currentTarget.value))} 
/>
+            {required && <span class="icon has-text-danger is-right">
+              <i class="mdi mdi-alert" />
+            </span>}
+            {help}
+            {children}
+          </p>
+          {addonAfter && <div class="control">
+            <a class="button is-static">{addonAfter}</a>
+          </div>}
+        </div>
+        {error && <p class="help is-danger">{error}</p>}
+      </div>
+      {side}
+    </div>
+  </div>;
+}
diff --git a/packages/merchant-backoffice-ui/src/components/form/TextField.tsx 
b/packages/merchant-backoffice-ui/src/components/form/TextField.tsx
new file mode 100644
index 000000000..2579a27b2
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/form/TextField.tsx
@@ -0,0 +1,53 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import { ComponentChildren, h, VNode } from "preact";
+import { useField, InputProps } from "./useField";
+
+interface Props<T> extends InputProps<T> {
+  inputType?: 'text' | 'number' | 'multiline' | 'password';
+  expand?: boolean;
+  side?: ComponentChildren;
+  children: ComponentChildren;
+}
+
+export function TextField<T>({ name, tooltip, label, expand, help, children, 
side}: Props<keyof T>): VNode {
+  const { error } = useField<T>(name);
+  return <div class="field is-horizontal">
+    <div class="field-label is-normal">
+      <label class="label">
+        {label}
+        {tooltip && <span class="icon has-tooltip-right" 
data-tooltip={tooltip}>
+          <i class="mdi mdi-information" />
+        </span>}
+      </label>
+    </div>
+    <div class="field-body is-flex-grow-3">
+      <div class="field">
+        <p class={expand ? "control is-expanded has-icons-right" : "control 
has-icons-right"}>
+          {children}          
+          {help}
+        </p>
+        {error && <p class="help is-danger">{error}</p>}
+      </div>
+      {side}
+    </div>
+  </div>;
+}
diff --git a/packages/merchant-backoffice-ui/src/components/form/useField.tsx 
b/packages/merchant-backoffice-ui/src/components/form/useField.tsx
new file mode 100644
index 000000000..8479d7ad8
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/form/useField.tsx
@@ -0,0 +1,86 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { ComponentChildren, VNode } from "preact";
+import { useFormContext } from "./FormProvider";
+
+interface Use<V> {
+  error?: string;
+  required: boolean;
+  value: any;
+  initial: any;
+  onChange: (v: V) => void;
+  toStr: (f: V | undefined) => string;
+  fromStr: (v: string) => V
+}
+
+export function useField<T>(name: keyof T): Use<T[typeof name]> {
+  const { errors, object, initialObject, toStr, fromStr, valueHandler } = 
useFormContext<T>()
+  type P = typeof name
+  type V = T[P]
+
+  const updateField = (field: P) => (value: V): void => {
+    return valueHandler((prev) => {
+      return setValueDeeper(prev, String(field).split('.'), value)
+    })
+  }
+
+  const defaultToString = ((f?: V): string => String(!f ? '' : f))
+  const defaultFromString = ((v: string): V => v as any)
+  const value = readField(object, String(name))
+  const initial = readField(initialObject, String(name))
+  const isDirty = value !== initial
+  const hasError = readField(errors, String(name))
+  return {
+    error: isDirty ? hasError : undefined,
+    required: !isDirty && hasError,
+    value,
+    initial,
+    onChange: updateField(name) as any,
+    toStr: toStr[name] ? toStr[name]! : defaultToString,
+    fromStr: fromStr[name] ? fromStr[name]! : defaultFromString,
+  }
+}
+/**
+ * read the field of an object an support accessing it using '.'
+ * 
+ * @param object 
+ * @param name 
+ * @returns 
+ */
+const readField = (object: any, name: string) => {
+  return name.split('.').reduce((prev, current) => prev && prev[current], 
object)
+}
+
+const setValueDeeper = (object: any, names: string[], value: any): any => {
+  if (names.length === 0) return value
+  const [head, ...rest] = names
+  return { ...object, [head]: setValueDeeper(object[head] || {}, rest, value) }
+}
+
+export interface InputProps<T> {
+  name: T;
+  label: ComponentChildren;
+  placeholder?: string;
+  tooltip?: ComponentChildren;
+  readonly?: boolean;
+  help?: ComponentChildren;
+}
\ No newline at end of file
diff --git 
a/packages/merchant-backoffice-ui/src/components/form/useGroupField.tsx 
b/packages/merchant-backoffice-ui/src/components/form/useGroupField.tsx
new file mode 100644
index 000000000..a73f464a1
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/form/useGroupField.tsx
@@ -0,0 +1,40 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { useFormContext } from "./FormProvider";
+
+interface Use {
+  hasError?: boolean;
+}
+
+export function useGroupField<T>(name: keyof T): Use {
+  const f = useFormContext<T>();
+  if (!f)
+    return {};
+
+  return {
+    hasError: readField(f.errors, String(name))
+  };
+}
+
+const readField = (object: any, name: string) => {
+  return name.split('.').reduce((prev, current) => prev && prev[current], 
object)
+}
diff --git 
a/packages/merchant-backoffice-ui/src/components/instance/DefaultInstanceFormFields.tsx
 
b/packages/merchant-backoffice-ui/src/components/instance/DefaultInstanceFormFields.tsx
new file mode 100644
index 000000000..d80c65cc2
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/components/instance/DefaultInstanceFormFields.tsx
@@ -0,0 +1,135 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { Fragment, h, VNode } from "preact";
+import { useBackendContext } from "../../context/backend";
+import { useTranslator } from "../../i18n";
+import { Entity } from "../../paths/admin/create/CreatePage";
+import { Input } from "../form/Input";
+import { InputCurrency } from "../form/InputCurrency";
+import { InputDuration } from "../form/InputDuration";
+import { InputGroup } from "../form/InputGroup";
+import { InputImage } from "../form/InputImage";
+import { InputLocation } from "../form/InputLocation";
+import { InputPaytoForm } from "../form/InputPaytoForm";
+import { InputWithAddon } from "../form/InputWithAddon";
+
+export function DefaultInstanceFormFields({
+  readonlyId,
+  showId,
+}: {
+  readonlyId?: boolean;
+  showId: boolean;
+}): VNode {
+  const i18n = useTranslator();
+  const backend = useBackendContext();
+  return (
+    <Fragment>
+      {showId && (
+        <InputWithAddon<Entity>
+          name="id"
+          addonBefore={`${backend.url}/instances/`}
+          readonly={readonlyId}
+          label={i18n`Identifier`}
+          tooltip={i18n`Name of the instance in URLs. The 'default' instance 
is special in that it is used to administer other instances.`}
+        />
+      )}
+
+      <Input<Entity>
+        name="name"
+        label={i18n`Business name`}
+        tooltip={i18n`Legal name of the business represented by this 
instance.`}
+      />
+
+      <Input<Entity>
+        name="email"
+        label={i18n`Email`}
+        tooltip={i18n`Contact email`}
+      />
+
+      <Input<Entity>
+        name="website"
+        label={i18n`Website URL`}
+        tooltip={i18n`URL.`}
+      />
+
+      <InputImage<Entity>
+        name="logo"
+        label={i18n`Logo`}
+        tooltip={i18n`Logo image.`}
+      />
+
+      <InputPaytoForm<Entity>
+        name="payto_uris"
+        label={i18n`Bank account`}
+        tooltip={i18n`URI specifying bank account for crediting revenue.`}
+      />
+
+      <InputCurrency<Entity>
+        name="default_max_deposit_fee"
+        label={i18n`Default max deposit fee`}
+        tooltip={i18n`Maximum deposit fees this merchant is willing to pay per 
order by default.`}
+      />
+
+      <InputCurrency<Entity>
+        name="default_max_wire_fee"
+        label={i18n`Default max wire fee`}
+        tooltip={i18n`Maximum wire fees this merchant is willing to pay per 
wire transfer by default.`}
+      />
+
+      <Input<Entity>
+        name="default_wire_fee_amortization"
+        label={i18n`Default wire fee amortization`}
+        tooltip={i18n`Number of orders excess wire transfer fees will be 
divided by to compute per order surcharge.`}
+      />
+
+      <InputGroup
+        name="address"
+        label={i18n`Address`}
+        tooltip={i18n`Physical location of the merchant.`}
+      >
+        <InputLocation name="address" />
+      </InputGroup>
+
+      <InputGroup
+        name="jurisdiction"
+        label={i18n`Jurisdiction`}
+        tooltip={i18n`Jurisdiction for legal disputes with the merchant.`}
+      >
+        <InputLocation name="jurisdiction" />
+      </InputGroup>
+
+      <InputDuration<Entity>
+        name="default_pay_delay"
+        label={i18n`Default payment delay`}
+        withForever
+        tooltip={i18n`Time customers have to pay an order before the offer 
expires by default.`}
+      />
+
+      <InputDuration<Entity>
+        name="default_wire_transfer_delay"
+        label={i18n`Default wire transfer delay`}
+        tooltip={i18n`Maximum time an exchange is allowed to delay wiring 
funds to the merchant, enabling it to aggregate smaller payments into larger 
wire transfers and reducing wire fees.`}
+        withForever
+      />
+    </Fragment>
+  );
+}
diff --git 
a/packages/merchant-backoffice-ui/src/components/menu/LangSelector.tsx 
b/packages/merchant-backoffice-ui/src/components/menu/LangSelector.tsx
new file mode 100644
index 000000000..41d08a58b
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/menu/LangSelector.tsx
@@ -0,0 +1,73 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import langIcon from '../../assets/icons/languageicon.svg';
+import { useTranslationContext } from "../../context/translation";
+import { strings as messages } from '../../i18n/strings'
+
+type LangsNames = {
+  [P in keyof typeof messages]: string
+}
+
+const names: LangsNames = {
+  es: 'Español [es]',
+  en: 'English [en]',
+  fr: 'Français [fr]',
+  de: 'Deutsch [de]',
+  sv: 'Svenska [sv]',
+  it: 'Italiano [it]',
+}
+
+function getLangName(s: keyof LangsNames | string) {
+  if (names[s]) return names[s]
+  return s
+}
+
+export function LangSelector(): VNode {
+  const [updatingLang, setUpdatingLang] = useState(false)
+  const { lang, changeLanguage } = useTranslationContext()
+
+  return <div class="dropdown is-active ">
+    <div class="dropdown-trigger">
+      <button class="button has-tooltip-left" 
+        data-tooltip="change language selection"
+        aria-haspopup="true" 
+        aria-controls="dropdown-menu" onClick={() => 
setUpdatingLang(!updatingLang)}>
+        <div class="icon is-small is-left">
+          <img src={langIcon} />
+        </div>
+        <span>{getLangName(lang)}</span>
+        <div class="icon is-right">
+          <i class="mdi mdi-chevron-down" />
+        </div>
+      </button>
+    </div>
+    {updatingLang && <div class="dropdown-menu" id="dropdown-menu" role="menu">
+      <div class="dropdown-content">
+        {Object.keys(messages)
+          .filter((l) => l !== lang)
+          .map(l => <a key={l} class="dropdown-item" value={l} onClick={() => 
{ changeLanguage(l); setUpdatingLang(false) }}>{getLangName(l)}</a>)}
+      </div>
+    </div>}
+  </div>
+}
\ No newline at end of file
diff --git 
a/packages/merchant-backoffice-ui/src/components/menu/NavigationBar.tsx 
b/packages/merchant-backoffice-ui/src/components/menu/NavigationBar.tsx
new file mode 100644
index 000000000..e1bb4c7c0
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/menu/NavigationBar.tsx
@@ -0,0 +1,58 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode } from 'preact';
+import logo from '../../assets/logo.jpeg';
+import { LangSelector } from './LangSelector';
+
+interface Props {
+  onMobileMenu: () => void;
+  title: string;
+}
+
+export function NavigationBar({ onMobileMenu, title }: Props): VNode {
+  return (<nav class="navbar is-fixed-top" role="navigation" aria-label="main 
navigation">
+    <div class="navbar-brand">
+      <span class="navbar-item" style={{ fontSize: 24, fontWeight: 900 
}}>{title}</span>
+
+      <a role="button" class="navbar-burger" aria-label="menu" 
aria-expanded="false" onClick={(e) => {
+        onMobileMenu()
+        e.stopPropagation()
+      }}>
+        <span aria-hidden="true" />
+        <span aria-hidden="true" />
+        <span aria-hidden="true" />
+      </a>
+    </div>
+
+    <div class="navbar-menu ">
+      <a class="navbar-start is-justify-content-center is-flex-grow-1" 
href="https://taler.net";>
+        <img src={logo} style={{ height: 50, maxHeight: 50 }} />
+      </a>
+      <div class="navbar-end">
+        <div class="navbar-item" style={{ paddingTop: 4, paddingBottom: 4 }}>
+          <LangSelector />
+        </div>
+      </div>
+    </div>
+  </nav>
+  );
+}
\ No newline at end of file
diff --git a/packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx 
b/packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx
new file mode 100644
index 000000000..e9c5ef8ae
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/menu/SideBar.tsx
@@ -0,0 +1,227 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { Fragment, h, VNode } from "preact";
+import { useCallback } from "preact/hooks";
+import { useBackendContext } from "../../context/backend";
+import { useConfigContext } from "../../context/config";
+import { useInstanceContext } from "../../context/instance";
+import { useInstanceKYCDetails } from "../../hooks/instance";
+import { Translate } from "../../i18n";
+import { LangSelector } from "./LangSelector";
+
+interface Props {
+  onLogout: () => void;
+  mobile?: boolean;
+  instance: string;
+  admin?: boolean;
+  mimic?: boolean;
+}
+
+export function Sidebar({
+  mobile,
+  instance,
+  onLogout,
+  admin,
+  mimic,
+}: Props): VNode {
+  const config = useConfigContext();
+  const backend = useBackendContext();
+
+  const kycStatus = useInstanceKYCDetails();
+  const needKYC = kycStatus.ok && kycStatus.data.type === "redirect";
+  // const withInstanceIdIfNeeded = useCallback(function (path: string) {
+  //   if (mimic) {
+  //     return path + '?instance=' + instance
+  //   }
+  //   return path
+  // },[instance])
+
+  return (
+    <aside class="aside is-placed-left is-expanded">
+      {mobile && (
+        <div
+          class="footer"
+          onClick={(e) => {
+            return e.stopImmediatePropagation();
+          }}
+        >
+          <LangSelector />
+        </div>
+      )}
+      <div class="aside-tools">
+        <div class="aside-tools-label">
+          <div>
+            <b>Taler</b> Backoffice
+          </div>
+          <div
+            class="is-size-7 has-text-right"
+            style={{ lineHeight: 0, marginTop: -10 }}
+          >
+            {process.env.__VERSION__} ({config.version})
+          </div>
+        </div>
+      </div>
+      <div class="menu is-menu-main">
+        {instance ? (
+          <Fragment>
+            <p class="menu-label">
+              <Translate>Instance</Translate>
+            </p>
+            <ul class="menu-list">
+              <li>
+                <a href={"/update"} class="has-icon">
+                  <span class="icon">
+                    <i class="mdi mdi-square-edit-outline" />
+                  </span>
+                  <span class="menu-item-label">
+                    <Translate>Settings</Translate>
+                  </span>
+                </a>
+              </li>
+              <li>
+                <a href={"/orders"} class="has-icon">
+                  <span class="icon">
+                    <i class="mdi mdi-cash-register" />
+                  </span>
+                  <span class="menu-item-label">
+                    <Translate>Orders</Translate>
+                  </span>
+                </a>
+              </li>
+              <li>
+                <a href={"/products"} class="has-icon">
+                  <span class="icon">
+                    <i class="mdi mdi-shopping" />
+                  </span>
+                  <span class="menu-item-label">
+                    <Translate>Products</Translate>
+                  </span>
+                </a>
+              </li>
+              <li>
+                <a href={"/transfers"} class="has-icon">
+                  <span class="icon">
+                    <i class="mdi mdi-bank" />
+                  </span>
+                  <span class="menu-item-label">
+                    <Translate>Transfers</Translate>
+                  </span>
+                </a>
+              </li>
+              <li>
+                <a href={"/reserves"} class="has-icon">
+                  <span class="icon">
+                    <i class="mdi mdi-cash" />
+                  </span>
+                  <span class="menu-item-label">Reserves</span>
+                </a>
+              </li>
+              {needKYC && (
+                <li>
+                  <a href={"/kyc"} class="has-icon">
+                    <span class="icon">
+                      <i class="mdi mdi-account-check" />
+                    </span>
+                    <span class="menu-item-label">KYC Status</span>
+                  </a>
+                </li>
+              )}
+            </ul>
+          </Fragment>
+        ) : undefined}
+        <p class="menu-label">
+          <Translate>Connection</Translate>
+        </p>
+        <ul class="menu-list">
+          <li>
+            <div>
+              <span style={{ width: "3rem" }} class="icon">
+                <i class="mdi mdi-currency-eur" />
+              </span>
+              <span class="menu-item-label">{config.currency}</span>
+            </div>
+          </li>
+          <li>
+            <div>
+              <span style={{ width: "3rem" }} class="icon">
+                <i class="mdi mdi-web" />
+              </span>
+              <span class="menu-item-label">
+                {new URL(backend.url).hostname}
+              </span>
+            </div>
+          </li>
+          <li>
+            <div>
+              <span style={{ width: "3rem" }} class="icon">
+                ID
+              </span>
+              <span class="menu-item-label">
+                {!instance ? "default" : instance}
+              </span>
+            </div>
+          </li>
+          {admin && !mimic && (
+            <Fragment>
+              <p class="menu-label">
+                <Translate>Instances</Translate>
+              </p>
+              <li>
+                <a href={"/instance/new"} class="has-icon">
+                  <span class="icon">
+                    <i class="mdi mdi-plus" />
+                  </span>
+                  <span class="menu-item-label">
+                    <Translate>New</Translate>
+                  </span>
+                </a>
+              </li>
+              <li>
+                <a href={"/instances"} class="has-icon">
+                  <span class="icon">
+                    <i class="mdi mdi-format-list-bulleted" />
+                  </span>
+                  <span class="menu-item-label">
+                    <Translate>List</Translate>
+                  </span>
+                </a>
+              </li>
+            </Fragment>
+          )}
+          <li>
+            <a
+              class="has-icon is-state-info is-hoverable"
+              onClick={(): void => onLogout()}
+            >
+              <span class="icon">
+                <i class="mdi mdi-logout default" />
+              </span>
+              <span class="menu-item-label">
+                <Translate>Log out</Translate>
+              </span>
+            </a>
+          </li>
+        </ul>
+      </div>
+    </aside>
+  );
+}
diff --git a/packages/merchant-backoffice-ui/src/components/menu/index.tsx 
b/packages/merchant-backoffice-ui/src/components/menu/index.tsx
new file mode 100644
index 000000000..0a621af56
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/menu/index.tsx
@@ -0,0 +1,210 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+import { ComponentChildren, Fragment, h, VNode } from "preact";
+import Match from "preact-router/match";
+import { useEffect, useState } from "preact/hooks";
+import { AdminPaths } from "../../AdminRoutes";
+import { InstancePaths } from "../../InstanceRoutes";
+import { Notification } from "../../utils/types";
+import { NavigationBar } from "./NavigationBar";
+import { Sidebar } from "./SideBar";
+
+function getInstanceTitle(path: string, id: string): string {
+  switch (path) {
+    case InstancePaths.update:
+      return `${id}: Settings`;
+    case InstancePaths.order_list:
+      return `${id}: Orders`;
+    case InstancePaths.order_new:
+      return `${id}: New order`;
+    case InstancePaths.product_list:
+      return `${id}: Products`;
+    case InstancePaths.product_new:
+      return `${id}: New product`;
+    case InstancePaths.product_update:
+      return `${id}: Update product`;
+    case InstancePaths.reserves_new:
+      return `${id}: New reserve`;
+    case InstancePaths.reserves_list:
+      return `${id}: Reserves`;
+    case InstancePaths.transfers_list:
+      return `${id}: Transfers`;
+    case InstancePaths.transfers_new:
+      return `${id}: New transfer`;
+    default:
+      return "";
+  }
+}
+
+function getAdminTitle(path: string, instance: string) {
+  if (path === AdminPaths.new_instance) return `New instance`;
+  if (path === AdminPaths.list_instances) return `Instances`;
+  return getInstanceTitle(path, instance);
+}
+
+interface MenuProps {
+  title?: string;
+  instance: string;
+  admin?: boolean;
+  onLogout?: () => void;
+  setInstanceName: (s: string) => void;
+}
+
+function WithTitle({
+  title,
+  children,
+}: {
+  title: string;
+  children: ComponentChildren;
+}): VNode {
+  useEffect(() => {
+    document.title = `Taler Backoffice: ${title}`;
+  }, [title]);
+  return <Fragment>{children}</Fragment>;
+}
+
+export function Menu({
+  onLogout,
+  title,
+  instance,
+  admin,
+  setInstanceName,
+}: MenuProps): VNode {
+  const [mobileOpen, setMobileOpen] = useState(false);
+
+  return (
+    <Match>
+      {({ path }: any) => {
+        const titleWithSubtitle = title
+          ? title
+          : !admin
+          ? getInstanceTitle(path, instance)
+          : getAdminTitle(path, instance);
+        const adminInstance = instance === "default";
+        const mimic = admin && !adminInstance;
+        return (
+          <WithTitle title={titleWithSubtitle}>
+            <div
+              class={mobileOpen ? "has-aside-mobile-expanded" : ""}
+              onClick={() => setMobileOpen(false)}
+            >
+              <NavigationBar
+                onMobileMenu={() => setMobileOpen(!mobileOpen)}
+                title={titleWithSubtitle}
+              />
+
+              {onLogout && (
+                <Sidebar
+                  onLogout={onLogout}
+                  admin={admin}
+                  mimic={mimic}
+                  instance={instance}
+                  mobile={mobileOpen}
+                />
+              )}
+
+              {mimic && (
+                <nav class="level">
+                  <div class="level-item has-text-centered 
has-background-warning">
+                    <p class="is-size-5">
+                      You are viewing the instance <b>"{instance}"</b>.{" "}
+                      <a
+                        href="#/instances"
+                        onClick={(e) => {
+                          setInstanceName("default");
+                        }}
+                      >
+                        go back
+                      </a>
+                    </p>
+                  </div>
+                </nav>
+              )}
+            </div>
+          </WithTitle>
+        );
+      }}
+    </Match>
+  );
+}
+
+interface NotYetReadyAppMenuProps {
+  title: string;
+  onLogout?: () => void;
+}
+
+interface NotifProps {
+  notification?: Notification;
+}
+export function NotificationCard({
+  notification: n,
+}: NotifProps): VNode | null {
+  if (!n) return null;
+  return (
+    <div class="notification">
+      <div class="columns is-vcentered">
+        <div class="column is-12">
+          <article
+            class={
+              n.type === "ERROR"
+                ? "message is-danger"
+                : n.type === "WARN"
+                ? "message is-warning"
+                : "message is-info"
+            }
+          >
+            <div class="message-header">
+              <p>{n.message}</p>
+            </div>
+            {n.description && (
+              <div class="message-body">
+                <div>{n.description}</div>
+                {n.details && <pre>{n.details}</pre>}
+              </div>
+            )}
+          </article>
+        </div>
+      </div>
+    </div>
+  );
+}
+
+export function NotYetReadyAppMenu({
+  onLogout,
+  title,
+}: NotYetReadyAppMenuProps): VNode {
+  const [mobileOpen, setMobileOpen] = useState(false);
+
+  useEffect(() => {
+    document.title = `Taler Backoffice: ${title}`;
+  }, [title]);
+
+  return (
+    <div
+      class={mobileOpen ? "has-aside-mobile-expanded" : ""}
+      onClick={() => setMobileOpen(false)}
+    >
+      <NavigationBar
+        onMobileMenu={() => setMobileOpen(!mobileOpen)}
+        title={title}
+      />
+      {onLogout && (
+        <Sidebar onLogout={onLogout} instance="" mobile={mobileOpen} />
+      )}
+    </div>
+  );
+}
diff --git a/packages/merchant-backoffice-ui/src/components/modal/index.tsx 
b/packages/merchant-backoffice-ui/src/components/modal/index.tsx
new file mode 100644
index 000000000..a7edb9e48
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/modal/index.tsx
@@ -0,0 +1,262 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+
+import { ComponentChildren, h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { useInstanceContext } from "../../context/instance";
+import { Translate, useTranslator } from "../../i18n";
+import { DEFAULT_REQUEST_TIMEOUT } from "../../utils/constants";
+import { Loading, Spinner } from "../exception/loading";
+import { FormProvider } from "../form/FormProvider";
+import { Input } from "../form/Input";
+
+interface Props {
+  active?: boolean;
+  description?: string;
+  onCancel?: () => void;
+  onConfirm?: () => void;
+  label?: string;
+  children?: ComponentChildren;
+  danger?: boolean;
+  disabled?: boolean;
+}
+
+export function ConfirmModal({ active, description, onCancel, onConfirm, 
children, danger, disabled, label = 'Confirm' }: Props): VNode {
+  return <div class={active ? "modal is-active" : "modal"}>
+    <div class="modal-background " onClick={onCancel} />
+    <div class="modal-card" style={{maxWidth: 700}}>
+      <header class="modal-card-head">
+        {!description ? null : <p 
class="modal-card-title"><b>{description}</b></p>}
+        <button class="delete " aria-label="close" onClick={onCancel} />
+      </header>
+      <section class="modal-card-body">
+        {children}
+      </section>
+      <footer class="modal-card-foot">
+        <div class="buttons is-right" style={{ width: '100%' }}>
+          <button class="button " onClick={onCancel} 
><Translate>Cancel</Translate></button>
+          <button class={danger ? "button is-danger " : "button is-info "} 
disabled={disabled} onClick={onConfirm} ><Translate>{label}</Translate></button>
+        </div>
+      </footer>
+    </div>
+    <button class="modal-close is-large " aria-label="close" 
onClick={onCancel} />
+  </div>
+}
+
+export function ContinueModal({ active, description, onCancel, onConfirm, 
children, disabled }: Props): VNode {
+  return <div class={active ? "modal is-active" : "modal"}>
+    <div class="modal-background " onClick={onCancel} />
+    <div class="modal-card">
+      <header class="modal-card-head has-background-success">
+        {!description ? null : <p class="modal-card-title">{description}</p>}
+        <button class="delete " aria-label="close" onClick={onCancel} />
+      </header>
+      <section class="modal-card-body">
+        {children}
+      </section>
+      <footer class="modal-card-foot">
+        <div class="buttons is-right" style={{ width: '100%' }}>
+          <button class="button is-success " disabled={disabled} 
onClick={onConfirm} ><Translate>Continue</Translate></button>
+        </div>
+      </footer>
+    </div>
+    <button class="modal-close is-large " aria-label="close" 
onClick={onCancel} />
+  </div>
+}
+
+export function SimpleModal({ onCancel, children }: any): VNode {
+  return <div class="modal is-active">
+    <div class="modal-background " onClick={onCancel} />
+    <div class="modal-card">
+      <section class="modal-card-body is-main-section">
+        {children}
+      </section>
+    </div>
+    <button class="modal-close is-large " aria-label="close" 
onClick={onCancel} />
+  </div>
+}
+
+export function ClearConfirmModal({ description, onCancel, onClear, onConfirm, 
children }: Props & { onClear?: () => void }): VNode {
+  return <div class="modal is-active">
+    <div class="modal-background " onClick={onCancel} />
+    <div class="modal-card">
+      <header class="modal-card-head">
+        {!description ? null : <p class="modal-card-title">{description}</p>}
+        <button class="delete " aria-label="close" onClick={onCancel} />
+      </header>
+      <section class="modal-card-body is-main-section">
+        {children}
+      </section>
+      <footer class="modal-card-foot">
+        {onClear && <button class="button is-danger" onClick={onClear} 
disabled={onClear === undefined} ><Translate>Clear</Translate></button>}
+        <div class="buttons is-right" style={{ width: '100%' }}>
+          <button class="button " onClick={onCancel} 
><Translate>Cancel</Translate></button>
+          <button class="button is-info" onClick={onConfirm} 
disabled={onConfirm === undefined} ><Translate>Confirm</Translate></button>
+        </div>
+      </footer>
+    </div>
+    <button class="modal-close is-large " aria-label="close" 
onClick={onCancel} />
+  </div>
+}
+
+interface DeleteModalProps {
+  element: { id: string, name: string };
+  onCancel: () => void;
+  onConfirm: (id: string) => void;
+}
+
+export function DeleteModal({ element, onCancel, onConfirm }: 
DeleteModalProps): VNode {
+  return <ConfirmModal label={`Delete instance`} description={`Delete the 
instance "${element.name}"`} danger active onCancel={onCancel} onConfirm={() => 
onConfirm(element.id)}>
+    <p>If you delete the instance named <b>"{element.name}"</b> (ID: 
<b>{element.id}</b>), the merchant will no longer be able to process orders or 
refunds</p>
+    <p>This action deletes the instance private key, but preserves all 
transaction data. You can still access that data after deleting the 
instance.</p>
+    <p class="warning">Deleting an instance <b>cannot be undone</b>.</p>
+  </ConfirmModal>
+}
+
+export function PurgeModal({ element, onCancel, onConfirm }: 
DeleteModalProps): VNode {
+  return <ConfirmModal label={`Purge the instance`} description={`Purge the 
instance "${element.name}"`} danger active onCancel={onCancel} onConfirm={() => 
onConfirm(element.id)}>
+    <p>If you purge the instance named <b>"{element.name}"</b> (ID: 
<b>{element.id}</b>), you will also delete all it's transaction data.</p>
+    <p>The instance will disappear from your list, and you will no longer be 
able to access it's data.</p>
+    <p class="warning">Purging an instance <b>cannot be undone</b>.</p>
+  </ConfirmModal>
+}
+
+interface UpdateTokenModalProps {
+  oldToken?: string;
+  onCancel: () => void;
+  onConfirm: (value: string) => void;
+  onClear: () => void;
+}
+
+//FIXME: merge UpdateTokenModal with SetTokenNewInstanceModal
+export function UpdateTokenModal({ onCancel, onClear, onConfirm, oldToken }: 
UpdateTokenModalProps): VNode {
+  type State = { old_token: string, new_token: string, repeat_token: string }
+  const [form, setValue] = useState<Partial<State>>({
+    old_token: '', new_token: '', repeat_token: '',
+  })
+  const i18n = useTranslator()
+
+  const hasInputTheCorrectOldToken = oldToken && oldToken !== form.old_token
+  const errors = {
+    old_token: hasInputTheCorrectOldToken ? i18n`is not the same as the 
current access token` : undefined,
+    new_token: !form.new_token ? i18n`cannot be empty` : (form.new_token === 
form.old_token ? i18n`cannot be the same as the old token` : undefined),
+    repeat_token: form.new_token !== form.repeat_token ? i18n`is not the same` 
: undefined
+  }
+
+  const hasErrors = Object.keys(errors).some(k => (errors as any)[k] !== 
undefined)
+
+  const instance = useInstanceContext()
+
+  const text = i18n`You are updating the access token from instance with id 
${instance.id}`
+
+  return <ClearConfirmModal description={text}
+    onCancel={onCancel}
+    onConfirm={!hasErrors ? () => onConfirm(form.new_token!) : undefined}
+    onClear={!hasInputTheCorrectOldToken && oldToken ? onClear : undefined}
+  >
+    <div class="columns">
+      <div class="column" />
+      <div class="column is-four-fifths" >
+        <FormProvider errors={errors} object={form} valueHandler={setValue}>
+          {oldToken && <Input<State> name="old_token" label={i18n`Old access 
token`} tooltip={i18n`access token currently in use`} inputType="password" />}
+          <Input<State> name="new_token" label={i18n`New access token`} 
tooltip={i18n`next access token to be used`} inputType="password" />
+          <Input<State> name="repeat_token" label={i18n`Repeat access token`} 
tooltip={i18n`confirm the same access token`} inputType="password" />
+        </FormProvider>
+        <p><Translate>Clearing the access token will mean public access to the 
instance</Translate></p>
+      </div>
+      <div class="column" />
+    </div>
+  </ClearConfirmModal>
+}
+
+export function SetTokenNewInstanceModal({ onCancel, onClear, onConfirm }: 
UpdateTokenModalProps): VNode {
+  type State = { old_token: string, new_token: string, repeat_token: string }
+  const [form, setValue] = useState<Partial<State>>({
+    new_token: '', repeat_token: '',
+  })
+  const i18n = useTranslator()
+
+  const errors = {
+    new_token: !form.new_token ? i18n`cannot be empty` : (form.new_token === 
form.old_token ? i18n`cannot be the same as the old access token` : undefined),
+    repeat_token: form.new_token !== form.repeat_token ? i18n`is not the same` 
: undefined
+  }
+
+  const hasErrors = Object.keys(errors).some(k => (errors as any)[k] !== 
undefined)
+
+
+  return <div class="modal is-active">
+    <div class="modal-background " onClick={onCancel} />
+    <div class="modal-card">
+      <header class="modal-card-head">
+        <p class="modal-card-title">{i18n`You are setting the access token for 
the new instance`}</p>
+        <button class="delete " aria-label="close" onClick={onCancel} />
+      </header>
+      <section class="modal-card-body is-main-section">
+        <div class="columns">
+          <div class="column" />
+          <div class="column is-four-fifths" >
+            <FormProvider errors={errors} object={form} 
valueHandler={setValue}>
+              <Input<State> name="new_token" label={i18n`New access token`} 
tooltip={i18n`next access token to be used`} inputType="password" />
+              <Input<State> name="repeat_token" label={i18n`Repeat access 
token`} tooltip={i18n`confirm the same access token`} inputType="password" />
+            </FormProvider>
+            <p><Translate>With external authorization method no check will be 
done by the merchant backend</Translate></p>
+          </div>
+          <div class="column" />
+        </div>
+      </section>
+      <footer class="modal-card-foot">
+        {onClear && <button class="button is-danger" onClick={onClear} 
disabled={onClear === undefined} ><Translate>Set external 
authorization</Translate></button>}
+        <div class="buttons is-right" style={{ width: '100%' }}>
+          <button class="button " onClick={onCancel} 
><Translate>Cancel</Translate></button>
+          <button class="button is-info" onClick={() => 
onConfirm(form.new_token!)} disabled={hasErrors} ><Translate>Set access 
token</Translate></button>
+        </div>
+      </footer>
+    </div>
+    <button class="modal-close is-large " aria-label="close" 
onClick={onCancel} />
+  </div>
+}
+
+export function LoadingModal({ onCancel }: { onCancel: () => void }): VNode {
+  const i18n = useTranslator()
+  return <div class="modal is-active">
+    <div class="modal-background " onClick={onCancel} />
+    <div class="modal-card">
+      <header class="modal-card-head">
+        <p class="modal-card-title"><Translate>Operation in 
progress...</Translate></p>
+      </header>
+      <section class="modal-card-body">
+        <div class="columns">
+          <div class="column" />
+          <Spinner />
+          <div class="column" />
+        </div>
+        <p>{i18n`The operation will be automatically canceled after 
${DEFAULT_REQUEST_TIMEOUT} seconds`}</p>
+      </section>
+      <footer class="modal-card-foot">
+        <div class="buttons is-right" style={{ width: '100%' }}>
+          <button class="button " onClick={onCancel} 
><Translate>Cancel</Translate></button>
+        </div>
+      </footer>
+    </div>
+    <button class="modal-close is-large " aria-label="close" 
onClick={onCancel} />
+  </div>
+}
diff --git 
a/packages/merchant-backoffice-ui/src/components/notifications/CreatedSuccessfully.tsx
 
b/packages/merchant-backoffice-ui/src/components/notifications/CreatedSuccessfully.tsx
new file mode 100644
index 000000000..e0b355c2e
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/components/notifications/CreatedSuccessfully.tsx
@@ -0,0 +1,49 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import { ComponentChildren, h, VNode } from "preact";
+
+interface Props {
+  onCreateAnother?: () => void;
+  onConfirm: () => void;
+  children: ComponentChildren;
+}
+
+export function CreatedSuccessfully({ children, onConfirm, onCreateAnother }: 
Props): VNode {
+  return <div class="columns is-fullwidth is-vcentered mt-3">
+    <div class="column" />
+    <div class="column is-four-fifths">
+      <div class="card">
+        <header class="card-header has-background-success">
+          <p class="card-header-title has-text-white-ter">
+            Success.
+          </p>
+        </header>
+        <div class="card-content">
+          {children}
+        </div>
+      </div>
+        <div class="buttons is-right">
+          {onCreateAnother && <button class="button is-info" 
onClick={onCreateAnother}>Create another</button>}
+          <button class="button is-info" onClick={onConfirm}>Continue</button>
+        </div>
+    </div>
+    <div class="column" />
+  </div>
+}
diff --git 
a/packages/merchant-backoffice-ui/src/components/notifications/Notifications.stories.tsx
 
b/packages/merchant-backoffice-ui/src/components/notifications/Notifications.stories.tsx
new file mode 100644
index 000000000..3b95295fe
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/components/notifications/Notifications.stories.tsx
@@ -0,0 +1,57 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h } from 'preact';
+import { Notifications } from './index';
+
+
+export default {
+  title: 'Components/Notification',
+  component: Notifications,
+  argTypes: {
+    removeNotification: { action: 'removeNotification' },
+  },
+};
+
+export const Info = (a: any) => <Notifications {...a} />;
+Info.args = {
+  notifications: [{
+    message: 'Title',
+    description: 'Some large description',
+    type: 'INFO',
+  }]
+}
+export const Warn = (a: any) => <Notifications {...a} />;
+Warn.args = {
+  notifications: [{
+    message: 'Title',
+    description: 'Some large description',
+    type: 'WARN',
+  }]
+}
+export const Error = (a: any) => <Notifications {...a} />;
+Error.args = {
+  notifications: [{
+    message: 'Title',
+    description: 'Some large description',
+    type: 'ERROR',
+  }]
+}
diff --git 
a/packages/merchant-backoffice-ui/src/components/notifications/index.tsx 
b/packages/merchant-backoffice-ui/src/components/notifications/index.tsx
new file mode 100644
index 000000000..34bd40ec6
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/notifications/index.tsx
@@ -0,0 +1,52 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode } from "preact";
+import { MessageType, Notification } from "../../utils/types";
+
+interface Props {
+  notifications: Notification[];
+  removeNotification?: (n: Notification) => void;
+}
+
+function messageStyle(type: MessageType): string {
+  switch (type) {
+    case "INFO": return "message is-info";
+    case "WARN": return "message is-warning";
+    case "ERROR": return "message is-danger";
+    case "SUCCESS": return "message is-success";
+    default: return "message"
+  }
+}
+
+export function Notifications({ notifications, removeNotification }: Props): 
VNode {
+  return <div class="toast">
+    {notifications.map((n,i) => <article key={i} class={messageStyle(n.type)}>
+      <div class="message-header">
+        <p>{n.message}</p>
+        <button class="delete" onClick={() => removeNotification && 
removeNotification(n)} />
+      </div>
+      {n.description && <div class="message-body">
+        {n.description}
+      </div>}
+    </article>)}
+  </div>
+}
\ No newline at end of file
diff --git 
a/packages/merchant-backoffice-ui/src/components/picker/DatePicker.tsx 
b/packages/merchant-backoffice-ui/src/components/picker/DatePicker.tsx
new file mode 100644
index 000000000..084b7b00a
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/picker/DatePicker.tsx
@@ -0,0 +1,324 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, Component } from "preact";
+
+interface Props {
+  closeFunction?: () => void;
+  dateReceiver?: (d: Date) => void;
+  opened?: boolean;
+}
+interface State {
+  displayedMonth: number;
+  displayedYear: number;
+  selectYearMode: boolean;
+  currentDate: Date;
+}
+
+// inspired by https://codepen.io/m4r1vs/pen/MOOxyE
+export class DatePicker extends Component<Props, State> {
+
+  closeDatePicker() {
+    this.props.closeFunction && this.props.closeFunction(); // Function gets 
passed by parent
+  }
+
+  /**
+  * Gets fired when a day gets clicked.
+  * @param {object} e The event thrown by the <span /> element clicked
+  */
+  dayClicked(e: any) {
+
+    const element = e.target; // the actual element clicked
+
+    if (element.innerHTML === '') return false; // don't continue if <span /> 
empty
+
+    // get date from clicked element (gets attached when rendered)
+    const date = new Date(element.getAttribute('data-value'));
+
+    // update the state
+    this.setState({ currentDate: date });
+    this.passDateToParent(date)
+  }
+
+  /**
+  * returns days in month as array
+  * @param {number} month the month to display
+  * @param {number} year the year to display
+  */
+  getDaysByMonth(month: number, year: number) {
+
+    const calendar = [];
+
+    const date = new Date(year, month, 1); // month to display
+
+    const firstDay = new Date(year, month, 1).getDay(); // first weekday of 
month
+    const lastDate = new Date(year, month + 1, 0).getDate(); // last date of 
month
+
+    let day: number | null = 0;
+
+    // the calendar is 7*6 fields big, so 42 loops
+    for (let i = 0; i < 42; i++) {
+
+      if (i >= firstDay && day !== null) day = day + 1;
+      if (day !== null && day > lastDate) day = null;
+
+      // append the calendar Array
+      calendar.push({
+        day: (day === 0 || day === null) ? null : day, // null or number
+        date: (day === 0 || day === null) ? null : new Date(year, month, day), 
// null or Date()
+        today: (day === now.getDate() && month === now.getMonth() && year === 
now.getFullYear()) // boolean
+      });
+    }
+
+    return calendar;
+  }
+
+  /**
+  * Display previous month by updating state
+  */
+  displayPrevMonth() {
+    if (this.state.displayedMonth <= 0) {
+      this.setState({
+        displayedMonth: 11,
+        displayedYear: this.state.displayedYear - 1
+      });
+    }
+    else {
+      this.setState({
+        displayedMonth: this.state.displayedMonth - 1
+      });
+    }
+  }
+
+  /**
+  * Display next month by updating state
+  */
+  displayNextMonth() {
+    if (this.state.displayedMonth >= 11) {
+      this.setState({
+        displayedMonth: 0,
+        displayedYear: this.state.displayedYear + 1
+      });
+    }
+    else {
+      this.setState({
+        displayedMonth: this.state.displayedMonth + 1
+      });
+    }
+  }
+
+  /**
+  * Display the selected month (gets fired when clicking on the date string)
+  */
+  displaySelectedMonth() {
+    if (this.state.selectYearMode) {
+      this.toggleYearSelector();
+    }
+    else {
+      if (!this.state.currentDate) return false;
+      this.setState({
+        displayedMonth: this.state.currentDate.getMonth(),
+        displayedYear: this.state.currentDate.getFullYear()
+      });
+    }
+  }
+
+  toggleYearSelector() {
+    this.setState({ selectYearMode: !this.state.selectYearMode });
+  }
+
+  changeDisplayedYear(e: any) {
+    const element = e.target;
+    this.toggleYearSelector();
+    this.setState({ displayedYear: parseInt(element.innerHTML, 10), 
displayedMonth: 0 });
+  }
+
+  /**
+  * Pass the selected date to parent when 'OK' is clicked
+  */
+  passSavedDateDateToParent() {
+    this.passDateToParent(this.state.currentDate)
+  }
+  passDateToParent(date: Date) {
+    if (typeof this.props.dateReceiver === 'function') 
this.props.dateReceiver(date);
+    this.closeDatePicker();
+  }
+
+  componentDidUpdate() {
+    if (this.state.selectYearMode) {
+      document.getElementsByClassName('selected')[0].scrollIntoView(); // 
works in every browser incl. IE, replace with scrollIntoViewIfNeeded when 
browsers support it
+    }
+  }
+
+  constructor() {
+    super();
+
+    this.closeDatePicker = this.closeDatePicker.bind(this);
+    this.dayClicked = this.dayClicked.bind(this);
+    this.displayNextMonth = this.displayNextMonth.bind(this);
+    this.displayPrevMonth = this.displayPrevMonth.bind(this);
+    this.getDaysByMonth = this.getDaysByMonth.bind(this);
+    this.changeDisplayedYear = this.changeDisplayedYear.bind(this);
+    this.passDateToParent = this.passDateToParent.bind(this);
+    this.toggleYearSelector = this.toggleYearSelector.bind(this);
+    this.displaySelectedMonth = this.displaySelectedMonth.bind(this);
+
+
+    this.state = {
+      currentDate: now,
+      displayedMonth: now.getMonth(),
+      displayedYear: now.getFullYear(),
+      selectYearMode: false
+    }
+  }
+
+  render() {
+
+    const { currentDate, displayedMonth, displayedYear, selectYearMode } = 
this.state;
+
+    return (
+      <div>
+        <div class={`datePicker ${  this.props.opened && 
"datePicker--opened"}`} >
+
+          <div class="datePicker--titles">
+            <h3 style={{
+              color: selectYearMode ? 'rgba(255,255,255,.87)' : 
'rgba(255,255,255,.57)'
+            }} 
onClick={this.toggleYearSelector}>{currentDate.getFullYear()}</h3>
+            <h2 style={{
+              color: !selectYearMode ? 'rgba(255,255,255,.87)' : 
'rgba(255,255,255,.57)'
+            }} onClick={this.displaySelectedMonth}>
+              {dayArr[currentDate.getDay()]}, 
{monthArrShort[currentDate.getMonth()]} {currentDate.getDate()}
+            </h2>
+          </div>
+
+          {!selectYearMode && <nav>
+            <span onClick={this.displayPrevMonth} class="icon"><i style={{ 
transform: 'rotate(180deg)' }} class="mdi mdi-forward" /></span>
+            <h4>{monthArrShortFull[displayedMonth]} {displayedYear}</h4>
+            <span onClick={this.displayNextMonth} class="icon"><i class="mdi 
mdi-forward" /></span>
+          </nav>}
+
+          <div class="datePicker--scroll">
+
+            {!selectYearMode && <div class="datePicker--calendar" >
+
+              <div class="datePicker--dayNames">
+                {['S', 'M', 'T', 'W', 'T', 'F', 'S'].map((day,i) => <span 
key={i}>{day}</span>)}
+              </div>
+
+              <div onClick={this.dayClicked} class="datePicker--days">
+
+                {/*
+                  Loop through the calendar object returned by 
getDaysByMonth().
+                */}
+
+                {this.getDaysByMonth(this.state.displayedMonth, 
this.state.displayedYear)
+                  .map(
+                    day => {
+                      let selected = false;
+
+                      if (currentDate && day.date) selected = 
(currentDate.toLocaleDateString() === day.date.toLocaleDateString());
+
+                      return (<span key={day.day}
+                        class={(day.today ? 'datePicker--today ' : '') + 
(selected ? 'datePicker--selected' : '')}
+                        disabled={!day.date}
+                        data-value={day.date}
+                      >
+                        {day.day}
+                      </span>)
+                    }
+                  )
+                }
+
+              </div>
+
+            </div>}
+
+            {selectYearMode && <div class="datePicker--selectYear">
+
+              {yearArr.map(year => (
+                <span key={year} class={(year === displayedYear) ? 'selected' 
: ''} onClick={this.changeDisplayedYear}>
+                  {year}
+                </span>
+              ))}
+
+            </div>}
+
+          </div>
+        </div>
+
+        <div class="datePicker--background" onClick={this.closeDatePicker} 
style={{
+          display: this.props.opened ? 'block' : 'none'
+        }}
+        />
+
+      </div>
+    )
+  }
+}
+
+
+const monthArrShortFull = [
+  'January',
+  'February',
+  'March',
+  'April',
+  'May',
+  'June',
+  'July',
+  'August',
+  'September',
+  'October',
+  'November',
+  'December'
+]
+
+const monthArrShort = [
+  'Jan',
+  'Feb',
+  'Mar',
+  'Apr',
+  'May',
+  'Jun',
+  'Jul',
+  'Aug',
+  'Sep',
+  'Oct',
+  'Nov',
+  'Dec'
+]
+
+const dayArr = [
+  'Sun',
+  'Mon',
+  'Tue',
+  'Wed',
+  'Thu',
+  'Fri',
+  'Sat'
+]
+
+const now = new Date()
+
+const yearArr: number[] = []
+
+for (let i = 2010; i <= now.getFullYear() + 10; i++) {
+  yearArr.push(i);
+}
diff --git 
a/packages/merchant-backoffice-ui/src/components/picker/DurationPicker.stories.tsx
 
b/packages/merchant-backoffice-ui/src/components/picker/DurationPicker.stories.tsx
new file mode 100644
index 000000000..275c80fa6
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/components/picker/DurationPicker.stories.tsx
@@ -0,0 +1,50 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, FunctionalComponent } from 'preact';
+import { useState } from 'preact/hooks';
+import { DurationPicker as TestedComponent } from './DurationPicker';
+
+
+export default {
+  title: 'Components/Picker/Duration',
+  component: TestedComponent,
+  argTypes: {
+    onCreate: { action: 'onCreate' },
+    goBack: { action: 'goBack' },
+  }
+};
+
+function createExample<Props>(Component: FunctionalComponent<Props>, props: 
Partial<Props>) {
+  const r = (args: any) => <Component {...args} />
+  r.args = props
+  return r
+}
+
+export const Example = createExample(TestedComponent, {
+  days: true, minutes: true, hours: true, seconds: true,
+  value: 10000000
+});
+
+export const WithState = () => {
+  const [v,s] = useState<number>(1000000)
+  return <TestedComponent value={v} onChange={s} days minutes hours seconds />
+}
diff --git 
a/packages/merchant-backoffice-ui/src/components/picker/DurationPicker.tsx 
b/packages/merchant-backoffice-ui/src/components/picker/DurationPicker.tsx
new file mode 100644
index 000000000..f32a48fd4
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/picker/DurationPicker.tsx
@@ -0,0 +1,211 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { useTranslator } from "../../i18n";
+import "../../scss/DurationPicker.scss";
+
+export interface Props {
+  hours?: boolean;
+  minutes?: boolean;
+  seconds?: boolean;
+  days?: boolean;
+  onChange: (value: number) => void;
+  value: number;
+}
+
+// inspiration taken from https://github.com/flurmbo/react-duration-picker
+export function DurationPicker({
+  days,
+  hours,
+  minutes,
+  seconds,
+  onChange,
+  value,
+}: Props): VNode {
+  const ss = 1000 * 1000;
+  const ms = ss * 60;
+  const hs = ms * 60;
+  const ds = hs * 24;
+  const i18n = useTranslator();
+
+  return (
+    <div class="rdp-picker">
+      {days && (
+        <DurationColumn
+          unit={i18n`days`}
+          max={99}
+          value={Math.floor(value / ds)}
+          onDecrease={value >= ds ? () => onChange(value - ds) : undefined}
+          onIncrease={value < 99 * ds ? () => onChange(value + ds) : undefined}
+          onChange={(diff) => onChange(value + diff * ds)}
+        />
+      )}
+      {hours && (
+        <DurationColumn
+          unit={i18n`hours`}
+          max={23}
+          min={1}
+          value={Math.floor(value / hs) % 24}
+          onDecrease={value >= hs ? () => onChange(value - hs) : undefined}
+          onIncrease={value < 99 * ds ? () => onChange(value + hs) : undefined}
+          onChange={(diff) => onChange(value + diff * hs)}
+        />
+      )}
+      {minutes && (
+        <DurationColumn
+          unit={i18n`minutes`}
+          max={59}
+          min={1}
+          value={Math.floor(value / ms) % 60}
+          onDecrease={value >= ms ? () => onChange(value - ms) : undefined}
+          onIncrease={value < 99 * ds ? () => onChange(value + ms) : undefined}
+          onChange={(diff) => onChange(value + diff * ms)}
+        />
+      )}
+      {seconds && (
+        <DurationColumn
+          unit={i18n`seconds`}
+          max={59}
+          value={Math.floor(value / ss) % 60}
+          onDecrease={value >= ss ? () => onChange(value - ss) : undefined}
+          onIncrease={value < 99 * ds ? () => onChange(value + ss) : undefined}
+          onChange={(diff) => onChange(value + diff * ss)}
+        />
+      )}
+    </div>
+  );
+}
+
+interface ColProps {
+  unit: string;
+  min?: number;
+  max: number;
+  value: number;
+  onIncrease?: () => void;
+  onDecrease?: () => void;
+  onChange?: (diff: number) => void;
+}
+
+function InputNumber({
+  initial,
+  onChange,
+}: {
+  initial: number;
+  onChange: (n: number) => void;
+}) {
+  const [value, handler] = useState<{ v: string }>({
+    v: toTwoDigitString(initial),
+  });
+
+  return (
+    <input
+      value={value.v}
+      onBlur={(e) => onChange(parseInt(value.v, 10))}
+      onInput={(e) => {
+        e.preventDefault();
+        const n = Number.parseInt(e.currentTarget.value, 10);
+        if (isNaN(n)) return handler({ v: toTwoDigitString(initial) });
+        return handler({ v: toTwoDigitString(n) });
+      }}
+      style={{
+        width: 50,
+        border: "none",
+        fontSize: "inherit",
+        background: "inherit",
+      }}
+    />
+  );
+}
+
+function DurationColumn({
+  unit,
+  min = 0,
+  max,
+  value,
+  onIncrease,
+  onDecrease,
+  onChange,
+}: ColProps): VNode {
+  const cellHeight = 35;
+  return (
+    <div class="rdp-column-container">
+      <div class="rdp-masked-div">
+        <hr class="rdp-reticule" style={{ top: cellHeight * 2 - 1 }} />
+        <hr class="rdp-reticule" style={{ top: cellHeight * 3 - 1 }} />
+
+        <div class="rdp-column" style={{ top: 0 }}>
+          <div class="rdp-cell" key={value - 2}>
+            {onDecrease && (
+              <button
+                style={{ width: "100%", textAlign: "center", margin: 5 }}
+                onClick={onDecrease}
+              >
+                <span class="icon">
+                  <i class="mdi mdi-chevron-up" />
+                </span>
+              </button>
+            )}
+          </div>
+          <div class="rdp-cell" key={value - 1}>
+            {value > min ? toTwoDigitString(value - 1) : ""}
+          </div>
+          <div class="rdp-cell rdp-center" key={value}>
+            {onChange ? (
+              <InputNumber
+                initial={value}
+                onChange={(n) => onChange(n - value)}
+              />
+            ) : (
+              toTwoDigitString(value)
+            )}
+            <div>{unit}</div>
+          </div>
+
+          <div class="rdp-cell" key={value + 1}>
+            {value < max ? toTwoDigitString(value + 1) : ""}
+          </div>
+
+          <div class="rdp-cell" key={value + 2}>
+            {onIncrease && (
+              <button
+                style={{ width: "100%", textAlign: "center", margin: 5 }}
+                onClick={onIncrease}
+              >
+                <span class="icon">
+                  <i class="mdi mdi-chevron-down" />
+                </span>
+              </button>
+            )}
+          </div>
+        </div>
+      </div>
+    </div>
+  );
+}
+
+function toTwoDigitString(n: number) {
+  if (n < 10) {
+    return `0${n}`;
+  }
+  return `${n}`;
+}
diff --git 
a/packages/merchant-backoffice-ui/src/components/product/InventoryProductForm.stories.tsx
 
b/packages/merchant-backoffice-ui/src/components/product/InventoryProductForm.stories.tsx
new file mode 100644
index 000000000..6504d85ba
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/components/product/InventoryProductForm.stories.tsx
@@ -0,0 +1,58 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode, FunctionalComponent } from 'preact';
+import { InventoryProductForm as TestedComponent } from 
'./InventoryProductForm';
+
+
+export default {
+  title: 'Components/Product/Add',
+  component: TestedComponent,
+  argTypes: {
+    onAddProduct: { action: 'onAddProduct' },
+  },
+};
+
+function createExample<Props>(Component: FunctionalComponent<Props>, props: 
Partial<Props>) {
+  const r = (args: any) => <Component {...args} />
+  r.args = props
+  return r
+}
+
+export const WithASimpleList = createExample(TestedComponent, {
+  inventory:[{
+    id: 'this id',
+    description: 'this is the description',
+  } as any]
+});
+
+export const WithAProductSelected = createExample(TestedComponent, {
+  inventory:[],
+  currentProducts: {
+    thisid: {
+      quantity: 1,
+      product: {
+        id: 'asd',
+        description: 'asdsadsad',
+      } as any
+    }
+  }
+});
diff --git 
a/packages/merchant-backoffice-ui/src/components/product/InventoryProductForm.tsx
 
b/packages/merchant-backoffice-ui/src/components/product/InventoryProductForm.tsx
new file mode 100644
index 000000000..8f05c9736
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/components/product/InventoryProductForm.tsx
@@ -0,0 +1,95 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+import { h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { FormProvider, FormErrors } from "../form/FormProvider";
+import { InputNumber } from "../form/InputNumber";
+import { InputSearchProduct } from "../form/InputSearchProduct";
+import { MerchantBackend, WithId } from "../../declaration";
+import { Translate, useTranslator } from "../../i18n";
+import { ProductMap } from "../../paths/instance/orders/create/CreatePage";
+
+type Form = {
+  product: MerchantBackend.Products.ProductDetail & WithId,
+  quantity: number;
+}
+
+interface Props {
+  currentProducts: ProductMap,
+  onAddProduct: (product: MerchantBackend.Products.ProductDetail & WithId, 
quantity: number) => void,
+  inventory: (MerchantBackend.Products.ProductDetail & WithId)[],
+}
+
+export function InventoryProductForm({ currentProducts, onAddProduct, 
inventory }: Props): VNode {
+  const initialState = { quantity: 1 }
+  const [state, setState] = useState<Partial<Form>>(initialState)
+  const [errors, setErrors] = useState<FormErrors<Form>>({})
+
+  const i18n = useTranslator()
+
+  const productWithInfiniteStock = state.product && state.product.total_stock 
=== -1
+
+  const submit = (): void => {
+    if (!state.product) {
+      setErrors({ product: i18n`You must enter a valid product identifier.` });
+      return;
+    }
+    if (productWithInfiniteStock) {
+      onAddProduct(state.product, 1)
+    } else {
+      if (!state.quantity || state.quantity <= 0) {
+        setErrors({ quantity: i18n`Quantity must be greater than 0!` });
+        return;
+      }
+      const currentStock = state.product.total_stock - 
state.product.total_lost - state.product.total_sold
+      const p = currentProducts[state.product.id]
+      if (p) {
+        if (state.quantity + p.quantity > currentStock) {
+          const left = currentStock - p.quantity;
+          setErrors({ quantity: i18n`This quantity exceeds remaining stock. 
Currently, only ${left} units remain unreserved in stock.` });
+          return;
+        }
+        onAddProduct(state.product, state.quantity + p.quantity)
+      } else {
+        if (state.quantity > currentStock) {
+          const left = currentStock;
+          setErrors({ quantity: i18n`This quantity exceeds remaining stock. 
Currently, only ${left} units remain unreserved in stock.` });
+          return;
+        }
+        onAddProduct(state.product, state.quantity)
+      }
+    }
+
+    setState(initialState)
+  }
+
+  return <FormProvider<Form> errors={errors} object={state} 
valueHandler={setState}>
+    <InputSearchProduct selected={state.product} onChange={(p) => setState(v 
=> ({ ...v, product: p }))} products={inventory} />
+    { state.product && <div class="columns mt-5">
+      <div class="column is-two-thirds">
+        {!productWithInfiniteStock &&
+          <InputNumber<Form> name="quantity" label={i18n`Quantity`} 
tooltip={i18n`how many products will be added`} />
+        }
+      </div>
+      <div class="column">
+        <div class="buttons is-right">
+          <button class="button is-success" onClick={submit}><Translate>Add 
from inventory</Translate></button>
+        </div>
+      </div>
+    </div> }
+
+  </FormProvider>
+}
diff --git 
a/packages/merchant-backoffice-ui/src/components/product/NonInventoryProductForm.tsx
 
b/packages/merchant-backoffice-ui/src/components/product/NonInventoryProductForm.tsx
new file mode 100644
index 000000000..397efe616
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/components/product/NonInventoryProductForm.tsx
@@ -0,0 +1,146 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+import { Fragment, h, VNode } from "preact";
+import { useCallback, useEffect, useState } from "preact/hooks";
+import * as yup from 'yup';
+import { FormErrors, FormProvider } from "../form/FormProvider";
+import { Input } from "../form/Input";
+import { InputCurrency } from "../form/InputCurrency";
+import { InputImage } from "../form/InputImage";
+import { InputNumber } from "../form/InputNumber";
+import { InputTaxes } from "../form/InputTaxes";
+import { MerchantBackend } from "../../declaration";
+import { useListener } from "../../hooks/listener";
+import { Translate, useTranslator } from "../../i18n";
+import {
+  NonInventoryProductSchema as schema
+} from '../../schemas';
+
+
+type Entity = MerchantBackend.Product
+
+interface Props {
+  onAddProduct: (p: Entity) => Promise<void>;
+  productToEdit?: Entity;
+}
+export function NonInventoryProductFrom({ productToEdit, onAddProduct }: 
Props): VNode {
+  const [showCreateProduct, setShowCreateProduct] = useState(false)
+
+  const isEditing = !!productToEdit
+
+  useEffect(() => {
+    setShowCreateProduct(isEditing)
+  }, [isEditing])
+
+  const [submitForm, addFormSubmitter] = 
useListener<Partial<MerchantBackend.Product> | undefined>((result) => {
+    if (result) {
+      setShowCreateProduct(false)
+      return onAddProduct({
+        quantity: result.quantity || 0,
+        taxes: result.taxes || [],
+        description: result.description || '',
+        image: result.image || '',
+        price: result.price || '',
+        unit: result.unit || ''
+      })
+    }
+    return Promise.resolve()
+  })
+
+  const i18n = useTranslator()
+
+  return <Fragment>
+    <div class="buttons">
+      <button class="button is-success" data-tooltip={i18n`describe and add a 
product that is not in the inventory list`} onClick={() => 
setShowCreateProduct(true)} ><Translate>Add custom product</Translate></button>
+    </div>
+    {showCreateProduct && <div class="modal is-active">
+      <div class="modal-background " onClick={() => 
setShowCreateProduct(false)} />
+      <div class="modal-card">
+        <header class="modal-card-head">
+          <p class="modal-card-title">{i18n`Complete information of the 
product`}</p>
+          <button class="delete " aria-label="close" onClick={() => 
setShowCreateProduct(false)} />
+        </header>
+        <section class="modal-card-body">
+          <ProductForm initial={productToEdit} onSubscribe={addFormSubmitter} 
/>
+        </section>
+        <footer class="modal-card-foot">
+          <div class="buttons is-right" style={{ width: '100%' }}>
+            <button class="button " onClick={() => 
setShowCreateProduct(false)} ><Translate>Cancel</Translate></button>
+            <button class="button is-info " disabled={!submitForm} 
onClick={submitForm} ><Translate>Confirm</Translate></button>
+          </div>
+        </footer>
+      </div>
+      <button class="modal-close is-large " aria-label="close" onClick={() => 
setShowCreateProduct(false)} />
+    </div>}
+  </Fragment>
+}
+
+interface ProductProps {
+  onSubscribe: (c?: () => Entity | undefined) => void;
+  initial?: Partial<Entity>;
+}
+
+interface NonInventoryProduct {
+  quantity: number;
+  description: string;
+  unit: string;
+  price: string;
+  image: string;
+  taxes: MerchantBackend.Tax[];
+}
+
+export function ProductForm({ onSubscribe, initial }: ProductProps): VNode {
+  const [value, valueHandler] = useState<Partial<NonInventoryProduct>>({
+    taxes: [],
+    ...initial,
+  })
+  let errors: FormErrors<Entity> = {}
+  try {
+    schema.validateSync(value, { abortEarly: false })
+  } catch (err) {
+    if (err instanceof yup.ValidationError) {
+      const yupErrors = err.inner as yup.ValidationError[]
+      errors = yupErrors.reduce((prev, cur) => !cur.path ? prev : ({ ...prev, 
[cur.path]: cur.message }), {})
+    }
+  }
+
+  const submit = useCallback((): Entity | undefined => {
+    return value as MerchantBackend.Product
+  }, [value])
+
+  const hasErrors = Object.keys(errors).some(k => (errors as any)[k] !== 
undefined)
+
+  useEffect(() => {
+    onSubscribe(hasErrors ? undefined : submit)
+  }, [submit, hasErrors])
+
+  const i18n = useTranslator()
+
+  return <div>
+    <FormProvider<NonInventoryProduct> name="product" errors={errors} 
object={value} valueHandler={valueHandler} >
+
+      <InputImage<NonInventoryProduct> name="image" label={i18n`Image`} 
tooltip={i18n`photo of the product`} />
+      <Input<NonInventoryProduct> name="description" inputType="multiline" 
label={i18n`Description`} tooltip={i18n`full product description`} />
+      <Input<NonInventoryProduct> name="unit" label={i18n`Unit`} 
tooltip={i18n`name of the product unit`} />
+      <InputCurrency<NonInventoryProduct> name="price" label={i18n`Price`} 
tooltip={i18n`amount in the current currency`} />
+
+      <InputNumber<NonInventoryProduct> name="quantity" label={i18n`Quantity`} 
tooltip={i18n`how many products will be added`} />
+
+      <InputTaxes<NonInventoryProduct> name="taxes" label={i18n`Taxes`} />
+
+    </FormProvider>
+  </div>
+}
diff --git 
a/packages/merchant-backoffice-ui/src/components/product/ProductForm.tsx 
b/packages/merchant-backoffice-ui/src/components/product/ProductForm.tsx
new file mode 100644
index 000000000..9434d3de8
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/product/ProductForm.tsx
@@ -0,0 +1,176 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { h } from "preact";
+import { useCallback, useEffect, useState } from "preact/hooks";
+import * as yup from "yup";
+import { useBackendContext } from "../../context/backend";
+import { MerchantBackend } from "../../declaration";
+import { useTranslator } from "../../i18n";
+import {
+  ProductCreateSchema as createSchema,
+  ProductUpdateSchema as updateSchema,
+} from "../../schemas";
+import { FormProvider, FormErrors } from "../form/FormProvider";
+import { Input } from "../form/Input";
+import { InputCurrency } from "../form/InputCurrency";
+import { InputImage } from "../form/InputImage";
+import { InputNumber } from "../form/InputNumber";
+import { InputStock, Stock } from "../form/InputStock";
+import { InputTaxes } from "../form/InputTaxes";
+import { InputWithAddon } from "../form/InputWithAddon";
+
+type Entity = MerchantBackend.Products.ProductDetail & { product_id: string };
+
+interface Props {
+  onSubscribe: (c?: () => Entity | undefined) => void;
+  initial?: Partial<Entity>;
+  alreadyExist?: boolean;
+}
+
+export function ProductForm({ onSubscribe, initial, alreadyExist }: Props) {
+  const [value, valueHandler] = useState<Partial<Entity & { stock: Stock }>>({
+    address: {},
+    description_i18n: {},
+    taxes: [],
+    next_restock: { t_s: "never" },
+    price: ":0",
+    ...initial,
+    stock:
+      !initial || initial.total_stock === -1
+        ? undefined
+        : {
+            current: initial.total_stock || 0,
+            lost: initial.total_lost || 0,
+            sold: initial.total_sold || 0,
+            address: initial.address,
+            nextRestock: initial.next_restock,
+          },
+  });
+  let errors: FormErrors<Entity> = {};
+
+  try {
+    (alreadyExist ? updateSchema : createSchema).validateSync(value, {
+      abortEarly: false,
+    });
+  } catch (err) {
+    if (err instanceof yup.ValidationError) {
+      const yupErrors = err.inner as yup.ValidationError[];
+      errors = yupErrors.reduce(
+        (prev, cur) =>
+          !cur.path ? prev : { ...prev, [cur.path]: cur.message },
+        {}
+      );
+    }
+  }
+  const hasErrors = Object.keys(errors).some(
+    (k) => (errors as any)[k] !== undefined
+  );
+
+  const submit = useCallback((): Entity | undefined => {
+    const stock: Stock = (value as any).stock;
+
+    if (!stock) {
+      value.total_stock = -1;
+    } else {
+      value.total_stock = stock.current;
+      value.total_lost = stock.lost;
+      value.next_restock =
+        stock.nextRestock instanceof Date
+          ? { t_s: stock.nextRestock.getTime() / 1000 }
+          : stock.nextRestock;
+      value.address = stock.address;
+    }
+    delete (value as any).stock;
+
+    if (typeof value.minimum_age !== "undefined" && value.minimum_age < 1) {
+      delete value.minimum_age;
+    }
+
+    return value as MerchantBackend.Products.ProductDetail & {
+      product_id: string;
+    };
+  }, [value]);
+
+  useEffect(() => {
+    onSubscribe(hasErrors ? undefined : submit);
+  }, [submit, hasErrors]);
+
+  const backend = useBackendContext();
+  const i18n = useTranslator();
+
+  return (
+    <div>
+      <FormProvider<Entity>
+        name="product"
+        errors={errors}
+        object={value}
+        valueHandler={valueHandler}
+      >
+        {alreadyExist ? undefined : (
+          <InputWithAddon<Entity>
+            name="product_id"
+            addonBefore={`${backend.url}/product/`}
+            label={i18n`ID`}
+            tooltip={i18n`product identification to use in URLs (for internal 
use only)`}
+          />
+        )}
+        <InputImage<Entity>
+          name="image"
+          label={i18n`Image`}
+          tooltip={i18n`illustration of the product for customers`}
+        />
+        <Input<Entity>
+          name="description"
+          inputType="multiline"
+          label={i18n`Description`}
+          tooltip={i18n`product description for customers`}
+        />
+        <InputNumber<Entity>
+          name="minimum_age"
+          label={i18n`Age restricted`}
+          tooltip={i18n`is this product restricted for customer below certain 
age?`}
+        />
+        <Input<Entity>
+          name="unit"
+          label={i18n`Unit`}
+          tooltip={i18n`unit describing quantity of product sold (e.g. 2 
kilograms, 5 liters, 3 items, 5 meters) for customers`}
+        />
+        <InputCurrency<Entity>
+          name="price"
+          label={i18n`Price`}
+          tooltip={i18n`sale price for customers, including taxes, for above 
units of the product`}
+        />
+        <InputStock
+          name="stock"
+          label={i18n`Stock`}
+          alreadyExist={alreadyExist}
+          tooltip={i18n`product inventory for products with finite supply (for 
internal use only)`}
+        />
+        <InputTaxes<Entity>
+          name="taxes"
+          label={i18n`Taxes`}
+          tooltip={i18n`taxes included in the product price, exposed to 
customers`}
+        />
+      </FormProvider>
+    </div>
+  );
+}
diff --git 
a/packages/merchant-backoffice-ui/src/components/product/ProductList.tsx 
b/packages/merchant-backoffice-ui/src/components/product/ProductList.tsx
new file mode 100644
index 000000000..ff141bb39
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/components/product/ProductList.tsx
@@ -0,0 +1,105 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+import { Amounts } from "@gnu-taler/taler-util";
+import { h, VNode } from "preact";
+import emptyImage from "../../assets/empty.png";
+import { MerchantBackend } from "../../declaration";
+import { Translate } from "../../i18n";
+
+interface Props {
+  list: MerchantBackend.Product[];
+  actions?: {
+    name: string;
+    tooltip: string;
+    handler: (d: MerchantBackend.Product, index: number) => void;
+  }[];
+}
+export function ProductList({ list, actions = [] }: Props): VNode {
+  return (
+    <div class="table-container">
+      <table class="table is-fullwidth is-striped is-hoverable is-fullwidth">
+        <thead>
+          <tr>
+            <th>
+              <Translate>image</Translate>
+            </th>
+            <th>
+              <Translate>description</Translate>
+            </th>
+            <th>
+              <Translate>quantity</Translate>
+            </th>
+            <th>
+              <Translate>unit price</Translate>
+            </th>
+            <th>
+              <Translate>total price</Translate>
+            </th>
+            <th />
+          </tr>
+        </thead>
+        <tbody>
+          {list.map((entry, index) => {
+            const unitPrice = !entry.price ? "0" : entry.price;
+            const totalPrice = !entry.price
+              ? "0"
+              : Amounts.stringify(
+                  Amounts.mult(
+                    Amounts.parseOrThrow(entry.price),
+                    entry.quantity
+                  ).amount
+                );
+
+            return (
+              <tr key={index}>
+                <td>
+                  <img
+                    style={{ height: 32, width: 32 }}
+                    src={entry.image ? entry.image : emptyImage}
+                  />
+                </td>
+                <td>{entry.description}</td>
+                <td>
+                  {entry.quantity === 0
+                    ? "--"
+                    : `${entry.quantity} ${entry.unit}`}
+                </td>
+                <td>{unitPrice}</td>
+                <td>{totalPrice}</td>
+                <td class="is-actions-cell right-sticky">
+                  {actions.map((a, i) => {
+                    return (
+                      <div key={i} class="buttons is-right">
+                        <button
+                          class="button is-small is-danger has-tooltip-left"
+                          data-tooltip={a.tooltip}
+                          type="button"
+                          onClick={() => a.handler(entry, index)}
+                        >
+                          {a.name}
+                        </button>
+                      </div>
+                    );
+                  })}
+                </td>
+              </tr>
+            );
+          })}
+        </tbody>
+      </table>
+    </div>
+  );
+}
diff --git a/packages/merchant-backoffice-ui/src/context/backend.ts 
b/packages/merchant-backoffice-ui/src/context/backend.ts
new file mode 100644
index 000000000..9ef7bfdea
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/context/backend.ts
@@ -0,0 +1,82 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { createContext, h, VNode } from 'preact'
+import { useCallback, useContext, useState } from 'preact/hooks'
+import { useBackendDefaultToken, useBackendURL } from '../hooks';
+
+interface BackendContextType {
+  url: string;
+  token?: string;
+  triedToLog: boolean;
+  resetBackend: () => void;
+  clearAllTokens: () => void;
+  addTokenCleaner: (c: () => void) => void;
+  updateLoginStatus: (url: string, token?: string) => void;
+}
+
+const BackendContext = createContext<BackendContextType>({
+  url: '',
+  token: undefined,
+  triedToLog: false,
+  resetBackend: () => null,
+  clearAllTokens: () => null,
+  addTokenCleaner: () => null,
+  updateLoginStatus: () => null,
+})
+
+function useBackendContextState(defaultUrl?: string, initialToken?: string): 
BackendContextType {
+  const [url, triedToLog, changeBackend, resetBackend] = 
useBackendURL(defaultUrl);
+  const [token, _updateToken] = useBackendDefaultToken(initialToken);
+  const updateToken = (t?: string) => {
+    _updateToken(t)
+  }
+
+  const tokenCleaner = useCallback(() => { updateToken(undefined) }, [])
+  const [cleaners, setCleaners] = useState([tokenCleaner])
+  const addTokenCleaner = (c: () => void) => setCleaners(cs => [...cs, c])
+  const addTokenCleanerMemo = useCallback((c: () => void) => { 
addTokenCleaner(c) }, [tokenCleaner])
+
+  const clearAllTokens = () => {
+    cleaners.forEach(c => c())
+    for (let i = 0; i < localStorage.length; i++) {
+      const k = localStorage.key(i)
+      if (k && /^backend-token/.test(k)) localStorage.removeItem(k)
+    }
+    resetBackend()
+  }
+
+  const updateLoginStatus = (url: string, token?: string) => {
+    changeBackend(url);
+    if (token) updateToken(token);
+  };
+
+
+  return { url, token, triedToLog, updateLoginStatus, resetBackend, 
clearAllTokens, addTokenCleaner: addTokenCleanerMemo }
+}
+
+export const BackendContextProvider = ({ children, defaultUrl, initialToken }: 
{ children: any, defaultUrl?: string, initialToken?: string }): VNode => {
+  const value = useBackendContextState(defaultUrl, initialToken)
+
+  return h(BackendContext.Provider, { value, children });
+}
+
+export const useBackendContext = (): BackendContextType => 
useContext(BackendContext);
diff --git a/packages/merchant-backoffice-ui/src/context/config.ts 
b/packages/merchant-backoffice-ui/src/context/config.ts
new file mode 100644
index 000000000..5cd772380
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/context/config.ts
@@ -0,0 +1,32 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { createContext } from 'preact'
+import { useContext } from 'preact/hooks'
+
+interface Type {
+  currency: string;
+  version: string;
+}
+const Context = createContext<Type>(null!)
+
+export const ConfigContextProvider = Context.Provider
+export const useConfigContext = (): Type => useContext(Context);
diff --git a/packages/merchant-backoffice-ui/src/context/fetch.ts 
b/packages/merchant-backoffice-ui/src/context/fetch.ts
new file mode 100644
index 000000000..ef4dfb7ae
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/context/fetch.ts
@@ -0,0 +1,54 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { h, createContext, VNode, ComponentChildren } from "preact";
+import { useContext } from "preact/hooks";
+import useSWR from "swr";
+import useSWRInfinite from "swr/infinite";
+
+interface Type {
+  useSWR: typeof useSWR;
+  useSWRInfinite: typeof useSWRInfinite;
+}
+
+const Context = createContext<Type>({} as any);
+
+export const useFetchContext = (): Type => useContext(Context);
+export const FetchContextProvider = ({
+  children,
+}: {
+  children: ComponentChildren;
+}): VNode => {
+  return h(Context.Provider, { value: { useSWR, useSWRInfinite }, children });
+};
+
+export const FetchContextProviderTesting = ({
+  children,
+  data,
+}: {
+  children: ComponentChildren;
+  data: any;
+}): VNode => {
+  return h(Context.Provider, {
+    value: { useSWR: () => data, useSWRInfinite },
+    children,
+  });
+};
diff --git a/packages/merchant-backoffice-ui/src/context/instance.ts 
b/packages/merchant-backoffice-ui/src/context/instance.ts
new file mode 100644
index 000000000..fecf36426
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/context/instance.ts
@@ -0,0 +1,35 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { createContext } from 'preact'
+import { useContext } from 'preact/hooks'
+
+interface Type {
+  id: string;
+  token?: string;
+  admin?: boolean;
+  changeToken: (t?:string) => void;
+}
+
+const Context = createContext<Type>({} as any)
+
+export const InstanceContextProvider = Context.Provider
+export const useInstanceContext = (): Type => useContext(Context);
diff --git a/packages/merchant-backoffice-ui/src/context/listener.ts 
b/packages/merchant-backoffice-ui/src/context/listener.ts
new file mode 100644
index 000000000..659db0a03
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/context/listener.ts
@@ -0,0 +1,35 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { createContext } from 'preact'
+import { useContext } from 'preact/hooks'
+
+interface Type {
+  id: string;
+  token?: string;
+  admin?: boolean;
+  changeToken: (t?:string) => void;
+}
+
+const Context = createContext<Type>({} as any)
+
+export const ListenerContextProvider = Context.Provider
+export const useListenerContext = (): Type => useContext(Context);
diff --git a/packages/merchant-backoffice-ui/src/context/translation.ts 
b/packages/merchant-backoffice-ui/src/context/translation.ts
new file mode 100644
index 000000000..952a1e325
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/context/translation.ts
@@ -0,0 +1,59 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { createContext, h, VNode } from 'preact'
+import { useContext, useEffect } from 'preact/hooks'
+import { useLang } from '../hooks'
+import * as jedLib from "jed";
+import { strings } from "../i18n/strings";
+
+interface Type {
+  lang: string;
+  handler: any;
+  changeLanguage: (l: string) => void;
+}
+const initial = {
+  lang: 'en',
+  handler: null,
+  changeLanguage: () => {
+    // do not change anything
+  }
+}
+const Context = createContext<Type>(initial)
+
+interface Props {
+  initial?: string,
+  children: any,
+  forceLang?: string
+}
+
+export const TranslationProvider = ({ initial, children, forceLang }: Props): 
VNode => {
+  const [lang, changeLanguage] = useLang(initial)
+  useEffect(() => {
+    if (forceLang) {
+      changeLanguage(forceLang)
+    }
+  })
+  const handler = new jedLib.Jed(strings[lang]);
+  return h(Context.Provider, { value: { lang, handler, changeLanguage }, 
children });
+}
+
+export const useTranslationContext = (): Type => useContext(Context);
\ No newline at end of file
diff --git a/packages/merchant-backoffice-ui/src/custom.d.ts 
b/packages/merchant-backoffice-ui/src/custom.d.ts
new file mode 100644
index 000000000..d2705003b
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/custom.d.ts
@@ -0,0 +1,40 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+declare module '*.po' {
+  const content: any;
+  export default content;
+}
+declare module 'jed' {
+  const x: any;
+  export = x;
+}
+declare module "*.jpeg" {
+  const content: any;
+  export default content;
+}
+declare module "*.png" {
+  const content: any;
+  export default content;
+}
+declare module '*.svg' {
+  const content: any;
+  export default content;
+}
+
+declare module '*.scss' {
+  const content: Record<string, string>;
+  export default content;
+}
diff --git a/packages/merchant-backoffice-ui/src/declaration.d.ts 
b/packages/merchant-backoffice-ui/src/declaration.d.ts
new file mode 100644
index 000000000..f0d257d3c
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/declaration.d.ts
@@ -0,0 +1,1443 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+
+type HashCode = string;
+type EddsaPublicKey = string;
+type EddsaSignature = string;
+type WireTransferIdentifierRawP = string;
+type RelativeTime = Duration;
+type ImageDataUrl = string;
+
+export interface WithId {
+    id: string
+}
+
+interface Timestamp {
+    // Milliseconds since epoch, or the special
+    // value "forever" to represent an event that will
+    // never happen.
+    t_s: number | "never";
+}
+interface Duration {
+    d_us: number | "forever";
+}
+
+interface WithId {
+    id: string;
+}
+
+type Amount = string;
+type UUID = string;
+type Integer = number;
+
+export namespace ExchangeBackend {
+    interface WireResponse {
+
+        // Master public key of the exchange, must match the key returned in 
/keys.
+        master_public_key: EddsaPublicKey;
+
+        // Array of wire accounts operated by the exchange for
+        // incoming wire transfers.
+        accounts: WireAccount[];
+
+        // Object mapping names of wire methods (i.e. "sepa" or "x-taler-bank")
+        // to wire fees.
+        fees: { method: AggregateTransferFee };
+    }
+    interface WireAccount {
+        // payto:// URI identifying the account and wire method
+        payto_uri: string;
+
+        // Signature using the exchange's offline key
+        // with purpose TALER_SIGNATURE_MASTER_WIRE_DETAILS.
+        master_sig: EddsaSignature;
+    }
+    interface AggregateTransferFee {
+        // Per transfer wire transfer fee.
+        wire_fee: Amount;
+
+        // Per transfer closing fee.
+        closing_fee: Amount;
+
+        // What date (inclusive) does this fee go into effect?
+        // The different fees must cover the full time period in which
+        // any of the denomination keys are valid without overlap.
+        start_date: Timestamp;
+
+        // What date (exclusive) does this fee stop going into effect?
+        // The different fees must cover the full time period in which
+        // any of the denomination keys are valid without overlap.
+        end_date: Timestamp;
+
+        // Signature of TALER_MasterWireFeePS with
+        // purpose TALER_SIGNATURE_MASTER_WIRE_FEES.
+        sig: EddsaSignature;
+    }
+
+}
+export namespace MerchantBackend {
+    interface ErrorDetail {
+
+        // Numeric error code unique to the condition.
+        // The other arguments are specific to the error value reported here.
+        code: number;
+
+        // Human-readable description of the error, i.e. "missing parameter", 
"commitment violation", ...
+        // Should give a human-readable hint about the error's nature. 
Optional, may change without notice!
+        hint?: string;
+
+        // Optional detail about the specific input value that failed. May 
change without notice!
+        detail?: string;
+
+        // Name of the parameter that was bogus (if applicable).
+        parameter?: string;
+
+        // Path to the argument that was bogus (if applicable).
+        path?: string;
+
+        // Offset of the argument that was bogus (if applicable).
+        offset?: string;
+
+        // Index of the argument that was bogus (if applicable).
+        index?: string;
+
+        // Name of the object that was bogus (if applicable).
+        object?: string;
+
+        // Name of the currency than was problematic (if applicable).
+        currency?: string;
+
+        // Expected type (if applicable).
+        type_expected?: string;
+
+        // Type that was provided instead (if applicable).
+        type_actual?: string;
+    }
+
+
+    // Delivery location, loosely modeled as a subset of
+    // ISO20022's PostalAddress25.
+    interface Tax {
+        // the name of the tax
+        name: string;
+
+        // amount paid in tax
+        tax: Amount;
+    }
+
+    interface Auditor {
+        // official name
+        name: string;
+
+        // Auditor's public key
+        auditor_pub: EddsaPublicKey;
+
+        // Base URL of the auditor
+        url: string;
+    }
+    interface Exchange {
+        // the exchange's base URL
+        url: string;
+
+        // master public key of the exchange
+        master_pub: EddsaPublicKey;
+    }
+
+    interface Product {
+        // merchant-internal identifier for the product.
+        product_id?: string;
+
+        // Human-readable product description.
+        description: string;
+
+        // Map from IETF BCP 47 language tags to localized descriptions
+        description_i18n?: { [lang_tag: string]: string };
+
+        // The number of units of the product to deliver to the customer.
+        quantity: Integer;
+
+        // The unit in which the product is measured (liters, kilograms, 
packages, etc.)
+        unit: string;
+
+        // The price of the product; this is the total price for quantity 
times unit of this product.
+        price?: Amount;
+
+        // An optional base64-encoded product image
+        image: ImageDataUrl;
+
+        // a list of taxes paid by the merchant for this product. Can be empty.
+        taxes: Tax[];
+
+        // time indicating when this product should be delivered
+        delivery_date?: TalerProtocolTimestamp;
+
+        // Minimum age buyer must have (in years). Default is 0.
+        minimum_age?: Integer;
+    }
+    interface Merchant {
+        // label for a location with the business address of the merchant
+        address: Location;
+
+        // the merchant's legal name of business
+        name: string;
+
+        // label for a location that denotes the jurisdiction for disputes.
+        // Some of the typical fields for a location (such as a street 
address) may be absent.
+        jurisdiction: Location;
+    }
+
+    interface VersionResponse {
+        // libtool-style representation of the Merchant protocol version, see
+        // 
https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
+        // The format is "current:revision:age".
+        version: string;
+
+        // Name of the protocol.
+        name: "taler-merchant";
+
+        // Currency supported by this backend.
+        currency: string;
+
+    }
+    interface Location {
+        // Nation with its own government.
+        country?: string;
+
+        // Identifies a subdivision of a country such as state, region, county.
+        country_subdivision?: string;
+
+        // Identifies a subdivision within a country sub-division.
+        district?: string;
+
+        // Name of a built-up area, with defined boundaries, and a local 
government.
+        town?: string;
+
+        // Specific location name within the town.
+        town_location?: string;
+
+        // Identifier consisting of a group of letters and/or numbers that
+        // is added to a postal address to assist the sorting of mail.
+        post_code?: string;
+
+        // Name of a street or thoroughfare.
+        street?: string;
+
+        // Name of the building or house.
+        building_name?: string;
+
+        // Number that identifies the position of a building on a street.
+        building_number?: string;
+
+        // Free-form address lines, should not exceed 7 elements.
+        address_lines?: string[];
+    }
+    namespace Instances {
+
+        //POST /private/instances/$INSTANCE/auth
+        interface InstanceAuthConfigurationMessage {
+            // Type of authentication.
+            // "external":  The mechant backend does not do
+            //   any authentication checks.  Instead an API
+            //   gateway must do the authentication.
+            // "token": The merchant checks an auth token.
+            //   See "token" for details.
+            method: "external" | "token";
+
+            // For method "external", this field is mandatory.
+            // The token MUST begin with the string "secret-token:".
+            // After the auth token has been set (with method "token"),
+            // the value must be provided in a "Authorization: Bearer $token"
+            // header.
+            token?: string;
+
+        }
+        //POST /private/instances
+        interface InstanceConfigurationMessage {
+            // The URI where the wallet will send coins.  A merchant may have
+            // multiple accounts, thus this is an array.  Note that by
+            // removing URIs from this list the respective account is set to
+            // inactive and thus unavailable for new contracts, but preserved
+            // in the database as existing offers and contracts may still refer
+            // to it.
+            payto_uris: string[];
+
+            // Name of the merchant instance to create (will become $INSTANCE).
+            id: string;
+
+            // Merchant name corresponding to this instance.
+            name: string;
+
+            email: string;
+            website: string;
+            // An optional base64-encoded logo image
+            logo: ImageDataUrl;
+
+
+            // "Authentication" header required to authorize management access 
the instance.
+            // Optional, if not given authentication will be disabled for
+            // this instance (hopefully authentication checks are still
+            // done by some reverse proxy).
+            auth: InstanceAuthConfigurationMessage;
+
+            // The merchant's physical address (to be put into contracts).
+            address: Location;
+
+            // The jurisdiction under which the merchant conducts its business
+            // (to be put into contracts).
+            jurisdiction: Location;
+
+            // Maximum wire fee this instance is willing to pay.
+            // Can be overridden by the frontend on a per-order basis.
+            default_max_wire_fee: Amount;
+
+            // Default factor for wire fee amortization calculations.
+            // Can be overridden by the frontend on a per-order basis.
+            default_wire_fee_amortization: Integer;
+
+            // Maximum deposit fee (sum over all coins) this instance is 
willing to pay.
+            // Can be overridden by the frontend on a per-order basis.
+            default_max_deposit_fee: Amount;
+
+            //  If the frontend does NOT specify an execution date, how long 
should
+            // we tell the exchange to wait to aggregate transactions before
+            // executing the wire transfer?  This delay is added to the current
+            // time when we generate the advisory execution time for the 
exchange.
+            default_wire_transfer_delay: RelativeTime;
+
+            // If the frontend does NOT specify a payment deadline, how long 
should
+            // offers we make be valid by default?
+            default_pay_delay: RelativeTime;
+
+        }
+
+        // PATCH /private/instances/$INSTANCE
+        interface InstanceReconfigurationMessage {
+            // The URI where the wallet will send coins.  A merchant may have
+            // multiple accounts, thus this is an array.  Note that by
+            // removing URIs from this list
+            payto_uris: string[];
+
+            // Merchant name corresponding to this instance.
+            name: string;
+
+            // The merchant's physical address (to be put into contracts).
+            address: Location;
+
+            // The jurisdiction under which the merchant conducts its business
+            // (to be put into contracts).
+            jurisdiction: Location;
+
+            // Maximum wire fee this instance is willing to pay.
+            // Can be overridden by the frontend on a per-order basis.
+            default_max_wire_fee: Amount;
+
+            // Default factor for wire fee amortization calculations.
+            // Can be overridden by the frontend on a per-order basis.
+            default_wire_fee_amortization: Integer;
+
+            // Maximum deposit fee (sum over all coins) this instance is 
willing to pay.
+            // Can be overridden by the frontend on a per-order basis.
+            default_max_deposit_fee: Amount;
+
+            //  If the frontend does NOT specify an execution date, how long 
should
+            // we tell the exchange to wait to aggregate transactions before
+            // executing the wire transfer?  This delay is added to the current
+            // time when we generate the advisory execution time for the 
exchange.
+            default_wire_transfer_delay: RelativeTime;
+
+            // If the frontend does NOT specify a payment deadline, how long 
should
+            // offers we make be valid by default?
+            default_pay_delay: RelativeTime;
+
+        }
+
+        //   GET /private/instances
+        interface InstancesResponse {
+            // List of instances that are present in the backend (see Instance)
+            instances: Instance[];
+        }
+
+        interface Instance {
+            // Merchant name corresponding to this instance.
+            name: string;
+
+            deleted?: boolean;
+
+            // Merchant instance this response is about ($INSTANCE)
+            id: string;
+
+            // Public key of the merchant/instance, in Crockford Base32 
encoding.
+            merchant_pub: EddsaPublicKey;
+
+            // List of the payment targets supported by this instance. Clients 
can
+            // specify the desired payment target in /order requests.  Note 
that
+            // front-ends do not have to support wallets selecting payment 
targets.
+            payment_targets: string[];
+
+        }
+
+        //GET /private/instances/$INSTANCE/kyc
+        interface AccountKycRedirects {
+            // Array of pending KYCs.
+            pending_kycs: MerchantAccountKycRedirect[];
+
+            // Array of exchanges with no reply.
+            timeout_kycs: ExchangeKycTimeout[];
+
+        }
+        interface MerchantAccountKycRedirect {
+
+            // URL that the user should open in a browser to
+            // proceed with the KYC process (as returned
+            // by the exchange's /kyc-check/ endpoint).
+            kyc_url: string;
+
+            // Base URL of the exchange this is about.
+            exchange_url: string;
+
+            // Our bank wire account this is about.
+            payto_uri: string;
+
+        }
+        interface ExchangeKycTimeout {
+
+            // Base URL of the exchange this is about.
+            exchange_url: string;
+
+            // Numeric error code indicating errors the exchange
+            // returned, or TALER_EC_INVALID for none.
+            exchange_code: number;
+
+            // HTTP status code returned by the exchange when we asked for
+            // information about the KYC status.
+            // 0 if there was no response at all.
+            exchange_http_status: number;
+
+        }
+
+        //GET /private/instances/$INSTANCE
+        interface QueryInstancesResponse {
+            // The URI where the wallet will send coins.  A merchant may have
+            // multiple accounts, thus this is an array.
+            accounts: MerchantAccount[];
+
+            // Merchant name corresponding to this instance.
+            name: string;
+
+            // Public key of the merchant/instance, in Crockford Base32 
encoding.
+            merchant_pub: EddsaPublicKey;
+
+            // The merchant's physical address (to be put into contracts).
+            address: Location;
+
+            // The jurisdiction under which the merchant conducts its business
+            // (to be put into contracts).
+            jurisdiction: Location;
+
+            // Maximum wire fee this instance is willing to pay.
+            // Can be overridden by the frontend on a per-order basis.
+            default_max_wire_fee: Amount;
+
+            // Default factor for wire fee amortization calculations.
+            // Can be overridden by the frontend on a per-order basis.
+            default_wire_fee_amortization: Integer;
+
+            // Maximum deposit fee (sum over all coins) this instance is 
willing to pay.
+            // Can be overridden by the frontend on a per-order basis.
+            default_max_deposit_fee: Amount;
+
+            //  If the frontend does NOT specify an execution date, how long 
should
+            // we tell the exchange to wait to aggregate transactions before
+            // executing the wire transfer?  This delay is added to the current
+            // time when we generate the advisory execution time for the 
exchange.
+            default_wire_transfer_delay: RelativeTime;
+
+            // If the frontend does NOT specify a payment deadline, how long 
should
+            // offers we make be valid by default?
+            default_pay_delay: RelativeTime;
+
+            // Authentication configuration.
+            // Does not contain the token when token auth is configured.
+            auth: {
+                method: "external" | "token";
+                token?: string;
+            };
+        }
+
+        interface MerchantAccount {
+
+            // payto:// URI of the account.
+            payto_uri: string;
+
+            // Hash over the wire details (including over the salt)
+            h_wire: HashCode;
+
+            // salt used to compute h_wire
+            salt: HashCode;
+
+            // true if this account is active,
+            // false if it is historic.
+            active: boolean;
+        }
+
+        //   DELETE /private/instances/$INSTANCE
+
+
+    }
+
+    namespace Products {
+        // POST /private/products
+        interface ProductAddDetail {
+
+            // product ID to use.
+            product_id: string;
+
+            // Human-readable product description.
+            description: string;
+
+            // Map from IETF BCP 47 language tags to localized descriptions
+            description_i18n: { [lang_tag: string]: string };
+
+            // unit in which the product is measured (liters, kilograms, 
packages, etc.)
+            unit: string;
+
+            // The price for one unit of the product. Zero is used
+            // to imply that this product is not sold separately, or
+            // that the price is not fixed, and must be supplied by the
+            // front-end.  If non-zero, this price MUST include applicable
+            // taxes.
+            price: Amount;
+
+            // An optional base64-encoded product image
+            image: ImageDataUrl;
+
+            // a list of taxes paid by the merchant for one unit of this 
product
+            taxes: Tax[];
+
+            // Number of units of the product in stock in sum in total,
+            // including all existing sales ever. Given in product-specific
+            // units.
+            // A value of -1 indicates "infinite" (i.e. for "electronic" 
books).
+            total_stock: Integer;
+
+            // Identifies where the product is in stock.
+            address: Location;
+
+            // Identifies when we expect the next restocking to happen.
+            next_restock?: Timestamp;
+
+            // Minimum age buyer must have (in years). Default is 0.
+            minimum_age?: Integer;
+        }
+        //   PATCH /private/products/$PRODUCT_ID
+        interface ProductPatchDetail {
+
+            // Human-readable product description.
+            description: string;
+
+            // Map from IETF BCP 47 language tags to localized descriptions
+            description_i18n: { [lang_tag: string]: string };
+
+            // unit in which the product is measured (liters, kilograms, 
packages, etc.)
+            unit: string;
+
+            // The price for one unit of the product. Zero is used
+            // to imply that this product is not sold separately, or
+            // that the price is not fixed, and must be supplied by the
+            // front-end.  If non-zero, this price MUST include applicable
+            // taxes.
+            price: Amount;
+
+            // An optional base64-encoded product image
+            image: ImageDataUrl;
+
+            // a list of taxes paid by the merchant for one unit of this 
product
+            taxes: Tax[];
+
+            // Number of units of the product in stock in sum in total,
+            // including all existing sales ever. Given in product-specific
+            // units.
+            // A value of -1 indicates "infinite" (i.e. for "electronic" 
books).
+            total_stock: Integer;
+
+            // Number of units of the product that were lost (spoiled, stolen, 
etc.)
+            total_lost: Integer;
+
+            // Identifies where the product is in stock.
+            address: Location;
+
+            // Identifies when we expect the next restocking to happen.
+            next_restock?: Timestamp;
+
+            // Minimum age buyer must have (in years). Default is 0.
+            minimum_age?: Integer;
+        }
+
+        // GET /private/products
+        interface InventorySummaryResponse {
+            // List of products that are present in the inventory
+            products: InventoryEntry[];
+        }
+        interface InventoryEntry {
+            // Product identifier, as found in the product.
+            product_id: string;
+
+        }
+
+        // GET /private/products/$PRODUCT_ID
+        interface ProductDetail {
+
+            // Human-readable product description.
+            description: string;
+
+            // Map from IETF BCP 47 language tags to localized descriptions
+            description_i18n: { [lang_tag: string]: string };
+
+            // unit in which the product is measured (liters, kilograms, 
packages, etc.)
+            unit: string;
+
+            // The price for one unit of the product. Zero is used
+            // to imply that this product is not sold separately, or
+            // that the price is not fixed, and must be supplied by the
+            // front-end.  If non-zero, this price MUST include applicable
+            // taxes.
+            price: Amount;
+
+            // An optional base64-encoded product image
+            image: ImageDataUrl;
+
+            // a list of taxes paid by the merchant for one unit of this 
product
+            taxes: Tax[];
+
+            // Number of units of the product in stock in sum in total,
+            // including all existing sales ever. Given in product-specific
+            // units.
+            // A value of -1 indicates "infinite" (i.e. for "electronic" 
books).
+            total_stock: Integer;
+
+            // Number of units of the product that have already been sold.
+            total_sold: Integer;
+
+            // Number of units of the product that were lost (spoiled, stolen, 
etc.)
+            total_lost: Integer;
+
+            // Identifies where the product is in stock.
+            address: Location;
+
+            // Identifies when we expect the next restocking to happen.
+            next_restock?: Timestamp;
+
+            // Minimum age buyer must have (in years). Default is 0.
+            minimum_age?: Integer;
+        }
+
+        // POST /private/products/$PRODUCT_ID/lock
+        interface LockRequest {
+
+            // UUID that identifies the frontend performing the lock
+            // It is suggested that clients use a timeflake for this,
+            // see https://github.com/anthonynsimon/timeflake
+            lock_uuid: UUID;
+
+            // How long does the frontend intend to hold the lock
+            duration: RelativeTime;
+
+            // How many units should be locked?
+            quantity: Integer;
+
+        }
+
+        //   DELETE /private/products/$PRODUCT_ID
+
+    }
+
+    namespace Orders {
+
+        type MerchantOrderStatusResponse = CheckPaymentPaidResponse |
+            CheckPaymentClaimedResponse |
+            CheckPaymentUnpaidResponse;
+        interface CheckPaymentPaidResponse {
+            // The customer paid for this contract.
+            order_status: "paid";
+
+            // Was the payment refunded (even partially)?
+            refunded: boolean;
+
+            // True if there are any approved refunds that the wallet has
+            // not yet obtained.
+            refund_pending: boolean;
+
+            // Did the exchange wire us the funds?
+            wired: boolean;
+
+            // Total amount the exchange deposited into our bank account
+            // for this contract, excluding fees.
+            deposit_total: Amount;
+
+            // Numeric error code indicating errors the exchange
+            // encountered tracking the wire transfer for this purchase (before
+            // we even got to specific coin issues).
+            // 0 if there were no issues.
+            exchange_ec: number;
+
+            // HTTP status code returned by the exchange when we asked for
+            // information to track the wire transfer for this purchase.
+            // 0 if there were no issues.
+            exchange_hc: number;
+
+            // Total amount that was refunded, 0 if refunded is false.
+            refund_amount: Amount;
+
+            // Contract terms.
+            contract_terms: ContractTerms;
+
+            // The wire transfer status from the exchange for this order if
+            // available, otherwise empty array.
+            wire_details: TransactionWireTransfer[];
+
+            // Reports about trouble obtaining wire transfer details,
+            // empty array if no trouble were encountered.
+            wire_reports: TransactionWireReport[];
+
+            // The refund details for this order.  One entry per
+            // refunded coin; empty array if there are no refunds.
+            refund_details: RefundDetails[];
+
+            // Status URL, can be used as a redirect target for the browser
+            // to show the order QR code / trigger the wallet.
+            order_status_url: string;
+        }
+        interface CheckPaymentClaimedResponse {
+            // A wallet claimed the order, but did not yet pay for the 
contract.
+            order_status: "claimed";
+
+            // Contract terms.
+            contract_terms: ContractTerms;
+
+        }
+        interface CheckPaymentUnpaidResponse {
+            // The order was neither claimed nor paid.
+            order_status: "unpaid";
+
+            // when was the order created
+            creation_time: Timestamp;
+
+            // Order summary text.
+            summary: string;
+
+            // Total amount of the order (to be paid by the customer).
+            total_amount: Amount;
+
+            // URI that the wallet must process to complete the payment.
+            taler_pay_uri: string;
+
+            // Alternative order ID which was paid for already in the same 
session.
+            // Only given if the same product was purchased before in the same 
session.
+            already_paid_order_id?: string;
+
+            // Fulfillment URL of an already paid order. Only given if under 
this
+            // session an already paid order with a fulfillment URL exists.
+            already_paid_fulfillment_url?: string;
+
+            // Status URL, can be used as a redirect target for the browser
+            // to show the order QR code / trigger the wallet.
+            order_status_url: string;
+
+            // We do we NOT return the contract terms here because they may not
+            // exist in case the wallet did not yet claim them.
+        }
+        interface RefundDetails {
+            // Reason given for the refund.
+            reason: string;
+
+            // When was the refund approved.
+            timestamp: Timestamp;
+
+            // Set to true if a refund is still available for the wallet for 
this payment.
+            pending: boolean;
+
+            // Total amount that was refunded (minus a refund fee).
+            amount: Amount;
+        }
+        interface TransactionWireTransfer {
+            // Responsible exchange.
+            exchange_url: string;
+
+            // 32-byte wire transfer identifier.
+            wtid: Base32;
+
+            // Execution time of the wire transfer.
+            execution_time: Timestamp;
+
+            // Total amount that has been wire transferred
+            // to the merchant.
+            amount: Amount;
+
+            // Was this transfer confirmed by the merchant via the
+            // POST /transfers API, or is it merely claimed by the exchange?
+            confirmed: boolean;
+        }
+        interface TransactionWireReport {
+            // Numerical error code.
+            code: number;
+
+            // Human-readable error description.
+            hint: string;
+
+            // Numerical error code from the exchange.
+            exchange_ec: number;
+
+            // HTTP status code received from the exchange.
+            exchange_hc: number;
+
+            // Public key of the coin for which we got the exchange error.
+            coin_pub: CoinPublicKey;
+        }
+
+        interface OrderHistory {
+            // timestamp-sorted array of all orders matching the query.
+            // The order of the sorting depends on the sign of delta.
+            orders: OrderHistoryEntry[];
+        }
+        interface OrderHistoryEntry {
+
+            // order ID of the transaction related to this entry.
+            order_id: string;
+
+            // row ID of the order in the database
+            row_id: number;
+
+            // when the order was created
+            timestamp: Timestamp;
+
+            // the amount of money the order is for
+            amount: Amount;
+
+            // the summary of the order
+            summary: string;
+
+            // whether some part of the order is refundable,
+            // that is the refund deadline has not yet expired
+            // and the total amount refunded so far is below
+            // the value of the original transaction.
+            refundable: boolean;
+
+            // whether the order has been paid or not
+            paid: boolean;
+        }
+
+        interface PostOrderRequest {
+            // The order must at least contain the minimal
+            // order detail, but can override all
+            order: Order;
+
+            // if set, the backend will then set the refund deadline to the 
current
+            // time plus the specified delay.  If it's not set, refunds will 
not be
+            // possible.
+            refund_delay?: RelativeTime;
+
+            // specifies the payment target preferred by the client. Can be 
used
+            // to select among the various (active) wire methods supported by 
the instance.
+            payment_target?: string;
+
+            // specifies that some products are to be included in the
+            // order from the inventory.  For these inventory management
+            // is performed (so the products must be in stock) and
+            // details are completed from the product data of the backend.
+            inventory_products?: MinimalInventoryProduct[];
+
+            // Specifies a lock identifier that was used to
+            // lock a product in the inventory.  Only useful if
+            // manage_inventory is set.  Used in case a frontend
+            // reserved quantities of the individual products while
+            // the shopping card was being built.  Multiple UUIDs can
+            // be used in case different UUIDs were used for different
+            // products (i.e. in case the user started with multiple
+            // shopping sessions that were combined during checkout).
+            lock_uuids?: UUID[];
+
+            // Should a token for claiming the order be generated?
+            // False can make sense if the ORDER_ID is sufficiently
+            // high entropy to prevent adversarial claims (like it is
+            // if the backend auto-generates one). Default is 'true'.
+            create_token?: boolean;
+
+        }
+        type Order = MinimalOrderDetail | ContractTerms;
+
+        interface MinimalOrderDetail {
+            // Amount to be paid by the customer
+            amount: Amount;
+
+            // Short summary of the order
+            summary: string;
+
+            // URL that will show that the order was successful after
+            // it has been paid for.  Optional. When POSTing to the
+            // merchant, the placeholder "${ORDER_ID}" will be
+            // replaced with the actual order ID (useful if the
+            // order ID is generated server-side and needs to be
+            // in the URL).
+            fulfillment_url?: string;
+        }
+
+        interface MinimalInventoryProduct {
+            // Which product is requested (here mandatory!)
+            product_id: string;
+
+            // How many units of the product are requested
+            quantity: Integer;
+        }
+        interface PostOrderResponse {
+            // Order ID of the response that was just created
+            order_id: string;
+
+            // Token that authorizes the wallet to claim the order.
+            // Provided only if "create_token" was set to 'true'
+            // in the request.
+            token?: ClaimToken;
+        }
+        interface OutOfStockResponse {
+
+            // Product ID of an out-of-stock item
+            product_id: string;
+
+            // Requested quantity
+            requested_quantity: Integer;
+
+            // Available quantity (must be below requested_quanitity)
+            available_quantity: Integer;
+
+            // When do we expect the product to be again in stock?
+            // Optional, not given if unknown.
+            restock_expected?: Timestamp;
+        }
+
+        interface ForgetRequest {
+
+            // Array of valid JSON paths to forgettable fields in the order's
+            // contract terms.
+            fields: string[];
+        }
+        interface RefundRequest {
+            // Amount to be refunded
+            refund: Amount;
+
+            // Human-readable refund justification
+            reason: string;
+        }
+        interface MerchantRefundResponse {
+
+            // URL (handled by the backend) that the wallet should access to
+            // trigger refund processing.
+            // taler://refund/...
+            taler_refund_uri: string;
+
+            // Contract hash that a client may need to authenticate an
+            // HTTP request to obtain the above URI in a wallet-friendly way.
+            h_contract: HashCode;
+        }
+
+    }
+
+    namespace Tips {
+
+        // GET /private/reserves
+        interface TippingReserveStatus {
+            // Array of all known reserves (possibly empty!)
+            reserves: ReserveStatusEntry[];
+        }
+        interface ReserveStatusEntry {
+            // Public key of the reserve
+            reserve_pub: EddsaPublicKey;
+
+            // Timestamp when it was established
+            creation_time: Timestamp;
+
+            // Timestamp when it expires
+            expiration_time: Timestamp;
+
+            // Initial amount as per reserve creation call
+            merchant_initial_amount: Amount;
+
+            // Initial amount as per exchange, 0 if exchange did
+            // not confirm reserve creation yet.
+            exchange_initial_amount: Amount;
+
+            // Amount picked up so far.
+            pickup_amount: Amount;
+
+            // Amount approved for tips that exceeds the pickup_amount.
+            committed_amount: Amount;
+
+            // Is this reserve active (false if it was deleted but not purged)
+            active: boolean;
+        }
+
+        interface ReserveCreateRequest {
+            // Amount that the merchant promises to put into the reserve
+            initial_balance: Amount;
+
+            // Exchange the merchant intends to use for tipping
+            exchange_url: string;
+
+            // Desired wire method, for example "iban" or "x-taler-bank"
+            wire_method: string;
+        }
+        interface ReserveCreateConfirmation {
+            // Public key identifying the reserve
+            reserve_pub: EddsaPublicKey;
+
+            // Wire account of the exchange where to transfer the funds
+            payto_uri: string;
+        }
+        interface TipCreateRequest {
+            // Amount that the customer should be tipped
+            amount: Amount;
+
+            // Justification for giving the tip
+            justification: string;
+
+            // URL that the user should be directed to after tipping,
+            // will be included in the tip_token.
+            next_url: string;
+        }
+        interface TipCreateConfirmation {
+            // Unique tip identifier for the tip that was created.
+            tip_id: HashCode;
+
+            // taler://tip URI for the tip
+            taler_tip_uri: string;
+
+            // URL that will directly trigger processing
+            // the tip when the browser is redirected to it
+            tip_status_url: string;
+
+            // when does the tip expire
+            tip_expiration: Timestamp;
+        }
+
+        interface ReserveDetail {
+            // Timestamp when it was established.
+            creation_time: Timestamp;
+
+            // Timestamp when it expires.
+            expiration_time: Timestamp;
+
+            // Initial amount as per reserve creation call.
+            merchant_initial_amount: Amount;
+
+            // Initial amount as per exchange, 0 if exchange did
+            // not confirm reserve creation yet.
+            exchange_initial_amount: Amount;
+
+            // Amount picked up so far.
+            pickup_amount: Amount;
+
+            // Amount approved for tips that exceeds the pickup_amount.
+            committed_amount: Amount;
+
+            // Array of all tips created by this reserves (possibly empty!).
+            // Only present if asked for explicitly.
+            tips?: TipStatusEntry[];
+
+            // Is this reserve active (false if it was deleted but not purged)?
+            active: boolean;
+
+            // URI to use to fill the reserve, can be NULL
+            // if the reserve is inactive or was already filled
+            payto_uri: string;
+
+            // URL of the exchange hosting the reserve,
+            // NULL if the reserve is inactive
+            exchange_url: string;
+
+        }
+
+        interface TipStatusEntry {
+
+            // Unique identifier for the tip.
+            tip_id: HashCode;
+
+            // Total amount of the tip that can be withdrawn.
+            total_amount: Amount;
+
+            // Human-readable reason for why the tip was granted.
+            reason: string;
+        }
+
+        interface TipDetails {
+            // Amount that we authorized for this tip.
+            total_authorized: Amount;
+
+            // Amount that was picked up by the user already.
+            total_picked_up: Amount;
+
+            // Human-readable reason given when authorizing the tip.
+            reason: string;
+
+            // Timestamp indicating when the tip is set to expire (may be in 
the past).
+            expiration: Timestamp;
+
+            // Reserve public key from which the tip is funded.
+            reserve_pub: EddsaPublicKey;
+
+            // Array showing the pickup operations of the wallet (possibly 
empty!).
+            // Only present if asked for explicitly.
+            pickups?: PickupDetail[];
+        }
+        interface PickupDetail {
+            // Unique identifier for the pickup operation.
+            pickup_id: HashCode;
+
+            // Number of planchets involved.
+            num_planchets: Integer;
+
+            // Total amount requested for this pickup_id.
+            requested_amount: Amount;
+        }
+
+    }
+
+    namespace Transfers {
+
+        interface TransferList {
+            // list of all the transfers that fit the filter that we know
+            transfers: TransferDetails[];
+        }
+        interface TransferDetails {
+            // how much was wired to the merchant (minus fees)
+            credit_amount: Amount;
+
+            // raw wire transfer identifier identifying the wire transfer (a 
base32-encoded value)
+            wtid: string;
+
+            // target account that received the wire transfer
+            payto_uri: string;
+
+            // base URL of the exchange that made the wire transfer
+            exchange_url: string;
+
+            // Serial number identifying the transfer in the merchant backend.
+            // Used for filgering via offset.
+            transfer_serial_id: number;
+
+            // Time of the execution of the wire transfer by the exchange, 
according to the exchange
+            // Only provided if we did get an answer from the exchange.
+            execution_time?: Timestamp;
+
+            // True if we checked the exchange's answer and are happy with it.
+            // False if we have an answer and are unhappy, missing if we
+            // do not have an answer from the exchange.
+            verified?: boolean;
+
+            // True if the merchant uses the POST /transfers API to confirm
+            // that this wire transfer took place (and it is thus not
+            // something merely claimed by the exchange).
+            confirmed?: boolean;
+        }
+
+        interface TransferInformation {
+            // how much was wired to the merchant (minus fees)
+            credit_amount: Amount;
+
+            // raw wire transfer identifier identifying the wire transfer (a 
base32-encoded value)
+            wtid: WireTransferIdentifierRawP;
+
+            // target account that received the wire transfer
+            payto_uri: string;
+
+            // base URL of the exchange that made the wire transfer
+            exchange_url: string;
+        }
+        interface MerchantTrackTransferResponse {
+            // Total amount transferred
+            total: Amount;
+
+            // Applicable wire fee that was charged
+            wire_fee: Amount;
+
+            // Time of the execution of the wire transfer by the exchange, 
according to the exchange
+            execution_time: Timestamp;
+
+            // details about the deposits
+            deposits_sums: MerchantTrackTransferDetail[];
+        }
+        interface MerchantTrackTransferDetail {
+            // Business activity associated with the wire transferred amount
+            // deposit_value.
+            order_id: string;
+
+            // The total amount the exchange paid back for order_id.
+            deposit_value: Amount;
+
+            // applicable fees for the deposit
+            deposit_fee: Amount;
+        }
+
+        type ExchangeConflictDetails = WireFeeConflictDetails | 
TrackTransferConflictDetails
+        // Note: this is not the full 'proof' of missbehavior, as
+        // the bogus message from the exchange with a signature
+        // over the 'different' wire fee is missing.
+        //
+        // This information is NOT provided by the current implementation,
+        // because this would be quite expensive to generate and is
+        // hardly needed _here_. Once we add automated reports for
+        // the Taler auditor, we need to generate this data anyway
+        // and should probably return it here as well.
+        interface WireFeeConflictDetails {
+            // Numerical error code:
+            code: "TALER_EC_MERCHANT_PRIVATE_POST_TRANSFERS_BAD_WIRE_FEE";
+
+            // Text describing the issue for humans.
+            hint: string;
+
+
+            // Wire fee (wrongly) charged by the exchange, breaking the
+            // contract affirmed by the exchange_sig.
+            wire_fee: Amount;
+
+            // Timestamp of the wire transfer
+            execution_time: Timestamp;
+
+            // The expected wire fee (as signed by the exchange)
+            expected_wire_fee: Amount;
+
+            // Expected closing fee (needed to verify signature)
+            expected_closing_fee: Amount;
+
+            // Start date of the expected fee structure
+            start_date: Timestamp;
+
+            // End date of the expected fee structure
+            end_date: Timestamp;
+
+            // Signature of the exchange affirming the expected fee structure
+            master_sig: EddsaSignature;
+
+            // Master public key of the exchange
+            master_pub: EddsaPublicKey;
+        }
+        interface TrackTransferConflictDetails {
+            // Numerical error code
+            code: 
"TALER_EC_MERCHANT_PRIVATE_POST_TRANSFERS_CONFLICTING_REPORTS";
+
+            // Text describing the issue for humans.
+            hint: string;
+
+            // Offset in the exchange_transfer where the
+            // exchange's response fails to match the exchange_deposit_proof.
+            conflict_offset: number;
+
+            // The response from the exchange which tells us when the
+            // coin was returned to us, except that it does not match
+            // the expected value of the coin.
+            //
+            // This field is NOT provided by the current implementation,
+            // because this would be quite expensive to generate and is
+            // hardly needed _here_. Once we add automated reports for
+            // the Taler auditor, we need to generate this data anyway
+            // and should probably return it here as well.
+            // exchange_transfer?: TrackTransferResponse;
+
+            // Public key of the exchange used to sign the response to
+            // our deposit request.
+            deposit_exchange_pub: EddsaPublicKey;
+
+            // Signature of the exchange signing the (conflicting) response.
+            // Signs over a struct TALER_DepositConfirmationPS.
+            deposit_exchange_sig: EddsaSignature;
+
+            // Hash of the merchant's bank account the wire transfer went to
+            h_wire: HashCode;
+
+            // Hash of the contract terms with the conflicting deposit.
+            h_contract_terms: HashCode;
+
+            // At what time the exchange received the deposit.  Needed
+            // to verify the \exchange_sig\.
+            deposit_timestamp: Timestamp;
+
+            // At what time the refund possibility expired (needed to verify 
exchange_sig).
+            refund_deadline: Timestamp;
+
+            // Public key of the coin for which we have conflicting 
information.
+            coin_pub: EddsaPublicKey;
+
+            // Amount the exchange counted the coin for in the transfer.
+            amount_with_fee: Amount;
+
+            // Expected value of the coin.
+            coin_value: Amount;
+
+            // Expected deposit fee of the coin.
+            coin_fee: Amount;
+
+            // Expected deposit fee of the coin.
+            deposit_fee: Amount;
+
+        }
+
+        // interface TrackTransferProof {
+        //     // signature from the exchange made with purpose
+        //     // TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT
+        //     exchange_sig: EddsaSignature;
+
+        //     // public EdDSA key of the exchange that was used to generate 
the signature.
+        //     // Should match one of the exchange's signing keys from /keys.  
Again given
+        //     // explicitly as the client might otherwise be confused by 
clock skew as to
+        //     // which signing key was used.
+        //     exchange_pub: EddsaSignature;
+
+        //     // hash of the wire details (identical for all deposits)
+        //     // Needed to check the exchange_sig
+        //     h_wire: HashCode;
+        // }
+
+    }
+
+
+    interface ContractTerms {
+        // Human-readable description of the whole purchase
+        summary: string;
+
+        // Map from IETF BCP 47 language tags to localized summaries
+        summary_i18n?: { [lang_tag: string]: string };
+
+        // Unique, free-form identifier for the proposal.
+        // Must be unique within a merchant instance.
+        // For merchants that do not store proposals in their DB
+        // before the customer paid for them, the order_id can be used
+        // by the frontend to restore a proposal from the information
+        // encoded in it (such as a short product identifier and timestamp).
+        order_id: string;
+
+        // Total price for the transaction.
+        // The exchange will subtract deposit fees from that amount
+        // before transferring it to the merchant.
+        amount: Amount;
+
+        // The URL for this purchase.  Every time is is visited, the merchant
+        // will send back to the customer the same proposal.  Clearly, this URL
+        // can be bookmarked and shared by users.
+        fulfillment_url?: string;
+
+        // Maximum total deposit fee accepted by the merchant for this contract
+        max_fee: Amount;
+
+        // Maximum wire fee accepted by the merchant (customer share to be
+        // divided by the 'wire_fee_amortization' factor, and further reduced
+        // if deposit fees are below 'max_fee').  Default if missing is zero.
+        max_wire_fee: Amount;
+
+        // Over how many customer transactions does the merchant expect to
+        // amortize wire fees on average?  If the exchange's wire fee is
+        // above 'max_wire_fee', the difference is divided by this number
+        // to compute the expected customer's contribution to the wire fee.
+        // The customer's contribution may further be reduced by the difference
+        // between the 'max_fee' and the sum of the actual deposit fees.
+        // Optional, default value if missing is 1.  0 and negative values are
+        // invalid and also interpreted as 1.
+        wire_fee_amortization: number;
+
+        // List of products that are part of the purchase (see Product).
+        products: Product[];
+
+        // Time when this contract was generated
+        timestamp: TalerProtocolTimestamp;
+
+        // After this deadline has passed, no refunds will be accepted.
+        refund_deadline: TalerProtocolTimestamp;
+
+        // After this deadline, the merchant won't accept payments for the 
contact
+        pay_deadline: TalerProtocolTimestamp;
+
+        // Transfer deadline for the exchange.  Must be in the
+        // deposit permissions of coins used to pay for this order.
+        wire_transfer_deadline: TalerProtocolTimestamp;
+
+        // Merchant's public key used to sign this proposal; this information
+        // is typically added by the backend Note that this can be an 
ephemeral key.
+        merchant_pub: EddsaPublicKey;
+
+        // Base URL of the (public!) merchant backend API.
+        // Must be an absolute URL that ends with a slash.
+        merchant_base_url: string;
+
+        // More info about the merchant, see below
+        merchant: Merchant;
+
+        // The hash of the merchant instance's wire details.
+        h_wire: HashCode;
+
+        // Wire transfer method identifier for the wire method associated with 
h_wire.
+        // The wallet may only select exchanges via a matching auditor if the
+        // exchange also supports this wire method.
+        // The wire transfer fees must be added based on this wire transfer 
method.
+        wire_method: string;
+
+        // Any exchanges audited by these auditors are accepted by the 
merchant.
+        auditors: Auditor[];
+
+        // Exchanges that the merchant accepts even if it does not accept any 
auditors that audit them.
+        exchanges: Exchange[];
+
+        // Delivery location for (all!) products.
+        delivery_location?: Location;
+
+        // Time indicating when the order should be delivered.
+        // May be overwritten by individual products.
+        delivery_date?: TalerProtocolTimestamp;
+
+        // Nonce generated by the wallet and echoed by the merchant
+        // in this field when the proposal is generated.
+        nonce: string;
+
+        // Specifies for how long the wallet should try to get an
+        // automatic refund for the purchase. If this field is
+        // present, the wallet should wait for a few seconds after
+        // the purchase and then automatically attempt to obtain
+        // a refund.  The wallet should probe until "delay"
+        // after the payment was successful (i.e. via long polling
+        // or via explicit requests with exponential back-off).
+        //
+        // In particular, if the wallet is offline
+        // at that time, it MUST repeat the request until it gets
+        // one response from the merchant after the delay has expired.
+        // If the refund is granted, the wallet MUST automatically
+        // recover the payment.  This is used in case a merchant
+        // knows that it might be unable to satisfy the contract and
+        // desires for the wallet to attempt to get the refund without any
+        // customer interaction.  Note that it is NOT an error if the
+        // merchant does not grant a refund.
+        auto_refund?: RelativeTime;
+
+        // Extra data that is only interpreted by the merchant frontend.
+        // Useful when the merchant needs to store extra information on a
+        // contract without storing it separately in their database.
+        extra?: any;
+
+        // Minimum age buyer must have (in years). Default is 0.
+        minimum_age?: Integer;
+    }
+
+}
diff --git a/packages/merchant-backoffice-ui/src/hooks/async.ts 
b/packages/merchant-backoffice-ui/src/hooks/async.ts
new file mode 100644
index 000000000..fd550043b
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/hooks/async.ts
@@ -0,0 +1,76 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import { useState } from "preact/hooks";
+import { cancelPendingRequest } from "./backend";
+
+export interface Options {
+  slowTolerance: number,
+}
+
+export interface AsyncOperationApi<T> {
+  request: (...a: any) => void,
+  cancel: () => void,
+  data: T | undefined,
+  isSlow: boolean,
+  isLoading: boolean,
+  error: string | undefined
+}
+
+export function useAsync<T>(fn?: (...args: any) => Promise<T>, { 
slowTolerance: tooLong }: Options = { slowTolerance: 1000 }): 
AsyncOperationApi<T> {
+  const [data, setData] = useState<T | undefined>(undefined);
+  const [isLoading, setLoading] = useState<boolean>(false);
+  const [error, setError] = useState<any>(undefined);
+  const [isSlow, setSlow] = useState(false)
+
+  const request = async (...args: any) => {
+    if (!fn) return;
+    setLoading(true);
+
+    const handler = setTimeout(() => {
+      setSlow(true)
+    }, tooLong)
+
+    try {
+      const result = await fn(...args);
+      setData(result);
+    } catch (error) {
+      setError(error);
+    }
+    setLoading(false);
+    setSlow(false)
+    clearTimeout(handler)
+  };
+
+  function cancel() {
+    cancelPendingRequest()
+    setLoading(false);
+    setSlow(false)
+  }
+
+  return {
+    request,
+    cancel,
+    data,
+    isSlow,
+    isLoading,
+    error
+  };
+}
diff --git a/packages/merchant-backoffice-ui/src/hooks/backend.ts 
b/packages/merchant-backoffice-ui/src/hooks/backend.ts
new file mode 100644
index 000000000..789cfc81c
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/hooks/backend.ts
@@ -0,0 +1,319 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { useSWRConfig } from "swr";
+import axios, { AxiosError, AxiosResponse } from "axios";
+import { MerchantBackend } from "../declaration";
+import { useBackendContext } from "../context/backend";
+import { useEffect, useState } from "preact/hooks";
+import { DEFAULT_REQUEST_TIMEOUT } from "../utils/constants";
+import { axiosHandler, removeAxiosCancelToken } from 
"../utils/switchableAxios";
+
+export function useMatchMutate(): (
+  re: RegExp,
+  value?: unknown
+) => Promise<any> {
+  const { cache, mutate } = useSWRConfig();
+
+  if (!(cache instanceof Map)) {
+    throw new Error(
+      "matchMutate requires the cache provider to be a Map instance"
+    );
+  }
+
+  return function matchRegexMutate(re: RegExp, value?: unknown) {
+    const allKeys = Array.from(cache.keys());
+    // console.log(allKeys)
+    const keys = allKeys.filter((key) => re.test(key));
+    // console.log(allKeys.length, keys.length)
+    const mutations = keys.map((key) => {
+      // console.log(key)
+      mutate(key, value, true);
+    });
+    return Promise.all(mutations);
+  };
+}
+
+export type HttpResponse<T> =
+  | HttpResponseOk<T>
+  | HttpResponseLoading<T>
+  | HttpError;
+export type HttpResponsePaginated<T> =
+  | HttpResponseOkPaginated<T>
+  | HttpResponseLoading<T>
+  | HttpError;
+
+export interface RequestInfo {
+  url: string;
+  hasToken: boolean;
+  params: unknown;
+  data: unknown;
+  status: number;
+}
+
+interface HttpResponseLoading<T> {
+  ok?: false;
+  loading: true;
+  clientError?: false;
+  serverError?: false;
+
+  data?: T;
+}
+export interface HttpResponseOk<T> {
+  ok: true;
+  loading?: false;
+  clientError?: false;
+  serverError?: false;
+
+  data: T;
+  info?: RequestInfo;
+}
+
+export type HttpResponseOkPaginated<T> = HttpResponseOk<T> & WithPagination;
+
+export interface WithPagination {
+  loadMore: () => void;
+  loadMorePrev: () => void;
+  isReachingEnd?: boolean;
+  isReachingStart?: boolean;
+}
+
+export type HttpError =
+  | HttpResponseClientError
+  | HttpResponseServerError
+  | HttpResponseUnexpectedError;
+export interface SwrError {
+  info: unknown;
+  status: number;
+  message: string;
+}
+export interface HttpResponseServerError {
+  ok?: false;
+  loading?: false;
+  clientError?: false;
+  serverError: true;
+
+  error?: MerchantBackend.ErrorDetail;
+  status: number;
+  message: string;
+  info?: RequestInfo;
+}
+interface HttpResponseClientError {
+  ok?: false;
+  loading?: false;
+  clientError: true;
+  serverError?: false;
+
+  info?: RequestInfo;
+  isUnauthorized: boolean;
+  isNotfound: boolean;
+  status: number;
+  error?: MerchantBackend.ErrorDetail;
+  message: string;
+}
+
+interface HttpResponseUnexpectedError {
+  ok?: false;
+  loading?: false;
+  clientError?: false;
+  serverError?: false;
+
+  info?: RequestInfo;
+  status?: number;
+  error: unknown;
+  message: string;
+}
+
+type Methods = "get" | "post" | "patch" | "delete" | "put";
+
+interface RequestOptions {
+  method?: Methods;
+  token?: string;
+  data?: unknown;
+  params?: unknown;
+}
+
+function buildRequestOk<T>(
+  res: AxiosResponse<T>,
+  url: string,
+  hasToken: boolean
+): HttpResponseOk<T> {
+  return {
+    ok: true,
+    data: res.data,
+    info: {
+      params: res.config.params,
+      data: res.config.data,
+      url,
+      hasToken,
+      status: res.status,
+    },
+  };
+}
+
+// function buildResponse<T>(data?: T, error?: MerchantBackend.ErrorDetail, 
isValidating?: boolean): HttpResponse<T> {
+//   if (isValidating) return {loading: true}
+//   if (error) return buildRequestFailed()
+// }
+
+function buildRequestFailed(
+  ex: AxiosError<MerchantBackend.ErrorDetail>,
+  url: string,
+  hasToken: boolean
+):
+  | HttpResponseClientError
+  | HttpResponseServerError
+  | HttpResponseUnexpectedError {
+  const status = ex.response?.status;
+
+  const info: RequestInfo = {
+    data: ex.request?.data,
+    params: ex.request?.params,
+    url,
+    hasToken,
+    status: status || 0,
+  };
+
+  if (status && status >= 400 && status < 500) {
+    const error: HttpResponseClientError = {
+      clientError: true,
+      isNotfound: status === 404,
+      isUnauthorized: status === 401,
+      status,
+      info,
+      message: ex.response?.data?.hint || ex.message,
+      error: ex.response?.data,
+    };
+    return error;
+  }
+  if (status && status >= 500 && status < 600) {
+    const error: HttpResponseServerError = {
+      serverError: true,
+      status,
+      info,
+      message:
+        `${ex.response?.data?.hint} (code ${ex.response?.data?.code})` ||
+        ex.message,
+      error: ex.response?.data,
+    };
+    return error;
+  }
+
+  const error: HttpResponseUnexpectedError = {
+    info,
+    status,
+    error: ex,
+    message: ex.message,
+  };
+
+  return error;
+}
+
+const CancelToken = axios.CancelToken;
+let source = CancelToken.source();
+
+export function cancelPendingRequest(): void {
+  source.cancel("canceled by the user");
+  source = CancelToken.source();
+}
+
+export function isAxiosError<T>(
+  error: AxiosError | any
+): error is AxiosError<T> {
+  return error && error.isAxiosError;
+}
+
+export async function request<T>(
+  url: string,
+  options: RequestOptions = {}
+): Promise<HttpResponseOk<T>> {
+  const headers = options.token
+    ? { Authorization: `Bearer ${options.token}` }
+    : undefined;
+
+  try {
+    const res = await axiosHandler({
+      url,
+      responseType: "json",
+      headers,
+      cancelToken: !removeAxiosCancelToken ? source.token : undefined,
+      method: options.method || "get",
+      data: options.data,
+      params: options.params,
+      timeout: DEFAULT_REQUEST_TIMEOUT * 1000,
+    });
+    return buildRequestOk<T>(res, url, !!options.token);
+  } catch (e) {
+    if (isAxiosError<MerchantBackend.ErrorDetail>(e)) {
+      const error = buildRequestFailed(e, url, !!options.token);
+      throw error;
+    }
+    throw e;
+  }
+}
+
+export function multiFetcher<T>(
+  urls: string[],
+  token: string,
+  backend: string
+): Promise<HttpResponseOk<T>[]> {
+  return Promise.all(urls.map((url) => fetcher<T>(url, token, backend)));
+}
+
+export function fetcher<T>(
+  url: string,
+  token: string,
+  backend: string
+): Promise<HttpResponseOk<T>> {
+  return request<T>(`${backend}${url}`, { token });
+}
+
+export function useBackendInstancesTestForAdmin(): 
HttpResponse<MerchantBackend.Instances.InstancesResponse> {
+  const { url, token } = useBackendContext();
+
+  type Type = MerchantBackend.Instances.InstancesResponse;
+
+  const [result, setResult] = useState<HttpResponse<Type>>({ loading: true });
+
+  useEffect(() => {
+    request<Type>(`${url}/management/instances`, { token })
+      .then((data) => setResult(data))
+      .catch((error) => setResult(error));
+  }, [url, token]);
+
+  return result;
+}
+
+export function useBackendConfig(): 
HttpResponse<MerchantBackend.VersionResponse> {
+  const { url, token } = useBackendContext();
+
+  type Type = MerchantBackend.VersionResponse;
+
+  const [result, setResult] = useState<HttpResponse<Type>>({ loading: true });
+
+  useEffect(() => {
+    request<Type>(`${url}/config`, { token })
+      .then((data) => setResult(data))
+      .catch((error) => setResult(error));
+  }, [url, token]);
+
+  return result;
+}
diff --git a/packages/merchant-backoffice-ui/src/hooks/index.ts 
b/packages/merchant-backoffice-ui/src/hooks/index.ts
new file mode 100644
index 000000000..a647e3e6c
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/hooks/index.ts
@@ -0,0 +1,110 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { StateUpdater, useCallback, useState } from "preact/hooks";
+import { ValueOrFunction } from '../utils/types';
+
+
+const calculateRootPath = () => {
+  const rootPath = typeof window !== undefined ? window.location.origin + 
window.location.pathname : '/'
+  return rootPath
+}
+
+export function useBackendURL(url?: string): [string, boolean, 
StateUpdater<string>, () => void] {
+  const [value, setter] = useNotNullLocalStorage('backend-url', url || 
calculateRootPath())
+  const [triedToLog, setTriedToLog] = useLocalStorage('tried-login')
+
+  const checkedSetter = (v: ValueOrFunction<string>) => {
+    setTriedToLog('yes')
+    return setter(p => (v instanceof Function ? v(p) : v).replace(/\/$/, ''))
+  }
+
+  const resetBackend = () => {
+    setTriedToLog(undefined)
+  }
+  return [value, !!triedToLog, checkedSetter, resetBackend]
+}
+
+export function useBackendDefaultToken(initialValue?: string): [string | 
undefined, StateUpdater<string | undefined>] {
+  return useLocalStorage('backend-token', initialValue)
+}
+
+export function useBackendInstanceToken(id: string): [string | undefined, 
StateUpdater<string | undefined>] {
+  const [token, setToken] = useLocalStorage(`backend-token-${id}`)
+  const [defaultToken, defaultSetToken] = useBackendDefaultToken()
+
+  // instance named 'default' use the default token
+  if (id === 'default') {
+    return [defaultToken, defaultSetToken]
+  }
+
+  return [token, setToken]
+}
+
+export function useLang(initial?: string): [string, StateUpdater<string>] {
+  const browserLang = typeof window !== "undefined" ? navigator.language || 
(navigator as any).userLanguage : undefined;
+  const defaultLang = (browserLang || initial || 'en').substring(0, 2)
+  return useNotNullLocalStorage('lang-preference', defaultLang)
+}
+
+export function useLocalStorage(key: string, initialValue?: string): [string | 
undefined, StateUpdater<string | undefined>] {
+  const [storedValue, setStoredValue] = useState<string | undefined>((): 
string | undefined => {
+    return typeof window !== "undefined" ? window.localStorage.getItem(key) || 
initialValue : initialValue;
+  });
+
+  const setValue = (value?: string | ((val?: string) => string | undefined)) 
=> {
+    setStoredValue(p => {
+      const toStore = value instanceof Function ? value(p) : value
+      if (typeof window !== "undefined") {
+        if (!toStore) {
+          window.localStorage.removeItem(key)
+        } else {
+          window.localStorage.setItem(key, toStore);
+        }
+      }
+      return toStore
+    })
+  };
+
+  return [storedValue, setValue];
+}
+
+export function useNotNullLocalStorage(key: string, initialValue: string): 
[string, StateUpdater<string>] {
+  const [storedValue, setStoredValue] = useState<string>((): string => {
+    return typeof window !== "undefined" ? window.localStorage.getItem(key) || 
initialValue : initialValue;
+  });
+
+  const setValue = (value: string | ((val: string) => string)) => {
+    const valueToStore = value instanceof Function ? value(storedValue) : 
value;
+    setStoredValue(valueToStore);
+    if (typeof window !== "undefined") {
+      if (!valueToStore) {
+        window.localStorage.removeItem(key)
+      } else {
+        window.localStorage.setItem(key, valueToStore);
+      }
+    }
+  };
+
+  return [storedValue, setValue];
+}
+
+
diff --git a/packages/merchant-backoffice-ui/src/hooks/instance.ts 
b/packages/merchant-backoffice-ui/src/hooks/instance.ts
new file mode 100644
index 000000000..748bb82af
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/hooks/instance.ts
@@ -0,0 +1,292 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+import useSWR, { useSWRConfig } from "swr";
+import { useBackendContext } from "../context/backend";
+import { useInstanceContext } from "../context/instance";
+import { MerchantBackend } from "../declaration";
+import {
+  fetcher,
+  HttpError,
+  HttpResponse,
+  HttpResponseOk,
+  request,
+  useMatchMutate,
+} from "./backend";
+
+interface InstanceAPI {
+  updateInstance: (
+    data: MerchantBackend.Instances.InstanceReconfigurationMessage
+  ) => Promise<void>;
+  deleteInstance: () => Promise<void>;
+  clearToken: () => Promise<void>;
+  setNewToken: (token: string) => Promise<void>;
+}
+
+export function useAdminAPI(): AdminAPI {
+  const { url, token } = useBackendContext();
+  const mutateAll = useMatchMutate();
+
+  const createInstance = async (
+    instance: MerchantBackend.Instances.InstanceConfigurationMessage
+  ): Promise<void> => {
+    await request(`${url}/management/instances`, {
+      method: "post",
+      token,
+      data: instance,
+    });
+
+    mutateAll(/\/management\/instances/);
+  };
+
+  const deleteInstance = async (id: string): Promise<void> => {
+    await request(`${url}/management/instances/${id}`, {
+      method: "delete",
+      token,
+    });
+
+    mutateAll(/\/management\/instances/);
+  };
+
+  const purgeInstance = async (id: string): Promise<void> => {
+    await request(`${url}/management/instances/${id}`, {
+      method: "delete",
+      token,
+      params: {
+        purge: "YES",
+      },
+    });
+
+    mutateAll(/\/management\/instances/);
+  };
+
+  return { createInstance, deleteInstance, purgeInstance };
+}
+
+export interface AdminAPI {
+  createInstance: (
+    data: MerchantBackend.Instances.InstanceConfigurationMessage
+  ) => Promise<void>;
+  deleteInstance: (id: string) => Promise<void>;
+  purgeInstance: (id: string) => Promise<void>;
+}
+
+export function useManagementAPI(instanceId: string): InstanceAPI {
+  const mutateAll = useMatchMutate();
+  const { url, token, updateLoginStatus } = useBackendContext();
+
+  const updateInstance = async (
+    instance: MerchantBackend.Instances.InstanceReconfigurationMessage
+  ): Promise<void> => {
+    await request(`${url}/management/instances/${instanceId}`, {
+      method: "patch",
+      token,
+      data: instance,
+    });
+
+    mutateAll(/\/management\/instances/);
+  };
+
+  const deleteInstance = async (): Promise<void> => {
+    await request(`${url}/management/instances/${instanceId}`, {
+      method: "delete",
+      token,
+    });
+
+    mutateAll(/\/management\/instances/);
+  };
+
+  const clearToken = async (): Promise<void> => {
+    await request(`${url}/management/instances/${instanceId}/auth`, {
+      method: "post",
+      token,
+      data: { method: "external" },
+    });
+
+    mutateAll(/\/management\/instances/);
+  };
+
+  const setNewToken = async (newToken: string): Promise<void> => {
+    await request(`${url}/management/instances/${instanceId}/auth`, {
+      method: "post",
+      token,
+      data: { method: "token", token: newToken },
+    });
+
+    updateLoginStatus(url, newToken)
+    mutateAll(/\/management\/instances/);
+  };
+
+  return { updateInstance, deleteInstance, setNewToken, clearToken };
+}
+
+export function useInstanceAPI(): InstanceAPI {
+  const { mutate } = useSWRConfig();
+  const { url: baseUrl, token: adminToken, updateLoginStatus } = 
useBackendContext();
+  const { token: instanceToken, id, admin } = useInstanceContext();
+
+  const { url, token } = !admin
+    ? { url: baseUrl, token: adminToken }
+    : { url: `${baseUrl}/instances/${id}`, token: instanceToken };
+
+  const updateInstance = async (
+    instance: MerchantBackend.Instances.InstanceReconfigurationMessage
+  ): Promise<void> => {
+    await request(`${url}/private/`, {
+      method: "patch",
+      token,
+      data: instance,
+    });
+
+    if (adminToken) mutate(["/private/instances", adminToken, baseUrl], null);
+    mutate([`/private/`, token, url], null);
+  };
+
+  const deleteInstance = async (): Promise<void> => {
+    await request(`${url}/private/`, {
+      method: "delete",
+      token: adminToken,
+    });
+
+    if (adminToken) mutate(["/private/instances", adminToken, baseUrl], null);
+    mutate([`/private/`, token, url], null);
+  };
+
+  const clearToken = async (): Promise<void> => {
+    await request(`${url}/private/auth`, {
+      method: "post",
+      token,
+      data: { method: "external" },
+    });
+
+    mutate([`/private/`, token, url], null);
+  };
+
+  const setNewToken = async (newToken: string): Promise<void> => {
+    await request(`${url}/private/auth`, {
+      method: "post",
+      token,
+      data: { method: "token", token: newToken },
+    });
+
+    updateLoginStatus(baseUrl, newToken)
+    mutate([`/private/`, token, url], null);
+  };
+
+  return { updateInstance, deleteInstance, setNewToken, clearToken };
+}
+
+export function useInstanceDetails(): 
HttpResponse<MerchantBackend.Instances.QueryInstancesResponse> {
+  const { url: baseUrl, token: baseToken } = useBackendContext();
+  const { token: instanceToken, id, admin } = useInstanceContext();
+
+  const { url, token } = !admin
+    ? { url: baseUrl, token: baseToken }
+    : { url: `${baseUrl}/instances/${id}`, token: instanceToken };
+
+  const { data, error, isValidating } = useSWR<
+    HttpResponseOk<MerchantBackend.Instances.QueryInstancesResponse>,
+    HttpError
+  >([`/private/`, token, url], fetcher, {
+    refreshInterval: 0,
+    refreshWhenHidden: false,
+    revalidateOnFocus: false,
+    revalidateOnReconnect: false,
+    refreshWhenOffline: false,
+    errorRetryCount: 0,
+    errorRetryInterval: 1,
+    shouldRetryOnError: false,
+  });
+
+  if (isValidating) return { loading: true, data: data?.data };
+  if (data) return data;
+  if (error) return error;
+  return { loading: true };
+}
+
+type KYCStatus =
+  | { type: "ok" }
+  | { type: "redirect"; status: MerchantBackend.Instances.AccountKycRedirects 
};
+
+export function useInstanceKYCDetails(): HttpResponse<KYCStatus> {
+  const { url: baseUrl, token: baseToken } = useBackendContext();
+  const { token: instanceToken, id, admin } = useInstanceContext();
+
+  const { url, token } = !admin
+    ? { url: baseUrl, token: baseToken }
+    : { url: `${baseUrl}/instances/${id}`, token: instanceToken };
+
+  const { data, error } = useSWR<
+    HttpResponseOk<MerchantBackend.Instances.AccountKycRedirects>,
+    HttpError
+  >([`/private/kyc`, token, url], fetcher, {
+    refreshInterval: 5000,
+    refreshWhenHidden: false,
+    revalidateOnFocus: false,
+    revalidateOnReconnect: false,
+    refreshWhenOffline: false,
+    errorRetryCount: 0,
+    errorRetryInterval: 1,
+    shouldRetryOnError: false,
+  });
+
+  if (data) {
+    if (data.info?.status === 202)
+      return { ok: true, data: { type: "redirect", status: data.data } };
+    return { ok: true, data: { type: "ok" } };
+  }
+  if (error) return error;
+  return { loading: true };
+}
+
+export function useManagedInstanceDetails(
+  instanceId: string
+): HttpResponse<MerchantBackend.Instances.QueryInstancesResponse> {
+  const { url, token } = useBackendContext();
+
+  const { data, error, isValidating } = useSWR<
+    HttpResponseOk<MerchantBackend.Instances.QueryInstancesResponse>,
+    HttpError
+  >([`/management/instances/${instanceId}`, token, url], fetcher, {
+    refreshInterval: 0,
+    refreshWhenHidden: false,
+    revalidateOnFocus: false,
+    revalidateOnReconnect: false,
+    refreshWhenOffline: false,
+    errorRetryCount: 0,
+    errorRetryInterval: 1,
+    shouldRetryOnError: false,
+  });
+
+  if (isValidating) return { loading: true, data: data?.data };
+  if (data) return data;
+  if (error) return error;
+  return { loading: true };
+}
+
+export function useBackendInstances(): 
HttpResponse<MerchantBackend.Instances.InstancesResponse> {
+  const { url } = useBackendContext();
+  const { token } = useInstanceContext();
+
+  const { data, error, isValidating } = useSWR<
+    HttpResponseOk<MerchantBackend.Instances.InstancesResponse>,
+    HttpError
+  >(["/management/instances", token, url], fetcher);
+
+  if (isValidating) return { loading: true, data: data?.data };
+  if (data) return data;
+  if (error) return error;
+  return { loading: true };
+}
diff --git a/packages/merchant-backoffice-ui/src/hooks/listener.ts 
b/packages/merchant-backoffice-ui/src/hooks/listener.ts
new file mode 100644
index 000000000..e7e3327b7
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/hooks/listener.ts
@@ -0,0 +1,81 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { useState } from "preact/hooks";
+
+/**
+ * This component is used when a component wants one child to have a trigger 
for
+ * an action (a button) and other child have the action implemented (like
+ * gathering information with a form). The difference with other approaches is
+ * that in this case the parent component is not holding the state.
+ * 
+ * It will return a subscriber and activator. 
+ * 
+ * The activator may be undefined, if it is undefined it is indicating that the
+ * subscriber is not ready to be called.
+ *
+ * The subscriber will receive a function (the listener) that will be call 
when the
+ * activator runs. The listener must return the collected information.
+ * 
+ * As a result, when the activator is triggered by a child component, the
+ * @action function is called receives the information from the listener 
defined by other
+ * child component 
+ *
+ * @param action from <T> to <R>
+ * @returns activator and subscriber, undefined activator means that there is 
not subscriber
+ */
+
+export function useListener<T, R = any>(action: (r: T) => Promise<R>): 
[undefined | (() => Promise<R>), (listener?: () => T) => void] {
+  type RunnerHandler = { toBeRan?: () => Promise<R>; };
+  const [state, setState] = useState<RunnerHandler>({});
+
+  /**
+   * subscriber will receive a method that will be call when the activator runs
+   *
+   * @param listener function to be run when the activator runs
+   */
+  const subscriber = (listener?: () => T) => {
+    if (listener) {
+      setState({
+        toBeRan: () => {
+          const whatWeGetFromTheListener = listener();
+          return action(whatWeGetFromTheListener);
+        }
+      });
+    } else {
+      setState({
+        toBeRan: undefined
+      })
+    }
+  };
+
+  /**
+   * activator will call runner if there is someone subscribed
+   */
+  const activator = state.toBeRan ? async () => {
+    if (state.toBeRan) {
+      return state.toBeRan();
+    }
+    return Promise.reject();
+  } : undefined;
+
+  return [activator, subscriber];
+}
diff --git a/packages/merchant-backoffice-ui/src/hooks/notifications.ts 
b/packages/merchant-backoffice-ui/src/hooks/notifications.ts
new file mode 100644
index 000000000..1c0c37308
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/hooks/notifications.ts
@@ -0,0 +1,48 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { useState } from "preact/hooks";
+import { Notification } from '../utils/types';
+
+interface Result {
+  notifications: Notification[];
+  pushNotification: (n: Notification) => void;
+  removeNotification: (n: Notification) => void;
+}
+
+type NotificationWithDate = Notification & { since: Date }
+
+export function useNotifications(initial: Notification[] = [], timeout = 
3000): Result {
+  const [notifications, setNotifications] = 
useState<(NotificationWithDate)[]>(initial.map(i => ({...i, since: new Date() 
})))
+
+  const pushNotification = (n: Notification): void => {
+    const entry = { ...n, since: new Date() }
+    setNotifications(ns => [...ns, entry])
+    if (n.type !== 'ERROR') setTimeout(() => {
+      setNotifications(ns => ns.filter(x => x.since !== entry.since))
+    }, timeout)
+  }
+
+  const removeNotification = (notif: Notification) => {
+    setNotifications((ns: NotificationWithDate[]) => ns.filter(n => n !== 
notif))
+  }
+  return { notifications, pushNotification, removeNotification }
+}
diff --git a/packages/merchant-backoffice-ui/src/hooks/order.ts 
b/packages/merchant-backoffice-ui/src/hooks/order.ts
new file mode 100644
index 000000000..d0829683d
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/hooks/order.ts
@@ -0,0 +1,323 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+import { useEffect, useState } from "preact/hooks";
+import useSWR, { useSWRConfig } from "swr";
+import { useBackendContext } from "../context/backend";
+import { useInstanceContext } from "../context/instance";
+import { MerchantBackend } from "../declaration";
+import { MAX_RESULT_SIZE, PAGE_SIZE } from "../utils/constants";
+import {
+  fetcher,
+  HttpError,
+  HttpResponse,
+  HttpResponseOk,
+  HttpResponsePaginated,
+  request,
+  useMatchMutate,
+} from "./backend";
+
+export interface OrderAPI {
+  //FIXME: add OutOfStockResponse on 410
+  createOrder: (
+    data: MerchantBackend.Orders.PostOrderRequest
+  ) => Promise<HttpResponseOk<MerchantBackend.Orders.PostOrderResponse>>;
+  forgetOrder: (
+    id: string,
+    data: MerchantBackend.Orders.ForgetRequest
+  ) => Promise<HttpResponseOk<void>>;
+  refundOrder: (
+    id: string,
+    data: MerchantBackend.Orders.RefundRequest
+  ) => Promise<HttpResponseOk<MerchantBackend.Orders.MerchantRefundResponse>>;
+  deleteOrder: (id: string) => Promise<HttpResponseOk<void>>;
+  getPaymentURL: (id: string) => Promise<HttpResponseOk<string>>;
+}
+
+type YesOrNo = "yes" | "no";
+
+export function orderFetcher<T>(
+  url: string,
+  token: string,
+  backend: string,
+  paid?: YesOrNo,
+  refunded?: YesOrNo,
+  wired?: YesOrNo,
+  searchDate?: Date,
+  delta?: number
+): Promise<HttpResponseOk<T>> {
+  const date_ms =
+    delta && delta < 0 && searchDate
+      ? searchDate.getTime() + 1
+      : searchDate?.getTime();
+  const params: any = {};
+  if (paid !== undefined) params.paid = paid;
+  if (delta !== undefined) params.delta = delta;
+  if (refunded !== undefined) params.refunded = refunded;
+  if (wired !== undefined) params.wired = wired;
+  if (date_ms !== undefined) params.date_ms = date_ms;
+  return request<T>(`${backend}${url}`, { token, params });
+}
+
+export function useOrderAPI(): OrderAPI {
+  const mutateAll = useMatchMutate();
+  const { url: baseUrl, token: adminToken } = useBackendContext();
+  const { token: instanceToken, id, admin } = useInstanceContext();
+
+  const { url, token } = !admin
+    ? {
+      url: baseUrl,
+      token: adminToken,
+    }
+    : {
+      url: `${baseUrl}/instances/${id}`,
+      token: instanceToken,
+    };
+
+  const createOrder = async (
+    data: MerchantBackend.Orders.PostOrderRequest
+  ): Promise<HttpResponseOk<MerchantBackend.Orders.PostOrderResponse>> => {
+    const res = await request<MerchantBackend.Orders.PostOrderResponse>(
+      `${url}/private/orders`,
+      {
+        method: "post",
+        token,
+        data,
+      }
+    );
+    await mutateAll(/.*private\/orders.*/);
+    // mutate('')
+    return res;
+  };
+  const refundOrder = async (
+    orderId: string,
+    data: MerchantBackend.Orders.RefundRequest
+  ): Promise<HttpResponseOk<MerchantBackend.Orders.MerchantRefundResponse>> => 
{
+    mutateAll(/@"\/private\/orders"@/);
+    const res = request<MerchantBackend.Orders.MerchantRefundResponse>(
+      `${url}/private/orders/${orderId}/refund`,
+      {
+        method: "post",
+        token,
+        data,
+      }
+    );
+
+    // order list returns refundable information, so we must evict everything
+    await mutateAll(/.*private\/orders.*/);
+    return res
+  };
+
+  const forgetOrder = async (
+    orderId: string,
+    data: MerchantBackend.Orders.ForgetRequest
+  ): Promise<HttpResponseOk<void>> => {
+    mutateAll(/@"\/private\/orders"@/);
+    const res = request<void>(`${url}/private/orders/${orderId}/forget`, {
+      method: "patch",
+      token,
+      data,
+    });
+    // we may be forgetting some fields that are pare of the listing, so we 
must evict everything
+    await mutateAll(/.*private\/orders.*/);
+    return res
+  };
+  const deleteOrder = async (
+    orderId: string
+  ): Promise<HttpResponseOk<void>> => {
+    mutateAll(/@"\/private\/orders"@/);
+    const res = request<void>(`${url}/private/orders/${orderId}`, {
+      method: "delete",
+      token,
+    });
+    await mutateAll(/.*private\/orders.*/);
+    return res
+  };
+
+  const getPaymentURL = async (
+    orderId: string
+  ): Promise<HttpResponseOk<string>> => {
+    return request<MerchantBackend.Orders.MerchantOrderStatusResponse>(
+      `${url}/private/orders/${orderId}`,
+      {
+        method: "get",
+        token,
+      }
+    ).then((res) => {
+      const url =
+        res.data.order_status === "unpaid"
+          ? res.data.taler_pay_uri
+          : res.data.contract_terms.fulfillment_url;
+      const response: HttpResponseOk<string> = res as any;
+      response.data = url || "";
+      return response;
+    });
+  };
+
+  return { createOrder, forgetOrder, deleteOrder, refundOrder, getPaymentURL };
+}
+
+export function useOrderDetails(
+  oderId: string
+): HttpResponse<MerchantBackend.Orders.MerchantOrderStatusResponse> {
+  const { url: baseUrl, token: baseToken } = useBackendContext();
+  const { token: instanceToken, id, admin } = useInstanceContext();
+
+  const { url, token } = !admin
+    ? { url: baseUrl, token: baseToken, }
+    : { url: `${baseUrl}/instances/${id}`, token: instanceToken, };
+
+  const { data, error, isValidating } = useSWR<
+    HttpResponseOk<MerchantBackend.Orders.MerchantOrderStatusResponse>,
+    HttpError
+  >([`/private/orders/${oderId}`, token, url], fetcher, {
+    refreshInterval: 0,
+    refreshWhenHidden: false,
+    revalidateOnFocus: false,
+    revalidateOnReconnect: false,
+    refreshWhenOffline: false,
+  });
+
+  if (isValidating) return { loading: true, data: data?.data };
+  if (data) return data;
+  if (error) return error;
+  return { loading: true };
+}
+
+export interface InstanceOrderFilter {
+  paid?: YesOrNo;
+  refunded?: YesOrNo;
+  wired?: YesOrNo;
+  date?: Date;
+}
+
+export function useInstanceOrders(
+  args?: InstanceOrderFilter,
+  updateFilter?: (d: Date) => void
+): HttpResponsePaginated<MerchantBackend.Orders.OrderHistory> {
+  const { url: baseUrl, token: baseToken } = useBackendContext();
+  const { token: instanceToken, id, admin } = useInstanceContext();
+
+  const { url, token } = !admin
+    ? { url: baseUrl, token: baseToken, }
+    : { url: `${baseUrl}/instances/${id}`, token: instanceToken, };
+
+  const [pageBefore, setPageBefore] = useState(1);
+  const [pageAfter, setPageAfter] = useState(1);
+
+  const totalAfter = pageAfter * PAGE_SIZE;
+  const totalBefore = args?.date ? pageBefore * PAGE_SIZE : 0;
+
+  /**
+   * FIXME: this can be cleaned up a little
+   *
+   * the logic of double query should be inside the orderFetch so from the 
hook perspective and cache
+   * is just one query and one error status
+   */
+  const {
+    data: beforeData,
+    error: beforeError,
+    isValidating: loadingBefore,
+  } = useSWR<HttpResponseOk<MerchantBackend.Orders.OrderHistory>, HttpError>(
+    [
+      `/private/orders`,
+      token,
+      url,
+      args?.paid,
+      args?.refunded,
+      args?.wired,
+      args?.date,
+      totalBefore,
+    ],
+    orderFetcher
+  );
+  const {
+    data: afterData,
+    error: afterError,
+    isValidating: loadingAfter,
+  } = useSWR<HttpResponseOk<MerchantBackend.Orders.OrderHistory>, HttpError>(
+    [
+      `/private/orders`,
+      token,
+      url,
+      args?.paid,
+      args?.refunded,
+      args?.wired,
+      args?.date,
+      -totalAfter,
+    ],
+    orderFetcher
+  );
+
+  //this will save last result
+  const [lastBefore, setLastBefore] = useState<
+    HttpResponse<MerchantBackend.Orders.OrderHistory>
+  >({ loading: true });
+  const [lastAfter, setLastAfter] = useState<
+    HttpResponse<MerchantBackend.Orders.OrderHistory>
+  >({ loading: true });
+  useEffect(() => {
+    if (afterData) setLastAfter(afterData);
+    if (beforeData) setLastBefore(beforeData);
+  }, [afterData, beforeData]);
+
+  if (beforeError) return beforeError;
+  if (afterError) return afterError;
+
+  // if the query returns less that we ask, then we have reach the end or 
beginning
+  const isReachingEnd = afterData && afterData.data.orders.length < totalAfter;
+  const isReachingStart = args?.date === undefined ||
+    (beforeData && beforeData.data.orders.length < totalBefore);
+
+  const pagination = {
+    isReachingEnd,
+    isReachingStart,
+    loadMore: () => {
+      if (!afterData || isReachingEnd) return;
+      if (afterData.data.orders.length < MAX_RESULT_SIZE) {
+        setPageAfter(pageAfter + 1);
+      } else {
+        const from =
+          afterData.data.orders[afterData.data.orders.length - 1].timestamp
+            .t_s;
+        if (from && from !== "never" && updateFilter) updateFilter(new 
Date(from * 1000));
+      }
+    },
+    loadMorePrev: () => {
+      if (!beforeData || isReachingStart) return;
+      if (beforeData.data.orders.length < MAX_RESULT_SIZE) {
+        setPageBefore(pageBefore + 1);
+      } else if (beforeData) {
+        const from =
+          beforeData.data.orders[beforeData.data.orders.length - 1].timestamp
+            .t_s;
+        if (from && from !== "never" && updateFilter) updateFilter(new 
Date(from * 1000));
+      }
+    },
+  };
+
+  const orders =
+    !beforeData || !afterData
+      ? []
+      : (beforeData || lastBefore).data.orders
+        .slice()
+        .reverse()
+        .concat((afterData || lastAfter).data.orders);
+  if (loadingAfter || loadingBefore) return { loading: true, data: { orders } 
};
+  if (beforeData && afterData) {
+    return { ok: true, data: { orders }, ...pagination };
+  }
+  return { loading: true };
+}
diff --git a/packages/merchant-backoffice-ui/src/hooks/product.ts 
b/packages/merchant-backoffice-ui/src/hooks/product.ts
new file mode 100644
index 000000000..c99542bc9
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/hooks/product.ts
@@ -0,0 +1,187 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+import useSWR, { useSWRConfig } from "swr";
+import { useBackendContext } from "../context/backend";
+import { useInstanceContext } from "../context/instance";
+import { MerchantBackend, WithId } from "../declaration";
+import {
+  fetcher,
+  HttpError,
+  HttpResponse,
+  HttpResponseOk,
+  multiFetcher,
+  request,
+  useMatchMutate
+} from "./backend";
+
+export interface ProductAPI {
+  createProduct: (
+    data: MerchantBackend.Products.ProductAddDetail
+  ) => Promise<void>;
+  updateProduct: (
+    id: string,
+    data: MerchantBackend.Products.ProductPatchDetail
+  ) => Promise<void>;
+  deleteProduct: (id: string) => Promise<void>;
+  lockProduct: (
+    id: string,
+    data: MerchantBackend.Products.LockRequest
+  ) => Promise<void>;
+}
+
+export function useProductAPI(): ProductAPI {
+  const mutateAll = useMatchMutate();
+  const { mutate } = useSWRConfig();
+  const { url: baseUrl, token: adminToken } = useBackendContext();
+  const { token: instanceToken, id, admin } = useInstanceContext();
+
+  const { url, token } = !admin
+    ? { url: baseUrl, token: adminToken, }
+    : { url: `${baseUrl}/instances/${id}`, token: instanceToken, };
+
+  const createProduct = async (
+    data: MerchantBackend.Products.ProductAddDetail
+  ): Promise<void> => {
+    const res = await request(`${url}/private/products`, {
+      method: "post",
+      token,
+      data,
+    });
+
+    return await mutateAll(/.*"\/private\/products.*/);
+  };
+
+  const updateProduct = async (
+    productId: string,
+    data: MerchantBackend.Products.ProductPatchDetail
+  ): Promise<void> => {
+    const r = await request(`${url}/private/products/${productId}`, {
+      method: "patch",
+      token,
+      data,
+    });
+
+    return await mutateAll(/.*"\/private\/products.*/);
+  };
+
+  const deleteProduct = async (productId: string): Promise<void> => {
+    await request(`${url}/private/products/${productId}`, {
+      method: "delete",
+      token,
+    });
+    await mutate([`/private/products`, token, url]);
+  };
+
+  const lockProduct = async (
+    productId: string,
+    data: MerchantBackend.Products.LockRequest
+  ): Promise<void> => {
+    await request(`${url}/private/products/${productId}/lock`, {
+      method: "post",
+      token,
+      data,
+    });
+
+    return await mutateAll(/.*"\/private\/products.*/);
+  };
+
+  return { createProduct, updateProduct, deleteProduct, lockProduct };
+}
+
+export function useInstanceProducts(): HttpResponse<
+  (MerchantBackend.Products.ProductDetail & WithId)[]
+> {
+  const { url: baseUrl, token: baseToken } = useBackendContext();
+  const { token: instanceToken, id, admin } = useInstanceContext();
+
+  const { url, token } = !admin
+    ? { url: baseUrl, token: baseToken, }
+    : { url: `${baseUrl}/instances/${id}`, token: instanceToken, };
+
+  const { data: list, error: listError } = useSWR<
+    HttpResponseOk<MerchantBackend.Products.InventorySummaryResponse>,
+    HttpError
+  >([`/private/products`, token, url], fetcher, {
+    refreshInterval: 0,
+    refreshWhenHidden: false,
+    revalidateOnFocus: false,
+    revalidateOnReconnect: false,
+    refreshWhenOffline: false,
+  });
+
+  const paths = (list?.data.products || []).map(
+    (p) => `/private/products/${p.product_id}`
+  );
+  const { data: products, error: productError } = useSWR<
+    HttpResponseOk<MerchantBackend.Products.ProductDetail>[],
+    HttpError
+  >([paths, token, url], multiFetcher, {
+    refreshInterval: 0,
+    refreshWhenHidden: false,
+    revalidateOnFocus: false,
+    revalidateOnReconnect: false,
+    refreshWhenOffline: false,
+  });
+
+
+  if (listError) return listError;
+  if (productError) return productError;
+
+  if (products) {
+    const dataWithId = products.map((d) => {
+      //take the id from the queried url
+      return {
+        ...d.data,
+        id: d.info?.url.replace(/.*\/private\/products\//, "") || "",
+      };
+    });
+    return { ok: true, data: dataWithId };
+  }
+  return { loading: true };
+}
+
+export function useProductDetails(
+  productId: string
+): HttpResponse<MerchantBackend.Products.ProductDetail> {
+  const { url: baseUrl, token: baseToken } = useBackendContext();
+  const { token: instanceToken, id, admin } = useInstanceContext();
+
+  const { url, token } = !admin
+    ? {
+      url: baseUrl,
+      token: baseToken,
+    }
+    : {
+      url: `${baseUrl}/instances/${id}`,
+      token: instanceToken,
+    };
+
+  const { data, error, isValidating } = useSWR<
+    HttpResponseOk<MerchantBackend.Products.ProductDetail>,
+    HttpError
+  >([`/private/products/${productId}`, token, url], fetcher, {
+    refreshInterval: 0,
+    refreshWhenHidden: false,
+    revalidateOnFocus: false,
+    revalidateOnReconnect: false,
+    refreshWhenOffline: false,
+  });
+
+  if (isValidating) return { loading: true, data: data?.data };
+  if (data) return data;
+  if (error) return error;
+  return { loading: true };
+}
diff --git a/packages/merchant-backoffice-ui/src/hooks/reserves.ts 
b/packages/merchant-backoffice-ui/src/hooks/reserves.ts
new file mode 100644
index 000000000..7a662dfbc
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/hooks/reserves.ts
@@ -0,0 +1,218 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+import useSWR, { useSWRConfig } from "swr";
+import { useBackendContext } from "../context/backend";
+import { useInstanceContext } from "../context/instance";
+import { MerchantBackend } from "../declaration";
+import {
+  fetcher,
+  HttpError,
+  HttpResponse,
+  HttpResponseOk,
+  request,
+  useMatchMutate,
+} from "./backend";
+
+export function useReservesAPI(): ReserveMutateAPI {
+  const mutateAll = useMatchMutate();
+  const { mutate } = useSWRConfig();
+  const { url: baseUrl, token: adminToken } = useBackendContext();
+  const { token: instanceToken, id, admin } = useInstanceContext();
+
+  const { url, token } = !admin
+    ? { url: baseUrl, token: adminToken, }
+    : { url: `${baseUrl}/instances/${id}`, token: instanceToken, };
+
+  const createReserve = async (
+    data: MerchantBackend.Tips.ReserveCreateRequest
+  ): Promise<
+    HttpResponseOk<MerchantBackend.Tips.ReserveCreateConfirmation>
+  > => {
+    const res = await request<MerchantBackend.Tips.ReserveCreateConfirmation>(
+      `${url}/private/reserves`,
+      {
+        method: "post",
+        token,
+        data,
+      }
+    );
+
+    //evict reserve list query
+    await mutateAll(/.*private\/reserves.*/);
+
+    return res;
+  };
+
+  const authorizeTipReserve = async (
+    pub: string,
+    data: MerchantBackend.Tips.TipCreateRequest
+  ): Promise<HttpResponseOk<MerchantBackend.Tips.TipCreateConfirmation>> => {
+    const res = await request<MerchantBackend.Tips.TipCreateConfirmation>(
+      `${url}/private/reserves/${pub}/authorize-tip`,
+      {
+        method: "post",
+        token,
+        data,
+      }
+    );
+
+    //evict reserve details query
+    await mutate([`/private/reserves/${pub}`, token, url]);
+
+    return res;
+  };
+
+  const authorizeTip = async (
+    data: MerchantBackend.Tips.TipCreateRequest
+  ): Promise<HttpResponseOk<MerchantBackend.Tips.TipCreateConfirmation>> => {
+    const res = await request<MerchantBackend.Tips.TipCreateConfirmation>(
+      `${url}/private/tips`,
+      {
+        method: "post",
+        token,
+        data,
+      }
+    );
+
+    //evict all details query
+    await mutateAll(/.*private\/reserves\/.*/);
+
+    return res;
+  };
+
+  const deleteReserve = async (pub: string): Promise<HttpResponse<void>> => {
+    const res = await request<void>(`${url}/private/reserves/${pub}`, {
+      method: "delete",
+      token,
+    });
+
+    //evict reserve list query
+    await mutateAll(/.*private\/reserves.*/);
+
+    return res;
+  };
+
+  return { createReserve, authorizeTip, authorizeTipReserve, deleteReserve };
+}
+
+export interface ReserveMutateAPI {
+  createReserve: (
+    data: MerchantBackend.Tips.ReserveCreateRequest
+  ) => Promise<HttpResponseOk<MerchantBackend.Tips.ReserveCreateConfirmation>>;
+  authorizeTipReserve: (
+    id: string,
+    data: MerchantBackend.Tips.TipCreateRequest
+  ) => Promise<HttpResponseOk<MerchantBackend.Tips.TipCreateConfirmation>>;
+  authorizeTip: (
+    data: MerchantBackend.Tips.TipCreateRequest
+  ) => Promise<HttpResponseOk<MerchantBackend.Tips.TipCreateConfirmation>>;
+  deleteReserve: (id: string) => Promise<HttpResponse<void>>;
+}
+
+export function useInstanceReserves(): 
HttpResponse<MerchantBackend.Tips.TippingReserveStatus> {
+  const { url: baseUrl, token: baseToken } = useBackendContext();
+  const { token: instanceToken, id, admin } = useInstanceContext();
+
+  const { url, token } = !admin
+    ? { url: baseUrl, token: baseToken, }
+    : { url: `${baseUrl}/instances/${id}`, token: instanceToken, };
+
+  const { data, error, isValidating } = useSWR<
+    HttpResponseOk<MerchantBackend.Tips.TippingReserveStatus>,
+    HttpError
+  >([`/private/reserves`, token, url], fetcher);
+
+  if (isValidating) return { loading: true, data: data?.data };
+  if (data) return data;
+  if (error) return error;
+  return { loading: true };
+}
+
+export function useReserveDetails(
+  reserveId: string
+): HttpResponse<MerchantBackend.Tips.ReserveDetail> {
+  const { url: baseUrl } = useBackendContext();
+  const { token, id: instanceId, admin } = useInstanceContext();
+
+  const url = !admin ? baseUrl : `${baseUrl}/instances/${instanceId}`;
+
+  const { data, error, isValidating } = useSWR<
+    HttpResponseOk<MerchantBackend.Tips.ReserveDetail>,
+    HttpError
+  >([`/private/reserves/${reserveId}`, token, url], reserveDetailFetcher, {
+    refreshInterval: 0,
+    refreshWhenHidden: false,
+    revalidateOnFocus: false,
+    revalidateOnReconnect: false,
+    refreshWhenOffline: false,
+  });
+
+  if (isValidating) return { loading: true, data: data?.data };
+  if (data) return data;
+  if (error) return error;
+  return { loading: true };
+}
+
+export function useTipDetails(
+  tipId: string
+): HttpResponse<MerchantBackend.Tips.TipDetails> {
+  const { url: baseUrl } = useBackendContext();
+  const { token, id: instanceId, admin } = useInstanceContext();
+
+  const url = !admin ? baseUrl : `${baseUrl}/instances/${instanceId}`;
+
+  const { data, error, isValidating } = useSWR<
+    HttpResponseOk<MerchantBackend.Tips.TipDetails>,
+    HttpError
+  >([`/private/tips/${tipId}`, token, url], tipsDetailFetcher, {
+    refreshInterval: 0,
+    refreshWhenHidden: false,
+    revalidateOnFocus: false,
+    revalidateOnReconnect: false,
+    refreshWhenOffline: false,
+  });
+
+  if (isValidating) return { loading: true, data: data?.data };
+  if (data) return data;
+  if (error) return error;
+  return { loading: true };
+}
+
+function reserveDetailFetcher<T>(
+  url: string,
+  token: string,
+  backend: string
+): Promise<HttpResponseOk<T>> {
+  return request<T>(`${backend}${url}`, {
+    token,
+    params: {
+      tips: "yes",
+    },
+  });
+}
+
+function tipsDetailFetcher<T>(
+  url: string,
+  token: string,
+  backend: string
+): Promise<HttpResponseOk<T>> {
+  return request<T>(`${backend}${url}`, {
+    token,
+    params: {
+      pickups: "yes",
+    },
+  });
+}
diff --git a/packages/merchant-backoffice-ui/src/hooks/transfer.ts 
b/packages/merchant-backoffice-ui/src/hooks/transfer.ts
new file mode 100644
index 000000000..0c12d6d4d
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/hooks/transfer.ts
@@ -0,0 +1,217 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+import { MerchantBackend } from "../declaration";
+import { useBackendContext } from "../context/backend";
+import {
+  request,
+  HttpResponse,
+  HttpError,
+  HttpResponseOk,
+  HttpResponsePaginated,
+  useMatchMutate,
+} from "./backend";
+import useSWR from "swr";
+import { useInstanceContext } from "../context/instance";
+import { MAX_RESULT_SIZE, PAGE_SIZE } from "../utils/constants";
+import { useEffect, useState } from "preact/hooks";
+
+async function transferFetcher<T>(
+  url: string,
+  token: string,
+  backend: string,
+  payto_uri?: string,
+  verified?: string,
+  position?: string,
+  delta?: number
+): Promise<HttpResponseOk<T>> {
+  const params: any = {};
+  if (payto_uri !== undefined) params.payto_uri = payto_uri;
+  if (verified !== undefined) params.verified = verified;
+  if (delta !== undefined) {
+    params.limit = delta;
+  }
+  if (position !== undefined) params.offset = position;
+
+  return request<T>(`${backend}${url}`, { token, params });
+}
+
+export function useTransferAPI(): TransferAPI {
+  const mutateAll = useMatchMutate();
+  const { url: baseUrl, token: adminToken } = useBackendContext();
+  const { token: instanceToken, id, admin } = useInstanceContext();
+
+  const { url, token } = !admin
+    ? {
+      url: baseUrl,
+      token: adminToken,
+    }
+    : {
+      url: `${baseUrl}/instances/${id}`,
+      token: instanceToken,
+    };
+
+  const informTransfer = async (
+    data: MerchantBackend.Transfers.TransferInformation
+  ): Promise<
+    HttpResponseOk<MerchantBackend.Transfers.MerchantTrackTransferResponse>
+  > => {
+    const res = await 
request<MerchantBackend.Transfers.MerchantTrackTransferResponse>(
+      `${url}/private/transfers`, {
+      method: "post",
+      token,
+      data,
+    });
+
+    await mutateAll(/.*private\/transfers.*/);
+    return res
+  };
+
+  return { informTransfer };
+}
+
+export interface TransferAPI {
+  informTransfer: (
+    data: MerchantBackend.Transfers.TransferInformation
+  ) => Promise<
+    HttpResponseOk<MerchantBackend.Transfers.MerchantTrackTransferResponse>
+  >;
+}
+
+export interface InstanceTransferFilter {
+  payto_uri?: string;
+  verified?: "yes" | "no";
+  position?: string;
+}
+
+export function useInstanceTransfers(
+  args?: InstanceTransferFilter,
+  updatePosition?: (id: string) => void
+): HttpResponsePaginated<MerchantBackend.Transfers.TransferList> {
+  const { url: baseUrl, token: baseToken } = useBackendContext();
+  const { token: instanceToken, id, admin } = useInstanceContext();
+
+  const { url, token } = !admin
+    ? { url: baseUrl, token: baseToken }
+    : { url: `${baseUrl}/instances/${id}`, token: instanceToken };
+
+  const [pageBefore, setPageBefore] = useState(1);
+  const [pageAfter, setPageAfter] = useState(1);
+
+  const totalAfter = pageAfter * PAGE_SIZE;
+  const totalBefore = args?.position !== undefined ? pageBefore * PAGE_SIZE : 
0;
+
+  /**
+   * FIXME: this can be cleaned up a little
+   *
+   * the logic of double query should be inside the orderFetch so from the 
hook perspective and cache
+   * is just one query and one error status
+   */
+  const {
+    data: beforeData,
+    error: beforeError,
+    isValidating: loadingBefore,
+  } = useSWR<HttpResponseOk<MerchantBackend.Transfers.TransferList>, 
HttpError>(
+    [
+      `/private/transfers`,
+      token,
+      url,
+      args?.payto_uri,
+      args?.verified,
+      args?.position,
+      totalBefore,
+    ],
+    transferFetcher
+  );
+  const {
+    data: afterData,
+    error: afterError,
+    isValidating: loadingAfter,
+  } = useSWR<HttpResponseOk<MerchantBackend.Transfers.TransferList>, 
HttpError>(
+    [
+      `/private/transfers`,
+      token,
+      url,
+      args?.payto_uri,
+      args?.verified,
+      args?.position,
+      -totalAfter,
+    ],
+    transferFetcher
+  );
+
+  //this will save last result
+  const [lastBefore, setLastBefore] = useState<
+    HttpResponse<MerchantBackend.Transfers.TransferList>
+  >({ loading: true });
+  const [lastAfter, setLastAfter] = useState<
+    HttpResponse<MerchantBackend.Transfers.TransferList>
+  >({ loading: true });
+  useEffect(() => {
+    if (afterData) setLastAfter(afterData);
+    if (beforeData) setLastBefore(beforeData);
+  }, [afterData, beforeData]);
+
+  if (beforeError) return beforeError;
+  if (afterError) return afterError;
+
+  // if the query returns less that we ask, then we have reach the end or 
beginning
+  const isReachingEnd = afterData && afterData.data.transfers.length < 
totalAfter;
+  const isReachingStart = args?.position === undefined ||
+    (beforeData && beforeData.data.transfers.length < totalBefore);
+
+  const pagination = {
+    isReachingEnd,
+    isReachingStart,
+    loadMore: () => {
+      if (!afterData || isReachingEnd) return;
+      if (afterData.data.transfers.length < MAX_RESULT_SIZE) {
+        setPageAfter(pageAfter + 1);
+      } else {
+        const from =
+          `${afterData.data
+            .transfers[afterData.data.transfers.length - 1]
+            .transfer_serial_id}`;
+        if (from && updatePosition) updatePosition(from);
+      }
+    },
+    loadMorePrev: () => {
+      if (!beforeData || isReachingStart) return;
+      if (beforeData.data.transfers.length < MAX_RESULT_SIZE) {
+        setPageBefore(pageBefore + 1);
+      } else if (beforeData) {
+        const from =
+          `${beforeData.data
+            .transfers[beforeData.data.transfers.length - 1]
+            .transfer_serial_id}`;
+        if (from && updatePosition) updatePosition(from);
+      }
+    },
+  };
+
+  const transfers =
+    !beforeData || !afterData
+      ? []
+      : (beforeData || lastBefore).data.transfers
+        .slice()
+        .reverse()
+        .concat((afterData || lastAfter).data.transfers);
+  if (loadingAfter || loadingBefore)
+    return { loading: true, data: { transfers } };
+  if (beforeData && afterData) {
+    return { ok: true, data: { transfers }, ...pagination };
+  }
+  return { loading: true };
+}
diff --git a/packages/merchant-backoffice-ui/src/i18n/de.po 
b/packages/merchant-backoffice-ui/src/i18n/de.po
new file mode 100644
index 000000000..6b35bd0ce
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/i18n/de.po
@@ -0,0 +1,1057 @@
+# This file is part of TALER
+# (C) 2016 GNUnet e.V.
+#
+# TALER is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3, or (at your option) any later version.
+#
+# TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Taler Wallet\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2016-11-23 00:00+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: src/ApplicationReadyRoutes.tsx:50 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:299
+#, c-format
+msgid "Access denied"
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:51 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:300
+#, c-format
+msgid "Check your token is valid"
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:72
+#, c-format
+msgid "Couldn't access the server."
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:73
+#, c-format
+msgid "Could not infer instance id from url %1$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:109
+#, c-format
+msgid "HTTP status #%1$s: Server reported a problem"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:110
+#, c-format
+msgid "Got message: \"%1$s\" from: %2$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:127
+#, c-format
+msgid "No default instance"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:128
+#, c-format
+msgid ""
+"in order to use merchant backoffice, you should create the default instance"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:288
+#, c-format
+msgid "Server reported a problem: HTTP status #%1$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:289
+#, c-format
+msgid "Got message: %1$s from: %2$s"
+msgstr ""
+
+#: src/components/exception/login.tsx:46
+#, c-format
+msgid "Login required"
+msgstr ""
+
+#: src/components/exception/login.tsx:49
+#, c-format
+msgid ""
+"Please enter your auth token. Token should have \"secret-token:\" and start "
+"with Bearer or ApiKey"
+msgstr ""
+
+#: src/components/exception/login.tsx:86 src/components/modal/index.tsx:53
+#: src/components/modal/index.tsx:75 src/paths/admin/create/CreatePage.tsx:115
+#: src/paths/instance/orders/create/CreatePage.tsx:325
+#: src/paths/instance/products/create/CreatePage.tsx:51
+#: src/paths/instance/products/list/Table.tsx:174
+#: src/paths/instance/products/list/Table.tsx:228
+#: src/paths/instance/products/update/UpdatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:134
+#, c-format
+msgid "Confirm"
+msgstr ""
+
+#: src/components/form/InputArray.tsx:72
+#, c-format
+msgid "The value %1$s is invalid for a payment url"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:67
+#: src/paths/instance/orders/list/index.tsx:123
+#, c-format
+msgid "pick a date"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:81
+#, c-format
+msgid "clear"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:83
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "never"
+msgstr ""
+
+#: src/components/form/InputImage.tsx:80
+#, c-format
+msgid "Image should be smaller than 1 MB"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:28
+#, c-format
+msgid "Country"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:30
+#: src/paths/admin/create/CreatePage.tsx:99
+#: src/paths/instance/transfers/list/Table.tsx:124
+#: src/paths/instance/update/UpdatePage.tsx:118
+#, c-format
+msgid "Address"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:34
+#, c-format
+msgid "Building number"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:35
+#, c-format
+msgid "Building name"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:36
+#, c-format
+msgid "Street"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:37
+#, c-format
+msgid "Post code"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:38
+#, c-format
+msgid "Town location"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:39
+#, c-format
+msgid "Town"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:40
+#, c-format
+msgid "District"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:41
+#, c-format
+msgid "Country subdivision"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:59
+#, c-format
+msgid "Product id"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:60
+#: src/components/product/ProductForm.tsx:99
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:122
+#: src/paths/instance/orders/list/Table.tsx:227
+#: src/paths/instance/products/list/Table.tsx:86
+#, c-format
+msgid "Description"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:73
+#: src/components/form/InputTaxes.tsx:81
+#: src/paths/admin/create/CreatePage.tsx:87 src/paths/admin/list/Table.tsx:110
+#: src/paths/instance/details/DetailPage.tsx:76
+#: src/paths/instance/update/UpdatePage.tsx:106
+#, c-format
+msgid "Name"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:102
+#, c-format
+msgid "loading..."
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:108
+#, c-format
+msgid "no products found"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:116
+#, c-format
+msgid "no results"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:33
+#, c-format
+msgid "Deleting"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:34
+#, c-format
+msgid "Changing"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:60
+#, c-format
+msgid "Manage token"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:83
+#, c-format
+msgid "Update"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:100
+#: src/paths/instance/orders/create/CreatePage.tsx:252
+#: src/paths/instance/orders/create/CreatePage.tsx:273
+#, c-format
+msgid "Remove"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:106 src/components/modal/index.tsx:52
+#: src/components/modal/index.tsx:73 src/paths/admin/create/CreatePage.tsx:114
+#: src/paths/instance/orders/create/CreatePage.tsx:324
+#: src/paths/instance/products/create/CreatePage.tsx:50
+#: src/paths/instance/products/list/Table.tsx:166
+#: src/paths/instance/products/list/Table.tsx:218
+#: src/paths/instance/products/update/UpdatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:88
+#: src/paths/instance/update/UpdatePage.tsx:133
+#, c-format
+msgid "Cancel"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:91
+#, c-format
+msgid "Manage stock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:93
+#, c-format
+msgid "Infinite"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:105
+#, c-format
+msgid "lost cannot be greater that current + incoming (max %1$s)"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:111
+#, c-format
+msgid "current stock will change from %1$s to %2$s"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:112
+#, c-format
+msgid "current stock will stay at %1$s"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:129
+#: src/paths/instance/products/list/Table.tsx:204
+#, c-format
+msgid "Incoming"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:130
+#: src/paths/instance/products/list/Table.tsx:205
+#, c-format
+msgid "Lost"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:142
+#, c-format
+msgid "Current"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:145
+#, c-format
+msgid "without stock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:150
+#, c-format
+msgid "Next restock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:152
+#, c-format
+msgid "Delivery address"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:73
+#, c-format
+msgid "this product has no taxes"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:77
+#: src/paths/instance/orders/details/DetailPage.tsx:145
+#: src/paths/instance/orders/details/DetailPage.tsx:296
+#: src/paths/instance/orders/list/Table.tsx:116
+#: src/paths/instance/transfers/create/CreatePage.tsx:84
+#, c-format
+msgid "Amount"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:78
+#, c-format
+msgid "currency and value separated with colon"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:84
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:78
+#, c-format
+msgid "Add"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:53
+#, c-format
+msgid "Instance"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:59
+#, c-format
+msgid "Settings"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:65
+#: src/paths/instance/orders/list/Table.tsx:60
+#, c-format
+msgid "Orders"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:71
+#: src/paths/instance/orders/create/CreatePage.tsx:258
+#: src/paths/instance/products/list/Table.tsx:48
+#, c-format
+msgid "Products"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:77
+#: src/paths/instance/transfers/list/Table.tsx:65
+#, c-format
+msgid "Transfers"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:87
+#, c-format
+msgid "Connection"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:112 src/paths/admin/list/Table.tsx:57
+#, c-format
+msgid "Instances"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:116
+#, c-format
+msgid "New"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:122
+#, c-format
+msgid "List"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:129
+#, c-format
+msgid "Log out"
+msgstr ""
+
+#: src/components/modal/index.tsx:74
+#, c-format
+msgid "Clear"
+msgstr ""
+
+#: src/components/modal/index.tsx:110 src/components/modal/index.tsx:111
+#, c-format
+msgid "should be the same"
+msgstr ""
+
+#: src/components/modal/index.tsx:111
+#, c-format
+msgid "cannot be the same as before"
+msgstr ""
+
+#: src/components/modal/index.tsx:114
+#, c-format
+msgid ""
+"You are updating the authorization token from instance %1$s with id %2$s"
+msgstr ""
+
+#: src/components/modal/index.tsx:124
+#, c-format
+msgid "Old token"
+msgstr ""
+
+#: src/components/modal/index.tsx:125
+#, c-format
+msgid "New token"
+msgstr ""
+
+#: src/components/modal/index.tsx:127
+#, c-format
+msgid "Clearing the auth token will mean public access to the instance"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:96
+#: src/paths/admin/create/CreatePage.tsx:85 src/paths/admin/list/Table.tsx:109
+#: src/paths/instance/transfers/list/Table.tsx:122
+#, c-format
+msgid "ID"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:98
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:121
+#: src/paths/instance/products/list/Table.tsx:85
+#, c-format
+msgid "Image"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:100
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:123
+#, c-format
+msgid "Unit"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:101
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:124
+#: src/paths/instance/products/list/Table.tsx:162
+#: src/paths/instance/products/list/Table.tsx:214
+#, c-format
+msgid "Price"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:103
+#: src/paths/instance/products/list/Table.tsx:90
+#, c-format
+msgid "Stock"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:105
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:128
+#: src/paths/instance/products/list/Table.tsx:88
+#, c-format
+msgid "Taxes"
+msgstr ""
+
+#: src/index.tsx:75
+#, c-format
+msgid "Server not found"
+msgstr ""
+
+#: src/index.tsx:85
+#, c-format
+msgid "Couldn't access the server"
+msgstr ""
+
+#: src/index.tsx:87 src/index.tsx:99
+#, c-format
+msgid "Got message %1$s from %2$s"
+msgstr ""
+
+#: src/index.tsx:97
+#, c-format
+msgid "Unexpected Error"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:108
+#, c-format
+msgid "Auth token"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:91
+#: src/paths/instance/details/DetailPage.tsx:77
+#: src/paths/instance/update/UpdatePage.tsx:110
+#, c-format
+msgid "Account address"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:93
+#: src/paths/instance/update/UpdatePage.tsx:112
+#, c-format
+msgid "Default max deposit fee"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:95
+#: src/paths/instance/update/UpdatePage.tsx:114
+#, c-format
+msgid "Default max wire fee"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:97
+#: src/paths/instance/update/UpdatePage.tsx:116
+#, c-format
+msgid "Default wire fee amortization"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:103
+#: src/paths/instance/update/UpdatePage.tsx:122
+#, c-format
+msgid "Jurisdiction"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:107
+#: src/paths/instance/update/UpdatePage.tsx:126
+#, c-format
+msgid "Default pay delay"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:109
+#: src/paths/instance/update/UpdatePage.tsx:128
+#, c-format
+msgid "Default wire transfer delay"
+msgstr ""
+
+#: src/paths/admin/create/index.tsx:58
+#, c-format
+msgid "could not create instance"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:63 src/paths/admin/list/Table.tsx:131
+#: src/paths/instance/transfers/list/Table.tsx:71
+#, c-format
+msgid "Delete"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:128
+#, c-format
+msgid "Edit"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:149
+#: src/paths/instance/products/list/Table.tsx:245
+#, c-format
+msgid "There is no instances yet, add more pressing the + sign"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:237
+#, c-format
+msgid "Inventory products"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:286
+#, c-format
+msgid "Total price"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:287
+#, c-format
+msgid "Total tax"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:289
+#: src/paths/instance/orders/create/CreatePage.tsx:297
+#, c-format
+msgid "Order price"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:295
+#, c-format
+msgid "Net"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:300
+#: src/paths/instance/orders/details/DetailPage.tsx:144
+#: src/paths/instance/orders/details/DetailPage.tsx:295
+#: src/paths/instance/orders/list/Table.tsx:117
+#, c-format
+msgid "Summary"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:302
+#, c-format
+msgid "Payments options"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:303
+#, c-format
+msgid "Auto refund deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:304
+#, c-format
+msgid "Refund deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:305
+#, c-format
+msgid "Pay deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:307
+#, c-format
+msgid "Delivery date"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:308
+#, c-format
+msgid "Location"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:312
+#, c-format
+msgid "Max fee"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:313
+#, c-format
+msgid "Max wire fee"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:314
+#, c-format
+msgid "Wire fee amortization"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:315
+#, c-format
+msgid "Fullfilment url"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:318
+#, c-format
+msgid "Extra information"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:44
+#, c-format
+msgid "select a product first"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:51
+#, c-format
+msgid "should be greater than 0"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:58
+#, c-format
+msgid ""
+"cannot be greater than current stock and quantity previously added. max: %1$s"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:64
+#, c-format
+msgid "cannot be greater than current stock %1$s"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:76
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:126
+#, c-format
+msgid "Quantity"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:92
+#: src/paths/instance/orders/details/DetailPage.tsx:235
+#: src/paths/instance/orders/details/DetailPage.tsx:333
+#, c-format
+msgid "Order"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:93
+#, c-format
+msgid "claimed"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:110
+#: src/paths/instance/orders/details/DetailPage.tsx:261
+#: src/paths/instance/orders/list/Table.tsx:136
+#, c-format
+msgid "copy url"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:126
+#: src/paths/instance/orders/details/DetailPage.tsx:349
+#, c-format
+msgid "pay at"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:127
+#: src/paths/instance/orders/details/DetailPage.tsx:350
+#, c-format
+msgid "created at"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:138
+#: src/paths/instance/orders/details/DetailPage.tsx:289
+#, c-format
+msgid "Timeline"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:142
+#: src/paths/instance/orders/details/DetailPage.tsx:293
+#, c-format
+msgid "Payment details"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:146
+#: src/paths/instance/orders/details/DetailPage.tsx:299
+#: src/paths/instance/orders/details/DetailPage.tsx:363
+#, c-format
+msgid "Order status"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:156
+#: src/paths/instance/orders/details/DetailPage.tsx:308
+#, c-format
+msgid "Product list"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:236
+#, c-format
+msgid "paid"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:238
+#, c-format
+msgid "wired"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:241
+#, c-format
+msgid "refunded"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:258
+#, c-format
+msgid "refund"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:297
+#, c-format
+msgid "Refunded amount"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:298
+#, c-format
+msgid "Deposit total"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:336
+#, c-format
+msgid "unpaid"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:364
+#, c-format
+msgid "Order status URL"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:365
+#, c-format
+msgid "Pay URI"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:383
+#, c-format
+msgid ""
+"Unknown order status. This is an error, please contact the administrator."
+msgstr ""
+
+#: src/paths/instance/orders/details/index.tsx:56
+#: src/paths/instance/orders/list/index.tsx:147
+#, c-format
+msgid "refund created successfully"
+msgstr ""
+
+#: src/paths/instance/orders/details/index.tsx:59
+#: src/paths/instance/orders/list/index.tsx:150
+#, c-format
+msgid "could not create the refund"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:111
+#, c-format
+msgid "load newer orders"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:115
+#, c-format
+msgid "Date"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:131
+#: src/paths/instance/orders/list/Table.tsx:223
+#, c-format
+msgid "Refund"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:145
+#, c-format
+msgid "load older orders"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:154
+#, c-format
+msgid "No orders has been found"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:202
+#, c-format
+msgid "date"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:203
+#, c-format
+msgid "amount"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:204
+#, c-format
+msgid "reason"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:224
+#, c-format
+msgid "Max refundable:"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "Reason"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "duplicated"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "requested by the customer"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "other"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:91
+#, c-format
+msgid "go to order id"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:107
+#, c-format
+msgid "Paid"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:108
+#, c-format
+msgid "Refunded"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:109
+#, c-format
+msgid "Not wired"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:110
+#, c-format
+msgid "All"
+msgstr ""
+
+#: src/paths/instance/products/create/index.tsx:48
+#: src/paths/instance/products/update/index.tsx:64
+#, c-format
+msgid "could not create product"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:87
+#, c-format
+msgid "Sell"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:89
+#, c-format
+msgid "Profit"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:91
+#, c-format
+msgid "Sold"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:59
+#, c-format
+msgid "product updated successfully"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:62
+#, c-format
+msgid "could not update the product"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:70
+#, c-format
+msgid "product delete successfully"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:73
+#, c-format
+msgid "could not delete the product"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:59
+#, c-format
+msgid "Tips"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:111
+#, c-format
+msgid "Committed amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:112
+#, c-format
+msgid "Exchange initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:113
+#, c-format
+msgid "Merchant initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:148
+#, c-format
+msgid "There is no tips yet, add more pressing the + sign"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:50
+#: src/paths/instance/transfers/create/CreatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:56
+#, c-format
+msgid "cannot be empty"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:51
+#, c-format
+msgid "check the id, doest look valid"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:52
+#, c-format
+msgid "should have 52 characters, current %1$s"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:57
+#, c-format
+msgid "URL doesn't have the right format"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:74
+#, c-format
+msgid "Transfer ID"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:76
+#, c-format
+msgid "Account Address"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:82
+#: src/paths/instance/transfers/list/Table.tsx:125
+#, c-format
+msgid "Exchange URL"
+msgstr ""
+
+#: src/paths/instance/transfers/create/index.tsx:49
+#, c-format
+msgid "could not inform transfer"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:118
+#, c-format
+msgid "load newer transfers"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:123
+#, c-format
+msgid "Credit"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:126
+#, c-format
+msgid "Confirmed"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:127
+#: src/paths/instance/transfers/list/index.tsx:60
+#, c-format
+msgid "Verified"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:128
+#, c-format
+msgid "Executed at"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "yes"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "no"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "unknown"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:145
+#, c-format
+msgid "load older transfers"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:154
+#, c-format
+msgid "There is no transfer yet, add more pressing the + sign"
+msgstr ""
diff --git a/packages/merchant-backoffice-ui/src/i18n/en.po 
b/packages/merchant-backoffice-ui/src/i18n/en.po
new file mode 100644
index 000000000..6b35bd0ce
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/i18n/en.po
@@ -0,0 +1,1057 @@
+# This file is part of TALER
+# (C) 2016 GNUnet e.V.
+#
+# TALER is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3, or (at your option) any later version.
+#
+# TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Taler Wallet\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2016-11-23 00:00+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: src/ApplicationReadyRoutes.tsx:50 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:299
+#, c-format
+msgid "Access denied"
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:51 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:300
+#, c-format
+msgid "Check your token is valid"
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:72
+#, c-format
+msgid "Couldn't access the server."
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:73
+#, c-format
+msgid "Could not infer instance id from url %1$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:109
+#, c-format
+msgid "HTTP status #%1$s: Server reported a problem"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:110
+#, c-format
+msgid "Got message: \"%1$s\" from: %2$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:127
+#, c-format
+msgid "No default instance"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:128
+#, c-format
+msgid ""
+"in order to use merchant backoffice, you should create the default instance"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:288
+#, c-format
+msgid "Server reported a problem: HTTP status #%1$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:289
+#, c-format
+msgid "Got message: %1$s from: %2$s"
+msgstr ""
+
+#: src/components/exception/login.tsx:46
+#, c-format
+msgid "Login required"
+msgstr ""
+
+#: src/components/exception/login.tsx:49
+#, c-format
+msgid ""
+"Please enter your auth token. Token should have \"secret-token:\" and start "
+"with Bearer or ApiKey"
+msgstr ""
+
+#: src/components/exception/login.tsx:86 src/components/modal/index.tsx:53
+#: src/components/modal/index.tsx:75 src/paths/admin/create/CreatePage.tsx:115
+#: src/paths/instance/orders/create/CreatePage.tsx:325
+#: src/paths/instance/products/create/CreatePage.tsx:51
+#: src/paths/instance/products/list/Table.tsx:174
+#: src/paths/instance/products/list/Table.tsx:228
+#: src/paths/instance/products/update/UpdatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:134
+#, c-format
+msgid "Confirm"
+msgstr ""
+
+#: src/components/form/InputArray.tsx:72
+#, c-format
+msgid "The value %1$s is invalid for a payment url"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:67
+#: src/paths/instance/orders/list/index.tsx:123
+#, c-format
+msgid "pick a date"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:81
+#, c-format
+msgid "clear"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:83
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "never"
+msgstr ""
+
+#: src/components/form/InputImage.tsx:80
+#, c-format
+msgid "Image should be smaller than 1 MB"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:28
+#, c-format
+msgid "Country"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:30
+#: src/paths/admin/create/CreatePage.tsx:99
+#: src/paths/instance/transfers/list/Table.tsx:124
+#: src/paths/instance/update/UpdatePage.tsx:118
+#, c-format
+msgid "Address"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:34
+#, c-format
+msgid "Building number"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:35
+#, c-format
+msgid "Building name"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:36
+#, c-format
+msgid "Street"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:37
+#, c-format
+msgid "Post code"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:38
+#, c-format
+msgid "Town location"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:39
+#, c-format
+msgid "Town"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:40
+#, c-format
+msgid "District"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:41
+#, c-format
+msgid "Country subdivision"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:59
+#, c-format
+msgid "Product id"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:60
+#: src/components/product/ProductForm.tsx:99
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:122
+#: src/paths/instance/orders/list/Table.tsx:227
+#: src/paths/instance/products/list/Table.tsx:86
+#, c-format
+msgid "Description"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:73
+#: src/components/form/InputTaxes.tsx:81
+#: src/paths/admin/create/CreatePage.tsx:87 src/paths/admin/list/Table.tsx:110
+#: src/paths/instance/details/DetailPage.tsx:76
+#: src/paths/instance/update/UpdatePage.tsx:106
+#, c-format
+msgid "Name"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:102
+#, c-format
+msgid "loading..."
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:108
+#, c-format
+msgid "no products found"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:116
+#, c-format
+msgid "no results"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:33
+#, c-format
+msgid "Deleting"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:34
+#, c-format
+msgid "Changing"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:60
+#, c-format
+msgid "Manage token"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:83
+#, c-format
+msgid "Update"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:100
+#: src/paths/instance/orders/create/CreatePage.tsx:252
+#: src/paths/instance/orders/create/CreatePage.tsx:273
+#, c-format
+msgid "Remove"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:106 src/components/modal/index.tsx:52
+#: src/components/modal/index.tsx:73 src/paths/admin/create/CreatePage.tsx:114
+#: src/paths/instance/orders/create/CreatePage.tsx:324
+#: src/paths/instance/products/create/CreatePage.tsx:50
+#: src/paths/instance/products/list/Table.tsx:166
+#: src/paths/instance/products/list/Table.tsx:218
+#: src/paths/instance/products/update/UpdatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:88
+#: src/paths/instance/update/UpdatePage.tsx:133
+#, c-format
+msgid "Cancel"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:91
+#, c-format
+msgid "Manage stock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:93
+#, c-format
+msgid "Infinite"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:105
+#, c-format
+msgid "lost cannot be greater that current + incoming (max %1$s)"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:111
+#, c-format
+msgid "current stock will change from %1$s to %2$s"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:112
+#, c-format
+msgid "current stock will stay at %1$s"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:129
+#: src/paths/instance/products/list/Table.tsx:204
+#, c-format
+msgid "Incoming"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:130
+#: src/paths/instance/products/list/Table.tsx:205
+#, c-format
+msgid "Lost"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:142
+#, c-format
+msgid "Current"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:145
+#, c-format
+msgid "without stock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:150
+#, c-format
+msgid "Next restock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:152
+#, c-format
+msgid "Delivery address"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:73
+#, c-format
+msgid "this product has no taxes"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:77
+#: src/paths/instance/orders/details/DetailPage.tsx:145
+#: src/paths/instance/orders/details/DetailPage.tsx:296
+#: src/paths/instance/orders/list/Table.tsx:116
+#: src/paths/instance/transfers/create/CreatePage.tsx:84
+#, c-format
+msgid "Amount"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:78
+#, c-format
+msgid "currency and value separated with colon"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:84
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:78
+#, c-format
+msgid "Add"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:53
+#, c-format
+msgid "Instance"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:59
+#, c-format
+msgid "Settings"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:65
+#: src/paths/instance/orders/list/Table.tsx:60
+#, c-format
+msgid "Orders"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:71
+#: src/paths/instance/orders/create/CreatePage.tsx:258
+#: src/paths/instance/products/list/Table.tsx:48
+#, c-format
+msgid "Products"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:77
+#: src/paths/instance/transfers/list/Table.tsx:65
+#, c-format
+msgid "Transfers"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:87
+#, c-format
+msgid "Connection"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:112 src/paths/admin/list/Table.tsx:57
+#, c-format
+msgid "Instances"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:116
+#, c-format
+msgid "New"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:122
+#, c-format
+msgid "List"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:129
+#, c-format
+msgid "Log out"
+msgstr ""
+
+#: src/components/modal/index.tsx:74
+#, c-format
+msgid "Clear"
+msgstr ""
+
+#: src/components/modal/index.tsx:110 src/components/modal/index.tsx:111
+#, c-format
+msgid "should be the same"
+msgstr ""
+
+#: src/components/modal/index.tsx:111
+#, c-format
+msgid "cannot be the same as before"
+msgstr ""
+
+#: src/components/modal/index.tsx:114
+#, c-format
+msgid ""
+"You are updating the authorization token from instance %1$s with id %2$s"
+msgstr ""
+
+#: src/components/modal/index.tsx:124
+#, c-format
+msgid "Old token"
+msgstr ""
+
+#: src/components/modal/index.tsx:125
+#, c-format
+msgid "New token"
+msgstr ""
+
+#: src/components/modal/index.tsx:127
+#, c-format
+msgid "Clearing the auth token will mean public access to the instance"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:96
+#: src/paths/admin/create/CreatePage.tsx:85 src/paths/admin/list/Table.tsx:109
+#: src/paths/instance/transfers/list/Table.tsx:122
+#, c-format
+msgid "ID"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:98
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:121
+#: src/paths/instance/products/list/Table.tsx:85
+#, c-format
+msgid "Image"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:100
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:123
+#, c-format
+msgid "Unit"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:101
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:124
+#: src/paths/instance/products/list/Table.tsx:162
+#: src/paths/instance/products/list/Table.tsx:214
+#, c-format
+msgid "Price"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:103
+#: src/paths/instance/products/list/Table.tsx:90
+#, c-format
+msgid "Stock"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:105
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:128
+#: src/paths/instance/products/list/Table.tsx:88
+#, c-format
+msgid "Taxes"
+msgstr ""
+
+#: src/index.tsx:75
+#, c-format
+msgid "Server not found"
+msgstr ""
+
+#: src/index.tsx:85
+#, c-format
+msgid "Couldn't access the server"
+msgstr ""
+
+#: src/index.tsx:87 src/index.tsx:99
+#, c-format
+msgid "Got message %1$s from %2$s"
+msgstr ""
+
+#: src/index.tsx:97
+#, c-format
+msgid "Unexpected Error"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:108
+#, c-format
+msgid "Auth token"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:91
+#: src/paths/instance/details/DetailPage.tsx:77
+#: src/paths/instance/update/UpdatePage.tsx:110
+#, c-format
+msgid "Account address"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:93
+#: src/paths/instance/update/UpdatePage.tsx:112
+#, c-format
+msgid "Default max deposit fee"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:95
+#: src/paths/instance/update/UpdatePage.tsx:114
+#, c-format
+msgid "Default max wire fee"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:97
+#: src/paths/instance/update/UpdatePage.tsx:116
+#, c-format
+msgid "Default wire fee amortization"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:103
+#: src/paths/instance/update/UpdatePage.tsx:122
+#, c-format
+msgid "Jurisdiction"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:107
+#: src/paths/instance/update/UpdatePage.tsx:126
+#, c-format
+msgid "Default pay delay"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:109
+#: src/paths/instance/update/UpdatePage.tsx:128
+#, c-format
+msgid "Default wire transfer delay"
+msgstr ""
+
+#: src/paths/admin/create/index.tsx:58
+#, c-format
+msgid "could not create instance"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:63 src/paths/admin/list/Table.tsx:131
+#: src/paths/instance/transfers/list/Table.tsx:71
+#, c-format
+msgid "Delete"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:128
+#, c-format
+msgid "Edit"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:149
+#: src/paths/instance/products/list/Table.tsx:245
+#, c-format
+msgid "There is no instances yet, add more pressing the + sign"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:237
+#, c-format
+msgid "Inventory products"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:286
+#, c-format
+msgid "Total price"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:287
+#, c-format
+msgid "Total tax"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:289
+#: src/paths/instance/orders/create/CreatePage.tsx:297
+#, c-format
+msgid "Order price"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:295
+#, c-format
+msgid "Net"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:300
+#: src/paths/instance/orders/details/DetailPage.tsx:144
+#: src/paths/instance/orders/details/DetailPage.tsx:295
+#: src/paths/instance/orders/list/Table.tsx:117
+#, c-format
+msgid "Summary"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:302
+#, c-format
+msgid "Payments options"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:303
+#, c-format
+msgid "Auto refund deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:304
+#, c-format
+msgid "Refund deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:305
+#, c-format
+msgid "Pay deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:307
+#, c-format
+msgid "Delivery date"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:308
+#, c-format
+msgid "Location"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:312
+#, c-format
+msgid "Max fee"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:313
+#, c-format
+msgid "Max wire fee"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:314
+#, c-format
+msgid "Wire fee amortization"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:315
+#, c-format
+msgid "Fullfilment url"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:318
+#, c-format
+msgid "Extra information"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:44
+#, c-format
+msgid "select a product first"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:51
+#, c-format
+msgid "should be greater than 0"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:58
+#, c-format
+msgid ""
+"cannot be greater than current stock and quantity previously added. max: %1$s"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:64
+#, c-format
+msgid "cannot be greater than current stock %1$s"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:76
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:126
+#, c-format
+msgid "Quantity"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:92
+#: src/paths/instance/orders/details/DetailPage.tsx:235
+#: src/paths/instance/orders/details/DetailPage.tsx:333
+#, c-format
+msgid "Order"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:93
+#, c-format
+msgid "claimed"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:110
+#: src/paths/instance/orders/details/DetailPage.tsx:261
+#: src/paths/instance/orders/list/Table.tsx:136
+#, c-format
+msgid "copy url"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:126
+#: src/paths/instance/orders/details/DetailPage.tsx:349
+#, c-format
+msgid "pay at"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:127
+#: src/paths/instance/orders/details/DetailPage.tsx:350
+#, c-format
+msgid "created at"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:138
+#: src/paths/instance/orders/details/DetailPage.tsx:289
+#, c-format
+msgid "Timeline"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:142
+#: src/paths/instance/orders/details/DetailPage.tsx:293
+#, c-format
+msgid "Payment details"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:146
+#: src/paths/instance/orders/details/DetailPage.tsx:299
+#: src/paths/instance/orders/details/DetailPage.tsx:363
+#, c-format
+msgid "Order status"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:156
+#: src/paths/instance/orders/details/DetailPage.tsx:308
+#, c-format
+msgid "Product list"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:236
+#, c-format
+msgid "paid"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:238
+#, c-format
+msgid "wired"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:241
+#, c-format
+msgid "refunded"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:258
+#, c-format
+msgid "refund"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:297
+#, c-format
+msgid "Refunded amount"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:298
+#, c-format
+msgid "Deposit total"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:336
+#, c-format
+msgid "unpaid"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:364
+#, c-format
+msgid "Order status URL"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:365
+#, c-format
+msgid "Pay URI"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:383
+#, c-format
+msgid ""
+"Unknown order status. This is an error, please contact the administrator."
+msgstr ""
+
+#: src/paths/instance/orders/details/index.tsx:56
+#: src/paths/instance/orders/list/index.tsx:147
+#, c-format
+msgid "refund created successfully"
+msgstr ""
+
+#: src/paths/instance/orders/details/index.tsx:59
+#: src/paths/instance/orders/list/index.tsx:150
+#, c-format
+msgid "could not create the refund"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:111
+#, c-format
+msgid "load newer orders"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:115
+#, c-format
+msgid "Date"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:131
+#: src/paths/instance/orders/list/Table.tsx:223
+#, c-format
+msgid "Refund"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:145
+#, c-format
+msgid "load older orders"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:154
+#, c-format
+msgid "No orders has been found"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:202
+#, c-format
+msgid "date"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:203
+#, c-format
+msgid "amount"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:204
+#, c-format
+msgid "reason"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:224
+#, c-format
+msgid "Max refundable:"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "Reason"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "duplicated"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "requested by the customer"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "other"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:91
+#, c-format
+msgid "go to order id"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:107
+#, c-format
+msgid "Paid"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:108
+#, c-format
+msgid "Refunded"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:109
+#, c-format
+msgid "Not wired"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:110
+#, c-format
+msgid "All"
+msgstr ""
+
+#: src/paths/instance/products/create/index.tsx:48
+#: src/paths/instance/products/update/index.tsx:64
+#, c-format
+msgid "could not create product"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:87
+#, c-format
+msgid "Sell"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:89
+#, c-format
+msgid "Profit"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:91
+#, c-format
+msgid "Sold"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:59
+#, c-format
+msgid "product updated successfully"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:62
+#, c-format
+msgid "could not update the product"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:70
+#, c-format
+msgid "product delete successfully"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:73
+#, c-format
+msgid "could not delete the product"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:59
+#, c-format
+msgid "Tips"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:111
+#, c-format
+msgid "Committed amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:112
+#, c-format
+msgid "Exchange initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:113
+#, c-format
+msgid "Merchant initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:148
+#, c-format
+msgid "There is no tips yet, add more pressing the + sign"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:50
+#: src/paths/instance/transfers/create/CreatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:56
+#, c-format
+msgid "cannot be empty"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:51
+#, c-format
+msgid "check the id, doest look valid"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:52
+#, c-format
+msgid "should have 52 characters, current %1$s"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:57
+#, c-format
+msgid "URL doesn't have the right format"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:74
+#, c-format
+msgid "Transfer ID"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:76
+#, c-format
+msgid "Account Address"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:82
+#: src/paths/instance/transfers/list/Table.tsx:125
+#, c-format
+msgid "Exchange URL"
+msgstr ""
+
+#: src/paths/instance/transfers/create/index.tsx:49
+#, c-format
+msgid "could not inform transfer"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:118
+#, c-format
+msgid "load newer transfers"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:123
+#, c-format
+msgid "Credit"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:126
+#, c-format
+msgid "Confirmed"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:127
+#: src/paths/instance/transfers/list/index.tsx:60
+#, c-format
+msgid "Verified"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:128
+#, c-format
+msgid "Executed at"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "yes"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "no"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "unknown"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:145
+#, c-format
+msgid "load older transfers"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:154
+#, c-format
+msgid "There is no transfer yet, add more pressing the + sign"
+msgstr ""
diff --git a/packages/merchant-backoffice-ui/src/i18n/es.po 
b/packages/merchant-backoffice-ui/src/i18n/es.po
new file mode 100644
index 000000000..9075d4656
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/i18n/es.po
@@ -0,0 +1,1065 @@
+# This file is part of TALER
+# (C) 2016 GNUnet e.V.
+#
+# TALER is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3, or (at your option) any later version.
+#
+# TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Taler Wallet\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2016-11-23 00:00+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: src/ApplicationReadyRoutes.tsx:50 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:299
+#, c-format
+msgid "Access denied"
+msgstr "Acceso denegado"
+
+#: src/ApplicationReadyRoutes.tsx:51 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:300
+#, c-format
+msgid "Check your token is valid"
+msgstr "Verifica que el token sea valido"
+
+#: src/ApplicationReadyRoutes.tsx:72
+#, c-format
+msgid "Couldn't access the server."
+msgstr "No se pudo acceder al servidor"
+
+#: src/ApplicationReadyRoutes.tsx:73
+#, c-format
+msgid "Could not infer instance id from url %1$s"
+msgstr "No se pudo inferir el id de la instancia con la url %1$s"
+
+#: src/InstanceRoutes.tsx:109
+#, c-format
+msgid "HTTP status #%1$s: Server reported a problem"
+msgstr "HTTP status #%1$s: Servidor reporto un problema"
+
+#: src/InstanceRoutes.tsx:110
+#, fuzzy, c-format
+msgid "Got message: \"%1$s\" from: %2$s"
+msgstr "Recivimos el mensaje %1$s desde %2$s"
+
+#: src/InstanceRoutes.tsx:127
+#, c-format
+msgid "No default instance"
+msgstr "Sin instancia default"
+
+#: src/InstanceRoutes.tsx:128
+#, c-format
+msgid ""
+"in order to use merchant backoffice, you should create the default instance"
+msgstr "para usar el merchant backoffice, debería crear la instancia default"
+
+#: src/InstanceRoutes.tsx:288
+#, c-format
+msgid "Server reported a problem: HTTP status #%1$s"
+msgstr "Servidir reporto un problema: HTTP status #%1$s"
+
+#: src/InstanceRoutes.tsx:289
+#, fuzzy, c-format
+msgid "Got message: %1$s from: %2$s"
+msgstr "Recivimos el mensaje %1$s desde %2$s"
+
+#: src/components/exception/login.tsx:46
+#, c-format
+msgid "Login required"
+msgstr "Login necesario"
+
+#: src/components/exception/login.tsx:49
+#, c-format
+msgid ""
+"Please enter your auth token. Token should have \"secret-token:\" and start "
+"with Bearer or ApiKey"
+msgstr ""
+"Por favor ingrese su token de autorización. El token debe tener \"secret-"
+"token\" y comenzar con Bearer o ApiKey"
+
+#: src/components/exception/login.tsx:86 src/components/modal/index.tsx:53
+#: src/components/modal/index.tsx:75 src/paths/admin/create/CreatePage.tsx:115
+#: src/paths/instance/orders/create/CreatePage.tsx:325
+#: src/paths/instance/products/create/CreatePage.tsx:51
+#: src/paths/instance/products/list/Table.tsx:174
+#: src/paths/instance/products/list/Table.tsx:228
+#: src/paths/instance/products/update/UpdatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:134
+#, c-format
+msgid "Confirm"
+msgstr "Confirmar"
+
+#: src/components/form/InputArray.tsx:72
+#, c-format
+msgid "The value %1$s is invalid for a payment url"
+msgstr "El valor %1$s es invalido para una URL de pago"
+
+#: src/components/form/InputDate.tsx:67
+#: src/paths/instance/orders/list/index.tsx:123
+#, c-format
+msgid "pick a date"
+msgstr "elegir una fecha"
+
+#: src/components/form/InputDate.tsx:81
+#, fuzzy, c-format
+msgid "clear"
+msgstr "Limpiar"
+
+#: src/components/form/InputDate.tsx:83
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "never"
+msgstr "nunca"
+
+#: src/components/form/InputImage.tsx:80
+#, c-format
+msgid "Image should be smaller than 1 MB"
+msgstr "La imagen debe ser mas chica que 1 MB"
+
+#: src/components/form/InputLocation.tsx:28
+#, c-format
+msgid "Country"
+msgstr "País"
+
+#: src/components/form/InputLocation.tsx:30
+#: src/paths/admin/create/CreatePage.tsx:99
+#: src/paths/instance/transfers/list/Table.tsx:124
+#: src/paths/instance/update/UpdatePage.tsx:118
+#, c-format
+msgid "Address"
+msgstr "Dirección"
+
+#: src/components/form/InputLocation.tsx:34
+#, c-format
+msgid "Building number"
+msgstr "Número de edificio"
+
+#: src/components/form/InputLocation.tsx:35
+#, c-format
+msgid "Building name"
+msgstr "Nombre de edificio"
+
+#: src/components/form/InputLocation.tsx:36
+#, c-format
+msgid "Street"
+msgstr "Calle"
+
+#: src/components/form/InputLocation.tsx:37
+#, c-format
+msgid "Post code"
+msgstr "Código postal"
+
+#: src/components/form/InputLocation.tsx:38
+#, fuzzy, c-format
+msgid "Town location"
+msgstr "Ubicación de ciudad"
+
+#: src/components/form/InputLocation.tsx:39
+#, c-format
+msgid "Town"
+msgstr "Ciudad"
+
+#: src/components/form/InputLocation.tsx:40
+#, c-format
+msgid "District"
+msgstr "Distrito"
+
+#: src/components/form/InputLocation.tsx:41
+#, c-format
+msgid "Country subdivision"
+msgstr "Provincia"
+
+#: src/components/form/InputSearchProduct.tsx:59
+#, fuzzy, c-format
+msgid "Product id"
+msgstr "Id de producto"
+
+#: src/components/form/InputSearchProduct.tsx:60
+#: src/components/product/ProductForm.tsx:99
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:122
+#: src/paths/instance/orders/list/Table.tsx:227
+#: src/paths/instance/products/list/Table.tsx:86
+#, c-format
+msgid "Description"
+msgstr "Descripcion"
+
+#: src/components/form/InputSearchProduct.tsx:73
+#: src/components/form/InputTaxes.tsx:81
+#: src/paths/admin/create/CreatePage.tsx:87 src/paths/admin/list/Table.tsx:110
+#: src/paths/instance/details/DetailPage.tsx:76
+#: src/paths/instance/update/UpdatePage.tsx:106
+#, c-format
+msgid "Name"
+msgstr "Nombre"
+
+#: src/components/form/InputSearchProduct.tsx:102
+#, c-format
+msgid "loading..."
+msgstr "Cargando..."
+
+#: src/components/form/InputSearchProduct.tsx:108
+#, c-format
+msgid "no products found"
+msgstr "No se encontraron productos"
+
+#: src/components/form/InputSearchProduct.tsx:116
+#, c-format
+msgid "no results"
+msgstr "Sin resultados"
+
+#: src/components/form/InputSecured.tsx:33
+#, c-format
+msgid "Deleting"
+msgstr "Borrando"
+
+#: src/components/form/InputSecured.tsx:34
+#, c-format
+msgid "Changing"
+msgstr "Cambiando"
+
+#: src/components/form/InputSecured.tsx:60
+#, c-format
+msgid "Manage token"
+msgstr "Administrar token"
+
+#: src/components/form/InputSecured.tsx:83
+#, c-format
+msgid "Update"
+msgstr "Actualizar"
+
+#: src/components/form/InputSecured.tsx:100
+#: src/paths/instance/orders/create/CreatePage.tsx:252
+#: src/paths/instance/orders/create/CreatePage.tsx:273
+#, c-format
+msgid "Remove"
+msgstr "Eliminar"
+
+#: src/components/form/InputSecured.tsx:106 src/components/modal/index.tsx:52
+#: src/components/modal/index.tsx:73 src/paths/admin/create/CreatePage.tsx:114
+#: src/paths/instance/orders/create/CreatePage.tsx:324
+#: src/paths/instance/products/create/CreatePage.tsx:50
+#: src/paths/instance/products/list/Table.tsx:166
+#: src/paths/instance/products/list/Table.tsx:218
+#: src/paths/instance/products/update/UpdatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:88
+#: src/paths/instance/update/UpdatePage.tsx:133
+#, c-format
+msgid "Cancel"
+msgstr "Cancelar"
+
+#: src/components/form/InputStock.tsx:91
+#, c-format
+msgid "Manage stock"
+msgstr "Administrar stock"
+
+#: src/components/form/InputStock.tsx:93
+#, c-format
+msgid "Infinite"
+msgstr "Inifinito"
+
+#: src/components/form/InputStock.tsx:105
+#, fuzzy, c-format
+msgid "lost cannot be greater that current + incoming (max %1$s)"
+msgstr "no puede ser mayor al stock actual %1$s"
+
+#: src/components/form/InputStock.tsx:111
+#, c-format
+msgid "current stock will change from %1$s to %2$s"
+msgstr "stock actual cambiará desde %1$s a %2$s"
+
+#: src/components/form/InputStock.tsx:112
+#, c-format
+msgid "current stock will stay at %1$s"
+msgstr "stock actual seguirá en %1$s"
+
+#: src/components/form/InputStock.tsx:129
+#: src/paths/instance/products/list/Table.tsx:204
+#, c-format
+msgid "Incoming"
+msgstr "Ingresando"
+
+#: src/components/form/InputStock.tsx:130
+#: src/paths/instance/products/list/Table.tsx:205
+#, c-format
+msgid "Lost"
+msgstr "Perdido"
+
+#: src/components/form/InputStock.tsx:142
+#, c-format
+msgid "Current"
+msgstr "Actual"
+
+#: src/components/form/InputStock.tsx:145
+#, c-format
+msgid "without stock"
+msgstr "sin stock"
+
+#: src/components/form/InputStock.tsx:150
+#, c-format
+msgid "Next restock"
+msgstr "Próximo reabastecimiento"
+
+#: src/components/form/InputStock.tsx:152
+#, c-format
+msgid "Delivery address"
+msgstr "Dirección de entrega"
+
+#: src/components/form/InputTaxes.tsx:73
+#, c-format
+msgid "this product has no taxes"
+msgstr "este producto no tiene impuestos"
+
+#: src/components/form/InputTaxes.tsx:77
+#: src/paths/instance/orders/details/DetailPage.tsx:145
+#: src/paths/instance/orders/details/DetailPage.tsx:296
+#: src/paths/instance/orders/list/Table.tsx:116
+#: src/paths/instance/transfers/create/CreatePage.tsx:84
+#, c-format
+msgid "Amount"
+msgstr "Monto"
+
+#: src/components/form/InputTaxes.tsx:78
+#, c-format
+msgid "currency and value separated with colon"
+msgstr "Moneda y valor separado por dos puntos"
+
+#: src/components/form/InputTaxes.tsx:84
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:78
+#, c-format
+msgid "Add"
+msgstr "Agregar"
+
+#: src/components/menu/SideBar.tsx:53
+#, c-format
+msgid "Instance"
+msgstr "Instancia"
+
+#: src/components/menu/SideBar.tsx:59
+#, c-format
+msgid "Settings"
+msgstr "Configuración"
+
+#: src/components/menu/SideBar.tsx:65
+#: src/paths/instance/orders/list/Table.tsx:60
+#, fuzzy, c-format
+msgid "Orders"
+msgstr "Ordenes"
+
+#: src/components/menu/SideBar.tsx:71
+#: src/paths/instance/orders/create/CreatePage.tsx:258
+#: src/paths/instance/products/list/Table.tsx:48
+#, c-format
+msgid "Products"
+msgstr "Productos"
+
+#: src/components/menu/SideBar.tsx:77
+#: src/paths/instance/transfers/list/Table.tsx:65
+#, c-format
+msgid "Transfers"
+msgstr "Transferencias"
+
+#: src/components/menu/SideBar.tsx:87
+#, fuzzy, c-format
+msgid "Connection"
+msgstr "Conexión"
+
+#: src/components/menu/SideBar.tsx:112 src/paths/admin/list/Table.tsx:57
+#, c-format
+msgid "Instances"
+msgstr "Instancias"
+
+#: src/components/menu/SideBar.tsx:116
+#, fuzzy, c-format
+msgid "New"
+msgstr "Nuevo"
+
+#: src/components/menu/SideBar.tsx:122
+#, c-format
+msgid "List"
+msgstr "Lista"
+
+#: src/components/menu/SideBar.tsx:129
+#, c-format
+msgid "Log out"
+msgstr "Salir"
+
+#: src/components/modal/index.tsx:74
+#, c-format
+msgid "Clear"
+msgstr "Limpiar"
+
+#: src/components/modal/index.tsx:110 src/components/modal/index.tsx:111
+#, c-format
+msgid "should be the same"
+msgstr "deberían ser iguales"
+
+#: src/components/modal/index.tsx:111
+#, c-format
+msgid "cannot be the same as before"
+msgstr "no puede ser igual al anterior"
+
+#: src/components/modal/index.tsx:114
+#, c-format
+msgid ""
+"You are updating the authorization token from instance %1$s with id %2$s"
+msgstr ""
+"Está actualizando el token de autorización para la instancia %1$s con id %2$s"
+
+#: src/components/modal/index.tsx:124
+#, c-format
+msgid "Old token"
+msgstr "Viejo token"
+
+#: src/components/modal/index.tsx:125
+#, c-format
+msgid "New token"
+msgstr "Nuevo token"
+
+#: src/components/modal/index.tsx:127
+#, c-format
+msgid "Clearing the auth token will mean public access to the instance"
+msgstr ""
+"Limpiar el token de autorización significa acceso publico a la instancia"
+
+#: src/components/product/ProductForm.tsx:96
+#: src/paths/admin/create/CreatePage.tsx:85 src/paths/admin/list/Table.tsx:109
+#: src/paths/instance/transfers/list/Table.tsx:122
+#, c-format
+msgid "ID"
+msgstr "ID"
+
+#: src/components/product/ProductForm.tsx:98
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:121
+#: src/paths/instance/products/list/Table.tsx:85
+#, c-format
+msgid "Image"
+msgstr "Imagen"
+
+#: src/components/product/ProductForm.tsx:100
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:123
+#, c-format
+msgid "Unit"
+msgstr "Unidad"
+
+#: src/components/product/ProductForm.tsx:101
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:124
+#: src/paths/instance/products/list/Table.tsx:162
+#: src/paths/instance/products/list/Table.tsx:214
+#, c-format
+msgid "Price"
+msgstr "Precio"
+
+#: src/components/product/ProductForm.tsx:103
+#: src/paths/instance/products/list/Table.tsx:90
+#, c-format
+msgid "Stock"
+msgstr "Stock"
+
+#: src/components/product/ProductForm.tsx:105
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:128
+#: src/paths/instance/products/list/Table.tsx:88
+#, c-format
+msgid "Taxes"
+msgstr "Impuesto"
+
+#: src/index.tsx:75
+#, c-format
+msgid "Server not found"
+msgstr "Servidor no encontrado"
+
+#: src/index.tsx:85
+#, c-format
+msgid "Couldn't access the server"
+msgstr "No se pudo aceder al servidor"
+
+#: src/index.tsx:87 src/index.tsx:99
+#, c-format
+msgid "Got message %1$s from %2$s"
+msgstr "Recivimos el mensaje %1$s desde %2$s"
+
+#: src/index.tsx:97
+#, c-format
+msgid "Unexpected Error"
+msgstr "Error inesperado"
+
+#: src/paths/admin/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:108
+#, c-format
+msgid "Auth token"
+msgstr "Token de autorización"
+
+#: src/paths/admin/create/CreatePage.tsx:91
+#: src/paths/instance/details/DetailPage.tsx:77
+#: src/paths/instance/update/UpdatePage.tsx:110
+#, c-format
+msgid "Account address"
+msgstr "Dirección de cuenta"
+
+#: src/paths/admin/create/CreatePage.tsx:93
+#: src/paths/instance/update/UpdatePage.tsx:112
+#, c-format
+msgid "Default max deposit fee"
+msgstr "Impuesto máximo de deposito por omisión"
+
+#: src/paths/admin/create/CreatePage.tsx:95
+#: src/paths/instance/update/UpdatePage.tsx:114
+#, c-format
+msgid "Default max wire fee"
+msgstr "Impuesto máximo de transferencia por omisión"
+
+#: src/paths/admin/create/CreatePage.tsx:97
+#: src/paths/instance/update/UpdatePage.tsx:116
+#, c-format
+msgid "Default wire fee amortization"
+msgstr "Amortización de impuesto de transferencia por omisión"
+
+#: src/paths/admin/create/CreatePage.tsx:103
+#: src/paths/instance/update/UpdatePage.tsx:122
+#, c-format
+msgid "Jurisdiction"
+msgstr "Jurisdicción"
+
+#: src/paths/admin/create/CreatePage.tsx:107
+#: src/paths/instance/update/UpdatePage.tsx:126
+#, c-format
+msgid "Default pay delay"
+msgstr "Retrazo de pago por omisión"
+
+#: src/paths/admin/create/CreatePage.tsx:109
+#: src/paths/instance/update/UpdatePage.tsx:128
+#, c-format
+msgid "Default wire transfer delay"
+msgstr "Retrazo de transferencia por omisión"
+
+#: src/paths/admin/create/index.tsx:58
+#, c-format
+msgid "could not create instance"
+msgstr "no se pudo crear la instancia"
+
+#: src/paths/admin/list/Table.tsx:63 src/paths/admin/list/Table.tsx:131
+#: src/paths/instance/transfers/list/Table.tsx:71
+#, fuzzy, c-format
+msgid "Delete"
+msgstr "Borrando"
+
+#: src/paths/admin/list/Table.tsx:128
+#, c-format
+msgid "Edit"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:149
+#: src/paths/instance/products/list/Table.tsx:245
+#, c-format
+msgid "There is no instances yet, add more pressing the + sign"
+msgstr "No hay instancias todavían, agregue mas presionando el signo +"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:237
+#, c-format
+msgid "Inventory products"
+msgstr "Productos de inventario"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:286
+#, c-format
+msgid "Total price"
+msgstr "Precio total"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:287
+#, c-format
+msgid "Total tax"
+msgstr "Impuesto total"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:289
+#: src/paths/instance/orders/create/CreatePage.tsx:297
+#, c-format
+msgid "Order price"
+msgstr "Precio de la orden"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:295
+#, fuzzy, c-format
+msgid "Net"
+msgstr "Neto"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:300
+#: src/paths/instance/orders/details/DetailPage.tsx:144
+#: src/paths/instance/orders/details/DetailPage.tsx:295
+#: src/paths/instance/orders/list/Table.tsx:117
+#, c-format
+msgid "Summary"
+msgstr "Resumen"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:302
+#, c-format
+msgid "Payments options"
+msgstr "Opciones de pago"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:303
+#, c-format
+msgid "Auto refund deadline"
+msgstr "Plazo de reembolso automático"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:304
+#, c-format
+msgid "Refund deadline"
+msgstr "Plazo de reembolso"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:305
+#, c-format
+msgid "Pay deadline"
+msgstr "Plazo de pago"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:307
+#, c-format
+msgid "Delivery date"
+msgstr "Fecha de entrega"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:308
+#, fuzzy, c-format
+msgid "Location"
+msgstr "Ubicación"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:312
+#, c-format
+msgid "Max fee"
+msgstr "Impuesto máximo"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:313
+#, c-format
+msgid "Max wire fee"
+msgstr "Impuesto de transferencia máximo"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:314
+#, c-format
+msgid "Wire fee amortization"
+msgstr "Amortización de impuesto de transferencia"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:315
+#, c-format
+msgid "Fullfilment url"
+msgstr "URL de completitud"
+
+#: src/paths/instance/orders/create/CreatePage.tsx:318
+#, c-format
+msgid "Extra information"
+msgstr "Información extra"
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:44
+#, c-format
+msgid "select a product first"
+msgstr "seleccione un producto primero"
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:51
+#, fuzzy, c-format
+msgid "should be greater than 0"
+msgstr "La imagen debe ser mas chica que 1 MB"
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:58
+#, c-format
+msgid ""
+"cannot be greater than current stock and quantity previously added. max: %1$s"
+msgstr ""
+"no puede ser mayor al stock actual y la cantidad previamente agregada. "
+"máximo: %1$s"
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:64
+#, c-format
+msgid "cannot be greater than current stock %1$s"
+msgstr "no puede ser mayor al stock actual %1$s"
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:76
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:126
+#, c-format
+msgid "Quantity"
+msgstr "Cantidad"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:92
+#: src/paths/instance/orders/details/DetailPage.tsx:235
+#: src/paths/instance/orders/details/DetailPage.tsx:333
+#, c-format
+msgid "Order"
+msgstr "Orden"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:93
+#, c-format
+msgid "claimed"
+msgstr "reclamado"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:110
+#: src/paths/instance/orders/details/DetailPage.tsx:261
+#: src/paths/instance/orders/list/Table.tsx:136
+#, c-format
+msgid "copy url"
+msgstr "copiar url"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:126
+#: src/paths/instance/orders/details/DetailPage.tsx:349
+#, c-format
+msgid "pay at"
+msgstr "pagar en"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:127
+#: src/paths/instance/orders/details/DetailPage.tsx:350
+#, c-format
+msgid "created at"
+msgstr "creado"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:138
+#: src/paths/instance/orders/details/DetailPage.tsx:289
+#, c-format
+msgid "Timeline"
+msgstr "Cronología"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:142
+#: src/paths/instance/orders/details/DetailPage.tsx:293
+#, c-format
+msgid "Payment details"
+msgstr "Detalles de pago"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:146
+#: src/paths/instance/orders/details/DetailPage.tsx:299
+#: src/paths/instance/orders/details/DetailPage.tsx:363
+#, fuzzy, c-format
+msgid "Order status"
+msgstr "Estado de orden"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:156
+#: src/paths/instance/orders/details/DetailPage.tsx:308
+#, fuzzy, c-format
+msgid "Product list"
+msgstr "Lista de producto"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:236
+#, c-format
+msgid "paid"
+msgstr "pagados"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:238
+#, c-format
+msgid "wired"
+msgstr "transferido"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:241
+#, c-format
+msgid "refunded"
+msgstr "reembolzado"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:258
+#, c-format
+msgid "refund"
+msgstr "reembolzar"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:297
+#, c-format
+msgid "Refunded amount"
+msgstr "Monto reembolzado"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:298
+#, c-format
+msgid "Deposit total"
+msgstr "Total depositado"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:336
+#, c-format
+msgid "unpaid"
+msgstr "impago"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:364
+#, c-format
+msgid "Order status URL"
+msgstr "URL de estado de orden"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:365
+#, c-format
+msgid "Pay URI"
+msgstr "URI de pago"
+
+#: src/paths/instance/orders/details/DetailPage.tsx:383
+#, c-format
+msgid ""
+"Unknown order status. This is an error, please contact the administrator."
+msgstr ""
+"Estado de orden desconocido. Esto es un error, por favor contacte a su "
+"administrador"
+
+#: src/paths/instance/orders/details/index.tsx:56
+#: src/paths/instance/orders/list/index.tsx:147
+#, c-format
+msgid "refund created successfully"
+msgstr "reembolzo creado satisfactoriamente"
+
+#: src/paths/instance/orders/details/index.tsx:59
+#: src/paths/instance/orders/list/index.tsx:150
+#, fuzzy, c-format
+msgid "could not create the refund"
+msgstr "No se pudo aceder al servidor"
+
+#: src/paths/instance/orders/list/Table.tsx:111
+#, c-format
+msgid "load newer orders"
+msgstr "cargar nuevas ordenes"
+
+#: src/paths/instance/orders/list/Table.tsx:115
+#, c-format
+msgid "Date"
+msgstr "Fecha"
+
+#: src/paths/instance/orders/list/Table.tsx:131
+#: src/paths/instance/orders/list/Table.tsx:223
+#, c-format
+msgid "Refund"
+msgstr "Reembolzar"
+
+#: src/paths/instance/orders/list/Table.tsx:145
+#, c-format
+msgid "load older orders"
+msgstr "cargar viejas ordenes"
+
+#: src/paths/instance/orders/list/Table.tsx:154
+#, c-format
+msgid "No orders has been found"
+msgstr "No se enconraron ordenes"
+
+#: src/paths/instance/orders/list/Table.tsx:202
+#, c-format
+msgid "date"
+msgstr "fecha"
+
+#: src/paths/instance/orders/list/Table.tsx:203
+#, c-format
+msgid "amount"
+msgstr "monto"
+
+#: src/paths/instance/orders/list/Table.tsx:204
+#, c-format
+msgid "reason"
+msgstr "razón"
+
+#: src/paths/instance/orders/list/Table.tsx:224
+#, c-format
+msgid "Max refundable:"
+msgstr "Máximo reembolzable:"
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "Reason"
+msgstr "Razón"
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "duplicated"
+msgstr "duplicado"
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "requested by the customer"
+msgstr "pedido por el consumidor"
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "other"
+msgstr "otro"
+
+#: src/paths/instance/orders/list/index.tsx:91
+#, c-format
+msgid "go to order id"
+msgstr "ir a id de orden"
+
+#: src/paths/instance/orders/list/index.tsx:107
+#, c-format
+msgid "Paid"
+msgstr "Pagado"
+
+#: src/paths/instance/orders/list/index.tsx:108
+#, fuzzy, c-format
+msgid "Refunded"
+msgstr "Reembolzado"
+
+#: src/paths/instance/orders/list/index.tsx:109
+#, fuzzy, c-format
+msgid "Not wired"
+msgstr "No transferido"
+
+#: src/paths/instance/orders/list/index.tsx:110
+#, c-format
+msgid "All"
+msgstr "Todo"
+
+#: src/paths/instance/products/create/index.tsx:48
+#: src/paths/instance/products/update/index.tsx:64
+#, c-format
+msgid "could not create product"
+msgstr "no se pudo crear el producto"
+
+#: src/paths/instance/products/list/Table.tsx:87
+#, c-format
+msgid "Sell"
+msgstr "Venta"
+
+#: src/paths/instance/products/list/Table.tsx:89
+#, c-format
+msgid "Profit"
+msgstr "Ganancia"
+
+#: src/paths/instance/products/list/Table.tsx:91
+#, c-format
+msgid "Sold"
+msgstr "Vendido"
+
+#: src/paths/instance/products/list/index.tsx:59
+#, c-format
+msgid "product updated successfully"
+msgstr "producto actualizado correctamente"
+
+#: src/paths/instance/products/list/index.tsx:62
+#, c-format
+msgid "could not update the product"
+msgstr "no se pudo actualizar el producto"
+
+#: src/paths/instance/products/list/index.tsx:70
+#, c-format
+msgid "product delete successfully"
+msgstr "producto fue eliminado correctamente"
+
+#: src/paths/instance/products/list/index.tsx:73
+#, c-format
+msgid "could not delete the product"
+msgstr "no se pudo eliminar el producto"
+
+#: src/paths/instance/tips/list/Table.tsx:59
+#, c-format
+msgid "Tips"
+msgstr "Propinas"
+
+#: src/paths/instance/tips/list/Table.tsx:111
+#, c-format
+msgid "Committed amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:112
+#, c-format
+msgid "Exchange initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:113
+#, c-format
+msgid "Merchant initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:148
+#, c-format
+msgid "There is no tips yet, add more pressing the + sign"
+msgstr "No hay propinas todavía, agregar mas presionando el signo +"
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:50
+#: src/paths/instance/transfers/create/CreatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:56
+#, c-format
+msgid "cannot be empty"
+msgstr "no puede ser vacío"
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:51
+#, c-format
+msgid "check the id, doest look valid"
+msgstr "verificar el id, no parece válido"
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:52
+#, c-format
+msgid "should have 52 characters, current %1$s"
+msgstr "debería tener 52 caracteres, actualmente %1$s"
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:57
+#, c-format
+msgid "URL doesn't have the right format"
+msgstr "La URL no tiene el formato correcto"
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:74
+#, fuzzy, c-format
+msgid "Transfer ID"
+msgstr "Transferencias"
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:76
+#, fuzzy, c-format
+msgid "Account Address"
+msgstr "Dirección de cuenta"
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:82
+#: src/paths/instance/transfers/list/Table.tsx:125
+#, c-format
+msgid "Exchange URL"
+msgstr "URL del Exchange"
+
+#: src/paths/instance/transfers/create/index.tsx:49
+#, fuzzy, c-format
+msgid "could not inform transfer"
+msgstr "no se pudo crear la instancia"
+
+#: src/paths/instance/transfers/list/Table.tsx:118
+#, fuzzy, c-format
+msgid "load newer transfers"
+msgstr "cargar nuevas ordenes"
+
+#: src/paths/instance/transfers/list/Table.tsx:123
+#, c-format
+msgid "Credit"
+msgstr "Crédito"
+
+#: src/paths/instance/transfers/list/Table.tsx:126
+#, fuzzy, c-format
+msgid "Confirmed"
+msgstr "Confirmar"
+
+#: src/paths/instance/transfers/list/Table.tsx:127
+#: src/paths/instance/transfers/list/index.tsx:60
+#, c-format
+msgid "Verified"
+msgstr "Verificado"
+
+#: src/paths/instance/transfers/list/Table.tsx:128
+#, fuzzy, c-format
+msgid "Executed at"
+msgstr "creado"
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "yes"
+msgstr "si"
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "no"
+msgstr "no"
+
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "unknown"
+msgstr "desconocido"
+
+#: src/paths/instance/transfers/list/Table.tsx:145
+#, fuzzy, c-format
+msgid "load older transfers"
+msgstr "cargar viejas transferencias"
+
+#: src/paths/instance/transfers/list/Table.tsx:154
+#, c-format
+msgid "There is no transfer yet, add more pressing the + sign"
+msgstr "No hay transferencias todavía, agregar mas presionando el signo +"
diff --git a/packages/merchant-backoffice-ui/src/i18n/fr.po 
b/packages/merchant-backoffice-ui/src/i18n/fr.po
new file mode 100644
index 000000000..6b35bd0ce
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/i18n/fr.po
@@ -0,0 +1,1057 @@
+# This file is part of TALER
+# (C) 2016 GNUnet e.V.
+#
+# TALER is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3, or (at your option) any later version.
+#
+# TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Taler Wallet\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2016-11-23 00:00+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: src/ApplicationReadyRoutes.tsx:50 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:299
+#, c-format
+msgid "Access denied"
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:51 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:300
+#, c-format
+msgid "Check your token is valid"
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:72
+#, c-format
+msgid "Couldn't access the server."
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:73
+#, c-format
+msgid "Could not infer instance id from url %1$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:109
+#, c-format
+msgid "HTTP status #%1$s: Server reported a problem"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:110
+#, c-format
+msgid "Got message: \"%1$s\" from: %2$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:127
+#, c-format
+msgid "No default instance"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:128
+#, c-format
+msgid ""
+"in order to use merchant backoffice, you should create the default instance"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:288
+#, c-format
+msgid "Server reported a problem: HTTP status #%1$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:289
+#, c-format
+msgid "Got message: %1$s from: %2$s"
+msgstr ""
+
+#: src/components/exception/login.tsx:46
+#, c-format
+msgid "Login required"
+msgstr ""
+
+#: src/components/exception/login.tsx:49
+#, c-format
+msgid ""
+"Please enter your auth token. Token should have \"secret-token:\" and start "
+"with Bearer or ApiKey"
+msgstr ""
+
+#: src/components/exception/login.tsx:86 src/components/modal/index.tsx:53
+#: src/components/modal/index.tsx:75 src/paths/admin/create/CreatePage.tsx:115
+#: src/paths/instance/orders/create/CreatePage.tsx:325
+#: src/paths/instance/products/create/CreatePage.tsx:51
+#: src/paths/instance/products/list/Table.tsx:174
+#: src/paths/instance/products/list/Table.tsx:228
+#: src/paths/instance/products/update/UpdatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:134
+#, c-format
+msgid "Confirm"
+msgstr ""
+
+#: src/components/form/InputArray.tsx:72
+#, c-format
+msgid "The value %1$s is invalid for a payment url"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:67
+#: src/paths/instance/orders/list/index.tsx:123
+#, c-format
+msgid "pick a date"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:81
+#, c-format
+msgid "clear"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:83
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "never"
+msgstr ""
+
+#: src/components/form/InputImage.tsx:80
+#, c-format
+msgid "Image should be smaller than 1 MB"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:28
+#, c-format
+msgid "Country"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:30
+#: src/paths/admin/create/CreatePage.tsx:99
+#: src/paths/instance/transfers/list/Table.tsx:124
+#: src/paths/instance/update/UpdatePage.tsx:118
+#, c-format
+msgid "Address"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:34
+#, c-format
+msgid "Building number"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:35
+#, c-format
+msgid "Building name"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:36
+#, c-format
+msgid "Street"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:37
+#, c-format
+msgid "Post code"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:38
+#, c-format
+msgid "Town location"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:39
+#, c-format
+msgid "Town"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:40
+#, c-format
+msgid "District"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:41
+#, c-format
+msgid "Country subdivision"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:59
+#, c-format
+msgid "Product id"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:60
+#: src/components/product/ProductForm.tsx:99
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:122
+#: src/paths/instance/orders/list/Table.tsx:227
+#: src/paths/instance/products/list/Table.tsx:86
+#, c-format
+msgid "Description"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:73
+#: src/components/form/InputTaxes.tsx:81
+#: src/paths/admin/create/CreatePage.tsx:87 src/paths/admin/list/Table.tsx:110
+#: src/paths/instance/details/DetailPage.tsx:76
+#: src/paths/instance/update/UpdatePage.tsx:106
+#, c-format
+msgid "Name"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:102
+#, c-format
+msgid "loading..."
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:108
+#, c-format
+msgid "no products found"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:116
+#, c-format
+msgid "no results"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:33
+#, c-format
+msgid "Deleting"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:34
+#, c-format
+msgid "Changing"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:60
+#, c-format
+msgid "Manage token"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:83
+#, c-format
+msgid "Update"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:100
+#: src/paths/instance/orders/create/CreatePage.tsx:252
+#: src/paths/instance/orders/create/CreatePage.tsx:273
+#, c-format
+msgid "Remove"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:106 src/components/modal/index.tsx:52
+#: src/components/modal/index.tsx:73 src/paths/admin/create/CreatePage.tsx:114
+#: src/paths/instance/orders/create/CreatePage.tsx:324
+#: src/paths/instance/products/create/CreatePage.tsx:50
+#: src/paths/instance/products/list/Table.tsx:166
+#: src/paths/instance/products/list/Table.tsx:218
+#: src/paths/instance/products/update/UpdatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:88
+#: src/paths/instance/update/UpdatePage.tsx:133
+#, c-format
+msgid "Cancel"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:91
+#, c-format
+msgid "Manage stock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:93
+#, c-format
+msgid "Infinite"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:105
+#, c-format
+msgid "lost cannot be greater that current + incoming (max %1$s)"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:111
+#, c-format
+msgid "current stock will change from %1$s to %2$s"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:112
+#, c-format
+msgid "current stock will stay at %1$s"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:129
+#: src/paths/instance/products/list/Table.tsx:204
+#, c-format
+msgid "Incoming"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:130
+#: src/paths/instance/products/list/Table.tsx:205
+#, c-format
+msgid "Lost"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:142
+#, c-format
+msgid "Current"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:145
+#, c-format
+msgid "without stock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:150
+#, c-format
+msgid "Next restock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:152
+#, c-format
+msgid "Delivery address"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:73
+#, c-format
+msgid "this product has no taxes"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:77
+#: src/paths/instance/orders/details/DetailPage.tsx:145
+#: src/paths/instance/orders/details/DetailPage.tsx:296
+#: src/paths/instance/orders/list/Table.tsx:116
+#: src/paths/instance/transfers/create/CreatePage.tsx:84
+#, c-format
+msgid "Amount"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:78
+#, c-format
+msgid "currency and value separated with colon"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:84
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:78
+#, c-format
+msgid "Add"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:53
+#, c-format
+msgid "Instance"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:59
+#, c-format
+msgid "Settings"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:65
+#: src/paths/instance/orders/list/Table.tsx:60
+#, c-format
+msgid "Orders"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:71
+#: src/paths/instance/orders/create/CreatePage.tsx:258
+#: src/paths/instance/products/list/Table.tsx:48
+#, c-format
+msgid "Products"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:77
+#: src/paths/instance/transfers/list/Table.tsx:65
+#, c-format
+msgid "Transfers"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:87
+#, c-format
+msgid "Connection"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:112 src/paths/admin/list/Table.tsx:57
+#, c-format
+msgid "Instances"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:116
+#, c-format
+msgid "New"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:122
+#, c-format
+msgid "List"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:129
+#, c-format
+msgid "Log out"
+msgstr ""
+
+#: src/components/modal/index.tsx:74
+#, c-format
+msgid "Clear"
+msgstr ""
+
+#: src/components/modal/index.tsx:110 src/components/modal/index.tsx:111
+#, c-format
+msgid "should be the same"
+msgstr ""
+
+#: src/components/modal/index.tsx:111
+#, c-format
+msgid "cannot be the same as before"
+msgstr ""
+
+#: src/components/modal/index.tsx:114
+#, c-format
+msgid ""
+"You are updating the authorization token from instance %1$s with id %2$s"
+msgstr ""
+
+#: src/components/modal/index.tsx:124
+#, c-format
+msgid "Old token"
+msgstr ""
+
+#: src/components/modal/index.tsx:125
+#, c-format
+msgid "New token"
+msgstr ""
+
+#: src/components/modal/index.tsx:127
+#, c-format
+msgid "Clearing the auth token will mean public access to the instance"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:96
+#: src/paths/admin/create/CreatePage.tsx:85 src/paths/admin/list/Table.tsx:109
+#: src/paths/instance/transfers/list/Table.tsx:122
+#, c-format
+msgid "ID"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:98
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:121
+#: src/paths/instance/products/list/Table.tsx:85
+#, c-format
+msgid "Image"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:100
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:123
+#, c-format
+msgid "Unit"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:101
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:124
+#: src/paths/instance/products/list/Table.tsx:162
+#: src/paths/instance/products/list/Table.tsx:214
+#, c-format
+msgid "Price"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:103
+#: src/paths/instance/products/list/Table.tsx:90
+#, c-format
+msgid "Stock"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:105
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:128
+#: src/paths/instance/products/list/Table.tsx:88
+#, c-format
+msgid "Taxes"
+msgstr ""
+
+#: src/index.tsx:75
+#, c-format
+msgid "Server not found"
+msgstr ""
+
+#: src/index.tsx:85
+#, c-format
+msgid "Couldn't access the server"
+msgstr ""
+
+#: src/index.tsx:87 src/index.tsx:99
+#, c-format
+msgid "Got message %1$s from %2$s"
+msgstr ""
+
+#: src/index.tsx:97
+#, c-format
+msgid "Unexpected Error"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:108
+#, c-format
+msgid "Auth token"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:91
+#: src/paths/instance/details/DetailPage.tsx:77
+#: src/paths/instance/update/UpdatePage.tsx:110
+#, c-format
+msgid "Account address"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:93
+#: src/paths/instance/update/UpdatePage.tsx:112
+#, c-format
+msgid "Default max deposit fee"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:95
+#: src/paths/instance/update/UpdatePage.tsx:114
+#, c-format
+msgid "Default max wire fee"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:97
+#: src/paths/instance/update/UpdatePage.tsx:116
+#, c-format
+msgid "Default wire fee amortization"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:103
+#: src/paths/instance/update/UpdatePage.tsx:122
+#, c-format
+msgid "Jurisdiction"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:107
+#: src/paths/instance/update/UpdatePage.tsx:126
+#, c-format
+msgid "Default pay delay"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:109
+#: src/paths/instance/update/UpdatePage.tsx:128
+#, c-format
+msgid "Default wire transfer delay"
+msgstr ""
+
+#: src/paths/admin/create/index.tsx:58
+#, c-format
+msgid "could not create instance"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:63 src/paths/admin/list/Table.tsx:131
+#: src/paths/instance/transfers/list/Table.tsx:71
+#, c-format
+msgid "Delete"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:128
+#, c-format
+msgid "Edit"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:149
+#: src/paths/instance/products/list/Table.tsx:245
+#, c-format
+msgid "There is no instances yet, add more pressing the + sign"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:237
+#, c-format
+msgid "Inventory products"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:286
+#, c-format
+msgid "Total price"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:287
+#, c-format
+msgid "Total tax"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:289
+#: src/paths/instance/orders/create/CreatePage.tsx:297
+#, c-format
+msgid "Order price"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:295
+#, c-format
+msgid "Net"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:300
+#: src/paths/instance/orders/details/DetailPage.tsx:144
+#: src/paths/instance/orders/details/DetailPage.tsx:295
+#: src/paths/instance/orders/list/Table.tsx:117
+#, c-format
+msgid "Summary"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:302
+#, c-format
+msgid "Payments options"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:303
+#, c-format
+msgid "Auto refund deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:304
+#, c-format
+msgid "Refund deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:305
+#, c-format
+msgid "Pay deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:307
+#, c-format
+msgid "Delivery date"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:308
+#, c-format
+msgid "Location"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:312
+#, c-format
+msgid "Max fee"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:313
+#, c-format
+msgid "Max wire fee"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:314
+#, c-format
+msgid "Wire fee amortization"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:315
+#, c-format
+msgid "Fullfilment url"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:318
+#, c-format
+msgid "Extra information"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:44
+#, c-format
+msgid "select a product first"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:51
+#, c-format
+msgid "should be greater than 0"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:58
+#, c-format
+msgid ""
+"cannot be greater than current stock and quantity previously added. max: %1$s"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:64
+#, c-format
+msgid "cannot be greater than current stock %1$s"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:76
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:126
+#, c-format
+msgid "Quantity"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:92
+#: src/paths/instance/orders/details/DetailPage.tsx:235
+#: src/paths/instance/orders/details/DetailPage.tsx:333
+#, c-format
+msgid "Order"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:93
+#, c-format
+msgid "claimed"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:110
+#: src/paths/instance/orders/details/DetailPage.tsx:261
+#: src/paths/instance/orders/list/Table.tsx:136
+#, c-format
+msgid "copy url"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:126
+#: src/paths/instance/orders/details/DetailPage.tsx:349
+#, c-format
+msgid "pay at"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:127
+#: src/paths/instance/orders/details/DetailPage.tsx:350
+#, c-format
+msgid "created at"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:138
+#: src/paths/instance/orders/details/DetailPage.tsx:289
+#, c-format
+msgid "Timeline"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:142
+#: src/paths/instance/orders/details/DetailPage.tsx:293
+#, c-format
+msgid "Payment details"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:146
+#: src/paths/instance/orders/details/DetailPage.tsx:299
+#: src/paths/instance/orders/details/DetailPage.tsx:363
+#, c-format
+msgid "Order status"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:156
+#: src/paths/instance/orders/details/DetailPage.tsx:308
+#, c-format
+msgid "Product list"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:236
+#, c-format
+msgid "paid"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:238
+#, c-format
+msgid "wired"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:241
+#, c-format
+msgid "refunded"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:258
+#, c-format
+msgid "refund"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:297
+#, c-format
+msgid "Refunded amount"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:298
+#, c-format
+msgid "Deposit total"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:336
+#, c-format
+msgid "unpaid"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:364
+#, c-format
+msgid "Order status URL"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:365
+#, c-format
+msgid "Pay URI"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:383
+#, c-format
+msgid ""
+"Unknown order status. This is an error, please contact the administrator."
+msgstr ""
+
+#: src/paths/instance/orders/details/index.tsx:56
+#: src/paths/instance/orders/list/index.tsx:147
+#, c-format
+msgid "refund created successfully"
+msgstr ""
+
+#: src/paths/instance/orders/details/index.tsx:59
+#: src/paths/instance/orders/list/index.tsx:150
+#, c-format
+msgid "could not create the refund"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:111
+#, c-format
+msgid "load newer orders"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:115
+#, c-format
+msgid "Date"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:131
+#: src/paths/instance/orders/list/Table.tsx:223
+#, c-format
+msgid "Refund"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:145
+#, c-format
+msgid "load older orders"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:154
+#, c-format
+msgid "No orders has been found"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:202
+#, c-format
+msgid "date"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:203
+#, c-format
+msgid "amount"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:204
+#, c-format
+msgid "reason"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:224
+#, c-format
+msgid "Max refundable:"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "Reason"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "duplicated"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "requested by the customer"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "other"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:91
+#, c-format
+msgid "go to order id"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:107
+#, c-format
+msgid "Paid"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:108
+#, c-format
+msgid "Refunded"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:109
+#, c-format
+msgid "Not wired"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:110
+#, c-format
+msgid "All"
+msgstr ""
+
+#: src/paths/instance/products/create/index.tsx:48
+#: src/paths/instance/products/update/index.tsx:64
+#, c-format
+msgid "could not create product"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:87
+#, c-format
+msgid "Sell"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:89
+#, c-format
+msgid "Profit"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:91
+#, c-format
+msgid "Sold"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:59
+#, c-format
+msgid "product updated successfully"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:62
+#, c-format
+msgid "could not update the product"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:70
+#, c-format
+msgid "product delete successfully"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:73
+#, c-format
+msgid "could not delete the product"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:59
+#, c-format
+msgid "Tips"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:111
+#, c-format
+msgid "Committed amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:112
+#, c-format
+msgid "Exchange initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:113
+#, c-format
+msgid "Merchant initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:148
+#, c-format
+msgid "There is no tips yet, add more pressing the + sign"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:50
+#: src/paths/instance/transfers/create/CreatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:56
+#, c-format
+msgid "cannot be empty"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:51
+#, c-format
+msgid "check the id, doest look valid"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:52
+#, c-format
+msgid "should have 52 characters, current %1$s"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:57
+#, c-format
+msgid "URL doesn't have the right format"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:74
+#, c-format
+msgid "Transfer ID"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:76
+#, c-format
+msgid "Account Address"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:82
+#: src/paths/instance/transfers/list/Table.tsx:125
+#, c-format
+msgid "Exchange URL"
+msgstr ""
+
+#: src/paths/instance/transfers/create/index.tsx:49
+#, c-format
+msgid "could not inform transfer"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:118
+#, c-format
+msgid "load newer transfers"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:123
+#, c-format
+msgid "Credit"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:126
+#, c-format
+msgid "Confirmed"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:127
+#: src/paths/instance/transfers/list/index.tsx:60
+#, c-format
+msgid "Verified"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:128
+#, c-format
+msgid "Executed at"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "yes"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "no"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "unknown"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:145
+#, c-format
+msgid "load older transfers"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:154
+#, c-format
+msgid "There is no transfer yet, add more pressing the + sign"
+msgstr ""
diff --git a/packages/merchant-backoffice-ui/src/i18n/index.tsx 
b/packages/merchant-backoffice-ui/src/i18n/index.tsx
new file mode 100644
index 000000000..9403de1f5
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/i18n/index.tsx
@@ -0,0 +1,215 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ * Translation helpers for React components and template literals.
+ */
+
+/**
+ * Imports
+ */
+import { ComponentChild, ComponentChildren, h, Fragment, VNode } from "preact";
+
+import { useTranslationContext } from "../context/translation";
+
+export type Translator = (
+  stringSeq: TemplateStringsArray,
+  ...values: any[]
+) => string;
+export function useTranslator(): Translator {
+  const ctx = useTranslationContext();
+  const jed = ctx.handler;
+  return function str(
+    stringSeq: TemplateStringsArray,
+    ...values: any[]
+  ): string {
+    const s = toI18nString(stringSeq);
+    if (!s) return s;
+    const tr = jed
+      .translate(s)
+      .ifPlural(1, s)
+      .fetch(...values);
+    return tr;
+  };
+}
+
+/**
+ * Convert template strings to a msgid
+ */
+function toI18nString(stringSeq: ReadonlyArray<string>): string {
+  let s = "";
+  for (let i = 0; i < stringSeq.length; i++) {
+    s += stringSeq[i];
+    if (i < stringSeq.length - 1) {
+      s += `%${i + 1}$s`;
+    }
+  }
+  return s;
+}
+
+interface TranslateSwitchProps {
+  target: number;
+  children: ComponentChildren;
+}
+
+function stringifyChildren(children: ComponentChildren): string {
+  let n = 1;
+  const ss = (children instanceof Array ? children : [children]).map((c) => {
+    if (typeof c === "string") {
+      return c;
+    }
+    return `%${n++}$s`;
+  });
+  const s = ss.join("").replace(/ +/g, " ").trim();
+  return s;
+}
+
+interface TranslateProps {
+  children: ComponentChildren;
+  /**
+   * Component that the translated element should be wrapped in.
+   * Defaults to "div".
+   */
+  wrap?: any;
+
+  /**
+   * Props to give to the wrapped component.
+   */
+  wrapProps?: any;
+}
+
+function getTranslatedChildren(
+  translation: string,
+  children: ComponentChildren
+): ComponentChild[] {
+  const tr = translation.split(/%(\d+)\$s/);
+  const childArray = children instanceof Array ? children : [children];
+  // Merge consecutive string children.
+  const placeholderChildren = Array<ComponentChild>();
+  for (let i = 0; i < childArray.length; i++) {
+    const x = childArray[i];
+    if (x === undefined) {
+      continue;
+    } else if (typeof x === "string") {
+      continue;
+    } else {
+      placeholderChildren.push(x);
+    }
+  }
+  const result = Array<ComponentChild>();
+  for (let i = 0; i < tr.length; i++) {
+    if (i % 2 == 0) {
+      // Text
+      result.push(tr[i]);
+    } else {
+      const childIdx = Number.parseInt(tr[i], 10) - 1;
+      result.push(placeholderChildren[childIdx]);
+    }
+  }
+  return result;
+}
+
+/**
+ * Translate text node children of this component.
+ * If a child component might produce a text node, it must be wrapped
+ * in a another non-text element.
+ *
+ * Example:
+ * ```
+ * <Translate>
+ * Hello.  Your score is <span><PlayerScore player={player} /></span>
+ * </Translate>
+ * ```
+ */
+export function Translate({ children }: TranslateProps): VNode {
+  const s = stringifyChildren(children);
+  const ctx = useTranslationContext();
+  const translation: string = ctx.handler.ngettext(s, s, 1);
+  const result = getTranslatedChildren(translation, children);
+  return <Fragment>{result}</Fragment>;
+}
+
+/**
+ * Switch translation based on singular or plural based on the target prop.
+ * Should only contain TranslateSingular and TransplatePlural as children.
+ *
+ * Example:
+ * ```
+ * <TranslateSwitch target={n}>
+ *  <TranslateSingular>I have {n} apple.</TranslateSingular>
+ *  <TranslatePlural>I have {n} apples.</TranslatePlural>
+ * </TranslateSwitch>
+ * ```
+ */
+export function TranslateSwitch({ children, target }: TranslateSwitchProps) {
+  let singular: VNode<TranslationPluralProps> | undefined;
+  let plural: VNode<TranslationPluralProps> | undefined;
+  // const children = this.props.children;
+  if (children) {
+    (children instanceof Array ? children : [children]).forEach(
+      (child: any) => {
+        if (child.type === TranslatePlural) {
+          plural = child;
+        }
+        if (child.type === TranslateSingular) {
+          singular = child;
+        }
+      }
+    );
+  }
+  if (!singular || !plural) {
+    console.error("translation not found");
+    return h("span", {}, ["translation not found"]);
+  }
+  singular.props.target = target;
+  plural.props.target = target;
+  // We're looking up the translation based on the
+  // singular, even if we must use the plural form.
+  return singular;
+}
+
+interface TranslationPluralProps {
+  children: ComponentChildren;
+  target: number;
+}
+
+/**
+ * See [[TranslateSwitch]].
+ */
+export function TranslatePlural({
+  children,
+  target,
+}: TranslationPluralProps): VNode {
+  const s = stringifyChildren(children);
+  const ctx = useTranslationContext();
+  const translation = ctx.handler.ngettext(s, s, 1);
+  const result = getTranslatedChildren(translation, children);
+  return <Fragment>{result}</Fragment>;
+}
+
+/**
+ * See [[TranslateSwitch]].
+ */
+export function TranslateSingular({
+  children,
+  target,
+}: TranslationPluralProps): VNode {
+  const s = stringifyChildren(children);
+  const ctx = useTranslationContext();
+  const translation = ctx.handler.ngettext(s, s, target);
+  const result = getTranslatedChildren(translation, children);
+  return <Fragment>{result}</Fragment>;
+}
diff --git a/packages/merchant-backoffice-ui/src/i18n/it.po 
b/packages/merchant-backoffice-ui/src/i18n/it.po
new file mode 100644
index 000000000..6b35bd0ce
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/i18n/it.po
@@ -0,0 +1,1057 @@
+# This file is part of TALER
+# (C) 2016 GNUnet e.V.
+#
+# TALER is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3, or (at your option) any later version.
+#
+# TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Taler Wallet\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2016-11-23 00:00+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: src/ApplicationReadyRoutes.tsx:50 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:299
+#, c-format
+msgid "Access denied"
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:51 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:300
+#, c-format
+msgid "Check your token is valid"
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:72
+#, c-format
+msgid "Couldn't access the server."
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:73
+#, c-format
+msgid "Could not infer instance id from url %1$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:109
+#, c-format
+msgid "HTTP status #%1$s: Server reported a problem"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:110
+#, c-format
+msgid "Got message: \"%1$s\" from: %2$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:127
+#, c-format
+msgid "No default instance"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:128
+#, c-format
+msgid ""
+"in order to use merchant backoffice, you should create the default instance"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:288
+#, c-format
+msgid "Server reported a problem: HTTP status #%1$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:289
+#, c-format
+msgid "Got message: %1$s from: %2$s"
+msgstr ""
+
+#: src/components/exception/login.tsx:46
+#, c-format
+msgid "Login required"
+msgstr ""
+
+#: src/components/exception/login.tsx:49
+#, c-format
+msgid ""
+"Please enter your auth token. Token should have \"secret-token:\" and start "
+"with Bearer or ApiKey"
+msgstr ""
+
+#: src/components/exception/login.tsx:86 src/components/modal/index.tsx:53
+#: src/components/modal/index.tsx:75 src/paths/admin/create/CreatePage.tsx:115
+#: src/paths/instance/orders/create/CreatePage.tsx:325
+#: src/paths/instance/products/create/CreatePage.tsx:51
+#: src/paths/instance/products/list/Table.tsx:174
+#: src/paths/instance/products/list/Table.tsx:228
+#: src/paths/instance/products/update/UpdatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:134
+#, c-format
+msgid "Confirm"
+msgstr ""
+
+#: src/components/form/InputArray.tsx:72
+#, c-format
+msgid "The value %1$s is invalid for a payment url"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:67
+#: src/paths/instance/orders/list/index.tsx:123
+#, c-format
+msgid "pick a date"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:81
+#, c-format
+msgid "clear"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:83
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "never"
+msgstr ""
+
+#: src/components/form/InputImage.tsx:80
+#, c-format
+msgid "Image should be smaller than 1 MB"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:28
+#, c-format
+msgid "Country"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:30
+#: src/paths/admin/create/CreatePage.tsx:99
+#: src/paths/instance/transfers/list/Table.tsx:124
+#: src/paths/instance/update/UpdatePage.tsx:118
+#, c-format
+msgid "Address"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:34
+#, c-format
+msgid "Building number"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:35
+#, c-format
+msgid "Building name"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:36
+#, c-format
+msgid "Street"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:37
+#, c-format
+msgid "Post code"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:38
+#, c-format
+msgid "Town location"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:39
+#, c-format
+msgid "Town"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:40
+#, c-format
+msgid "District"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:41
+#, c-format
+msgid "Country subdivision"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:59
+#, c-format
+msgid "Product id"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:60
+#: src/components/product/ProductForm.tsx:99
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:122
+#: src/paths/instance/orders/list/Table.tsx:227
+#: src/paths/instance/products/list/Table.tsx:86
+#, c-format
+msgid "Description"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:73
+#: src/components/form/InputTaxes.tsx:81
+#: src/paths/admin/create/CreatePage.tsx:87 src/paths/admin/list/Table.tsx:110
+#: src/paths/instance/details/DetailPage.tsx:76
+#: src/paths/instance/update/UpdatePage.tsx:106
+#, c-format
+msgid "Name"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:102
+#, c-format
+msgid "loading..."
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:108
+#, c-format
+msgid "no products found"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:116
+#, c-format
+msgid "no results"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:33
+#, c-format
+msgid "Deleting"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:34
+#, c-format
+msgid "Changing"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:60
+#, c-format
+msgid "Manage token"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:83
+#, c-format
+msgid "Update"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:100
+#: src/paths/instance/orders/create/CreatePage.tsx:252
+#: src/paths/instance/orders/create/CreatePage.tsx:273
+#, c-format
+msgid "Remove"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:106 src/components/modal/index.tsx:52
+#: src/components/modal/index.tsx:73 src/paths/admin/create/CreatePage.tsx:114
+#: src/paths/instance/orders/create/CreatePage.tsx:324
+#: src/paths/instance/products/create/CreatePage.tsx:50
+#: src/paths/instance/products/list/Table.tsx:166
+#: src/paths/instance/products/list/Table.tsx:218
+#: src/paths/instance/products/update/UpdatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:88
+#: src/paths/instance/update/UpdatePage.tsx:133
+#, c-format
+msgid "Cancel"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:91
+#, c-format
+msgid "Manage stock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:93
+#, c-format
+msgid "Infinite"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:105
+#, c-format
+msgid "lost cannot be greater that current + incoming (max %1$s)"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:111
+#, c-format
+msgid "current stock will change from %1$s to %2$s"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:112
+#, c-format
+msgid "current stock will stay at %1$s"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:129
+#: src/paths/instance/products/list/Table.tsx:204
+#, c-format
+msgid "Incoming"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:130
+#: src/paths/instance/products/list/Table.tsx:205
+#, c-format
+msgid "Lost"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:142
+#, c-format
+msgid "Current"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:145
+#, c-format
+msgid "without stock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:150
+#, c-format
+msgid "Next restock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:152
+#, c-format
+msgid "Delivery address"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:73
+#, c-format
+msgid "this product has no taxes"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:77
+#: src/paths/instance/orders/details/DetailPage.tsx:145
+#: src/paths/instance/orders/details/DetailPage.tsx:296
+#: src/paths/instance/orders/list/Table.tsx:116
+#: src/paths/instance/transfers/create/CreatePage.tsx:84
+#, c-format
+msgid "Amount"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:78
+#, c-format
+msgid "currency and value separated with colon"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:84
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:78
+#, c-format
+msgid "Add"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:53
+#, c-format
+msgid "Instance"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:59
+#, c-format
+msgid "Settings"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:65
+#: src/paths/instance/orders/list/Table.tsx:60
+#, c-format
+msgid "Orders"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:71
+#: src/paths/instance/orders/create/CreatePage.tsx:258
+#: src/paths/instance/products/list/Table.tsx:48
+#, c-format
+msgid "Products"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:77
+#: src/paths/instance/transfers/list/Table.tsx:65
+#, c-format
+msgid "Transfers"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:87
+#, c-format
+msgid "Connection"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:112 src/paths/admin/list/Table.tsx:57
+#, c-format
+msgid "Instances"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:116
+#, c-format
+msgid "New"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:122
+#, c-format
+msgid "List"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:129
+#, c-format
+msgid "Log out"
+msgstr ""
+
+#: src/components/modal/index.tsx:74
+#, c-format
+msgid "Clear"
+msgstr ""
+
+#: src/components/modal/index.tsx:110 src/components/modal/index.tsx:111
+#, c-format
+msgid "should be the same"
+msgstr ""
+
+#: src/components/modal/index.tsx:111
+#, c-format
+msgid "cannot be the same as before"
+msgstr ""
+
+#: src/components/modal/index.tsx:114
+#, c-format
+msgid ""
+"You are updating the authorization token from instance %1$s with id %2$s"
+msgstr ""
+
+#: src/components/modal/index.tsx:124
+#, c-format
+msgid "Old token"
+msgstr ""
+
+#: src/components/modal/index.tsx:125
+#, c-format
+msgid "New token"
+msgstr ""
+
+#: src/components/modal/index.tsx:127
+#, c-format
+msgid "Clearing the auth token will mean public access to the instance"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:96
+#: src/paths/admin/create/CreatePage.tsx:85 src/paths/admin/list/Table.tsx:109
+#: src/paths/instance/transfers/list/Table.tsx:122
+#, c-format
+msgid "ID"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:98
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:121
+#: src/paths/instance/products/list/Table.tsx:85
+#, c-format
+msgid "Image"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:100
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:123
+#, c-format
+msgid "Unit"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:101
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:124
+#: src/paths/instance/products/list/Table.tsx:162
+#: src/paths/instance/products/list/Table.tsx:214
+#, c-format
+msgid "Price"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:103
+#: src/paths/instance/products/list/Table.tsx:90
+#, c-format
+msgid "Stock"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:105
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:128
+#: src/paths/instance/products/list/Table.tsx:88
+#, c-format
+msgid "Taxes"
+msgstr ""
+
+#: src/index.tsx:75
+#, c-format
+msgid "Server not found"
+msgstr ""
+
+#: src/index.tsx:85
+#, c-format
+msgid "Couldn't access the server"
+msgstr ""
+
+#: src/index.tsx:87 src/index.tsx:99
+#, c-format
+msgid "Got message %1$s from %2$s"
+msgstr ""
+
+#: src/index.tsx:97
+#, c-format
+msgid "Unexpected Error"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:108
+#, c-format
+msgid "Auth token"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:91
+#: src/paths/instance/details/DetailPage.tsx:77
+#: src/paths/instance/update/UpdatePage.tsx:110
+#, c-format
+msgid "Account address"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:93
+#: src/paths/instance/update/UpdatePage.tsx:112
+#, c-format
+msgid "Default max deposit fee"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:95
+#: src/paths/instance/update/UpdatePage.tsx:114
+#, c-format
+msgid "Default max wire fee"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:97
+#: src/paths/instance/update/UpdatePage.tsx:116
+#, c-format
+msgid "Default wire fee amortization"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:103
+#: src/paths/instance/update/UpdatePage.tsx:122
+#, c-format
+msgid "Jurisdiction"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:107
+#: src/paths/instance/update/UpdatePage.tsx:126
+#, c-format
+msgid "Default pay delay"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:109
+#: src/paths/instance/update/UpdatePage.tsx:128
+#, c-format
+msgid "Default wire transfer delay"
+msgstr ""
+
+#: src/paths/admin/create/index.tsx:58
+#, c-format
+msgid "could not create instance"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:63 src/paths/admin/list/Table.tsx:131
+#: src/paths/instance/transfers/list/Table.tsx:71
+#, c-format
+msgid "Delete"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:128
+#, c-format
+msgid "Edit"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:149
+#: src/paths/instance/products/list/Table.tsx:245
+#, c-format
+msgid "There is no instances yet, add more pressing the + sign"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:237
+#, c-format
+msgid "Inventory products"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:286
+#, c-format
+msgid "Total price"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:287
+#, c-format
+msgid "Total tax"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:289
+#: src/paths/instance/orders/create/CreatePage.tsx:297
+#, c-format
+msgid "Order price"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:295
+#, c-format
+msgid "Net"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:300
+#: src/paths/instance/orders/details/DetailPage.tsx:144
+#: src/paths/instance/orders/details/DetailPage.tsx:295
+#: src/paths/instance/orders/list/Table.tsx:117
+#, c-format
+msgid "Summary"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:302
+#, c-format
+msgid "Payments options"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:303
+#, c-format
+msgid "Auto refund deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:304
+#, c-format
+msgid "Refund deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:305
+#, c-format
+msgid "Pay deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:307
+#, c-format
+msgid "Delivery date"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:308
+#, c-format
+msgid "Location"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:312
+#, c-format
+msgid "Max fee"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:313
+#, c-format
+msgid "Max wire fee"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:314
+#, c-format
+msgid "Wire fee amortization"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:315
+#, c-format
+msgid "Fullfilment url"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:318
+#, c-format
+msgid "Extra information"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:44
+#, c-format
+msgid "select a product first"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:51
+#, c-format
+msgid "should be greater than 0"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:58
+#, c-format
+msgid ""
+"cannot be greater than current stock and quantity previously added. max: %1$s"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:64
+#, c-format
+msgid "cannot be greater than current stock %1$s"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:76
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:126
+#, c-format
+msgid "Quantity"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:92
+#: src/paths/instance/orders/details/DetailPage.tsx:235
+#: src/paths/instance/orders/details/DetailPage.tsx:333
+#, c-format
+msgid "Order"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:93
+#, c-format
+msgid "claimed"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:110
+#: src/paths/instance/orders/details/DetailPage.tsx:261
+#: src/paths/instance/orders/list/Table.tsx:136
+#, c-format
+msgid "copy url"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:126
+#: src/paths/instance/orders/details/DetailPage.tsx:349
+#, c-format
+msgid "pay at"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:127
+#: src/paths/instance/orders/details/DetailPage.tsx:350
+#, c-format
+msgid "created at"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:138
+#: src/paths/instance/orders/details/DetailPage.tsx:289
+#, c-format
+msgid "Timeline"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:142
+#: src/paths/instance/orders/details/DetailPage.tsx:293
+#, c-format
+msgid "Payment details"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:146
+#: src/paths/instance/orders/details/DetailPage.tsx:299
+#: src/paths/instance/orders/details/DetailPage.tsx:363
+#, c-format
+msgid "Order status"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:156
+#: src/paths/instance/orders/details/DetailPage.tsx:308
+#, c-format
+msgid "Product list"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:236
+#, c-format
+msgid "paid"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:238
+#, c-format
+msgid "wired"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:241
+#, c-format
+msgid "refunded"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:258
+#, c-format
+msgid "refund"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:297
+#, c-format
+msgid "Refunded amount"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:298
+#, c-format
+msgid "Deposit total"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:336
+#, c-format
+msgid "unpaid"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:364
+#, c-format
+msgid "Order status URL"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:365
+#, c-format
+msgid "Pay URI"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:383
+#, c-format
+msgid ""
+"Unknown order status. This is an error, please contact the administrator."
+msgstr ""
+
+#: src/paths/instance/orders/details/index.tsx:56
+#: src/paths/instance/orders/list/index.tsx:147
+#, c-format
+msgid "refund created successfully"
+msgstr ""
+
+#: src/paths/instance/orders/details/index.tsx:59
+#: src/paths/instance/orders/list/index.tsx:150
+#, c-format
+msgid "could not create the refund"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:111
+#, c-format
+msgid "load newer orders"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:115
+#, c-format
+msgid "Date"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:131
+#: src/paths/instance/orders/list/Table.tsx:223
+#, c-format
+msgid "Refund"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:145
+#, c-format
+msgid "load older orders"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:154
+#, c-format
+msgid "No orders has been found"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:202
+#, c-format
+msgid "date"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:203
+#, c-format
+msgid "amount"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:204
+#, c-format
+msgid "reason"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:224
+#, c-format
+msgid "Max refundable:"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "Reason"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "duplicated"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "requested by the customer"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "other"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:91
+#, c-format
+msgid "go to order id"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:107
+#, c-format
+msgid "Paid"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:108
+#, c-format
+msgid "Refunded"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:109
+#, c-format
+msgid "Not wired"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:110
+#, c-format
+msgid "All"
+msgstr ""
+
+#: src/paths/instance/products/create/index.tsx:48
+#: src/paths/instance/products/update/index.tsx:64
+#, c-format
+msgid "could not create product"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:87
+#, c-format
+msgid "Sell"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:89
+#, c-format
+msgid "Profit"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:91
+#, c-format
+msgid "Sold"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:59
+#, c-format
+msgid "product updated successfully"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:62
+#, c-format
+msgid "could not update the product"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:70
+#, c-format
+msgid "product delete successfully"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:73
+#, c-format
+msgid "could not delete the product"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:59
+#, c-format
+msgid "Tips"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:111
+#, c-format
+msgid "Committed amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:112
+#, c-format
+msgid "Exchange initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:113
+#, c-format
+msgid "Merchant initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:148
+#, c-format
+msgid "There is no tips yet, add more pressing the + sign"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:50
+#: src/paths/instance/transfers/create/CreatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:56
+#, c-format
+msgid "cannot be empty"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:51
+#, c-format
+msgid "check the id, doest look valid"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:52
+#, c-format
+msgid "should have 52 characters, current %1$s"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:57
+#, c-format
+msgid "URL doesn't have the right format"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:74
+#, c-format
+msgid "Transfer ID"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:76
+#, c-format
+msgid "Account Address"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:82
+#: src/paths/instance/transfers/list/Table.tsx:125
+#, c-format
+msgid "Exchange URL"
+msgstr ""
+
+#: src/paths/instance/transfers/create/index.tsx:49
+#, c-format
+msgid "could not inform transfer"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:118
+#, c-format
+msgid "load newer transfers"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:123
+#, c-format
+msgid "Credit"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:126
+#, c-format
+msgid "Confirmed"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:127
+#: src/paths/instance/transfers/list/index.tsx:60
+#, c-format
+msgid "Verified"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:128
+#, c-format
+msgid "Executed at"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "yes"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "no"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "unknown"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:145
+#, c-format
+msgid "load older transfers"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:154
+#, c-format
+msgid "There is no transfer yet, add more pressing the + sign"
+msgstr ""
diff --git a/packages/merchant-backoffice-ui/src/i18n/poheader 
b/packages/merchant-backoffice-ui/src/i18n/poheader
new file mode 100644
index 000000000..ee3fcd7be
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/i18n/poheader
@@ -0,0 +1,27 @@
+#  This file is part of GNU Taler
+#  (C) 2021 Taler Systems S.A.
+
+#  GNU Taler is free software; you can redistribute it and/or modify it under 
the
+#  terms of the GNU General Public License as published by the Free Software
+#  Foundation; either version 3, or (at your option) any later version.
+
+#  GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+#  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+#  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+#  You should have received a copy of the GNU General Public License along with
+#  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Taler Wallet\n"
+"Report-Msgid-Bugs-To: taler@gnu.org\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
diff --git a/packages/merchant-backoffice-ui/src/i18n/strings-prelude 
b/packages/merchant-backoffice-ui/src/i18n/strings-prelude
new file mode 100644
index 000000000..cca13afad
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/i18n/strings-prelude
@@ -0,0 +1,19 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/*eslint quote-props: ["error", "consistent"]*/
+export const strings: {[s: string]: any} = {};
+
diff --git a/packages/merchant-backoffice-ui/src/i18n/strings.ts 
b/packages/merchant-backoffice-ui/src/i18n/strings.ts
new file mode 100644
index 000000000..63e96949a
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/i18n/strings.ts
@@ -0,0 +1,3445 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/*eslint quote-props: ["error", "consistent"]*/
+export const strings: {[s: string]: any} = {};
+
+strings['de'] = {
+  "domain": "messages",
+  "locale_data": {
+    "messages": {
+      "": {
+        "domain": "messages",
+        "plural_forms": "nplurals=2; plural=(n != 1);",
+        "lang": ""
+      },
+      "Access denied": [
+        ""
+      ],
+      "Check your token is valid": [
+        ""
+      ],
+      "Couldn't access the server.": [
+        ""
+      ],
+      "Could not infer instance id from url %1$s": [
+        ""
+      ],
+      "HTTP status #%1$s: Server reported a problem": [
+        ""
+      ],
+      "Got message: \"%1$s\" from: %2$s": [
+        ""
+      ],
+      "No default instance": [
+        ""
+      ],
+      "in order to use merchant backoffice, you should create the default 
instance": [
+        ""
+      ],
+      "Server reported a problem: HTTP status #%1$s": [
+        ""
+      ],
+      "Got message: %1$s from: %2$s": [
+        ""
+      ],
+      "Login required": [
+        ""
+      ],
+      "Please enter your auth token. Token should have \"secret-token:\" and 
start with Bearer or ApiKey": [
+        ""
+      ],
+      "Confirm": [
+        ""
+      ],
+      "The value %1$s is invalid for a payment url": [
+        ""
+      ],
+      "pick a date": [
+        ""
+      ],
+      "clear": [
+        ""
+      ],
+      "never": [
+        ""
+      ],
+      "Image should be smaller than 1 MB": [
+        ""
+      ],
+      "Country": [
+        ""
+      ],
+      "Address": [
+        ""
+      ],
+      "Building number": [
+        ""
+      ],
+      "Building name": [
+        ""
+      ],
+      "Street": [
+        ""
+      ],
+      "Post code": [
+        ""
+      ],
+      "Town location": [
+        ""
+      ],
+      "Town": [
+        ""
+      ],
+      "District": [
+        ""
+      ],
+      "Country subdivision": [
+        ""
+      ],
+      "Product id": [
+        ""
+      ],
+      "Description": [
+        ""
+      ],
+      "Name": [
+        ""
+      ],
+      "loading...": [
+        ""
+      ],
+      "no products found": [
+        ""
+      ],
+      "no results": [
+        ""
+      ],
+      "Deleting": [
+        ""
+      ],
+      "Changing": [
+        ""
+      ],
+      "Manage token": [
+        ""
+      ],
+      "Update": [
+        ""
+      ],
+      "Remove": [
+        ""
+      ],
+      "Cancel": [
+        ""
+      ],
+      "Manage stock": [
+        ""
+      ],
+      "Infinite": [
+        ""
+      ],
+      "lost cannot be greater that current + incoming (max %1$s)": [
+        ""
+      ],
+      "current stock will change from %1$s to %2$s": [
+        ""
+      ],
+      "current stock will stay at %1$s": [
+        ""
+      ],
+      "Incoming": [
+        ""
+      ],
+      "Lost": [
+        ""
+      ],
+      "Current": [
+        ""
+      ],
+      "without stock": [
+        ""
+      ],
+      "Next restock": [
+        ""
+      ],
+      "Delivery address": [
+        ""
+      ],
+      "this product has no taxes": [
+        ""
+      ],
+      "Amount": [
+        ""
+      ],
+      "currency and value separated with colon": [
+        ""
+      ],
+      "Add": [
+        ""
+      ],
+      "Instance": [
+        ""
+      ],
+      "Settings": [
+        ""
+      ],
+      "Orders": [
+        ""
+      ],
+      "Products": [
+        ""
+      ],
+      "Transfers": [
+        ""
+      ],
+      "Connection": [
+        ""
+      ],
+      "Instances": [
+        ""
+      ],
+      "New": [
+        ""
+      ],
+      "List": [
+        ""
+      ],
+      "Log out": [
+        ""
+      ],
+      "Clear": [
+        ""
+      ],
+      "should be the same": [
+        ""
+      ],
+      "cannot be the same as before": [
+        ""
+      ],
+      "You are updating the authorization token from instance %1$s with id 
%2$s": [
+        ""
+      ],
+      "Old token": [
+        ""
+      ],
+      "New token": [
+        ""
+      ],
+      "Clearing the auth token will mean public access to the instance": [
+        ""
+      ],
+      "ID": [
+        ""
+      ],
+      "Image": [
+        ""
+      ],
+      "Unit": [
+        ""
+      ],
+      "Price": [
+        ""
+      ],
+      "Stock": [
+        ""
+      ],
+      "Taxes": [
+        ""
+      ],
+      "Server not found": [
+        ""
+      ],
+      "Couldn't access the server": [
+        ""
+      ],
+      "Got message %1$s from %2$s": [
+        ""
+      ],
+      "Unexpected Error": [
+        ""
+      ],
+      "Auth token": [
+        ""
+      ],
+      "Account address": [
+        ""
+      ],
+      "Default max deposit fee": [
+        ""
+      ],
+      "Default max wire fee": [
+        ""
+      ],
+      "Default wire fee amortization": [
+        ""
+      ],
+      "Jurisdiction": [
+        ""
+      ],
+      "Default pay delay": [
+        ""
+      ],
+      "Default wire transfer delay": [
+        ""
+      ],
+      "could not create instance": [
+        ""
+      ],
+      "Delete": [
+        ""
+      ],
+      "Edit": [
+        ""
+      ],
+      "There is no instances yet, add more pressing the + sign": [
+        ""
+      ],
+      "Inventory products": [
+        ""
+      ],
+      "Total price": [
+        ""
+      ],
+      "Total tax": [
+        ""
+      ],
+      "Order price": [
+        ""
+      ],
+      "Net": [
+        ""
+      ],
+      "Summary": [
+        ""
+      ],
+      "Payments options": [
+        ""
+      ],
+      "Auto refund deadline": [
+        ""
+      ],
+      "Refund deadline": [
+        ""
+      ],
+      "Pay deadline": [
+        ""
+      ],
+      "Delivery date": [
+        ""
+      ],
+      "Location": [
+        ""
+      ],
+      "Max fee": [
+        ""
+      ],
+      "Max wire fee": [
+        ""
+      ],
+      "Wire fee amortization": [
+        ""
+      ],
+      "Fullfilment url": [
+        ""
+      ],
+      "Extra information": [
+        ""
+      ],
+      "select a product first": [
+        ""
+      ],
+      "should be greater than 0": [
+        ""
+      ],
+      "cannot be greater than current stock and quantity previously added. 
max: %1$s": [
+        ""
+      ],
+      "cannot be greater than current stock %1$s": [
+        ""
+      ],
+      "Quantity": [
+        ""
+      ],
+      "Order": [
+        ""
+      ],
+      "claimed": [
+        ""
+      ],
+      "copy url": [
+        ""
+      ],
+      "pay at": [
+        ""
+      ],
+      "created at": [
+        ""
+      ],
+      "Timeline": [
+        ""
+      ],
+      "Payment details": [
+        ""
+      ],
+      "Order status": [
+        ""
+      ],
+      "Product list": [
+        ""
+      ],
+      "paid": [
+        ""
+      ],
+      "wired": [
+        ""
+      ],
+      "refunded": [
+        ""
+      ],
+      "refund": [
+        ""
+      ],
+      "Refunded amount": [
+        ""
+      ],
+      "Deposit total": [
+        ""
+      ],
+      "unpaid": [
+        ""
+      ],
+      "Order status URL": [
+        ""
+      ],
+      "Pay URI": [
+        ""
+      ],
+      "Unknown order status. This is an error, please contact the 
administrator.": [
+        ""
+      ],
+      "refund created successfully": [
+        ""
+      ],
+      "could not create the refund": [
+        ""
+      ],
+      "load newer orders": [
+        ""
+      ],
+      "Date": [
+        ""
+      ],
+      "Refund": [
+        ""
+      ],
+      "load older orders": [
+        ""
+      ],
+      "No orders has been found": [
+        ""
+      ],
+      "date": [
+        ""
+      ],
+      "amount": [
+        ""
+      ],
+      "reason": [
+        ""
+      ],
+      "Max refundable:": [
+        ""
+      ],
+      "Reason": [
+        ""
+      ],
+      "duplicated": [
+        ""
+      ],
+      "requested by the customer": [
+        ""
+      ],
+      "other": [
+        ""
+      ],
+      "go to order id": [
+        ""
+      ],
+      "Paid": [
+        ""
+      ],
+      "Refunded": [
+        ""
+      ],
+      "Not wired": [
+        ""
+      ],
+      "All": [
+        ""
+      ],
+      "could not create product": [
+        ""
+      ],
+      "Sell": [
+        ""
+      ],
+      "Profit": [
+        ""
+      ],
+      "Sold": [
+        ""
+      ],
+      "product updated successfully": [
+        ""
+      ],
+      "could not update the product": [
+        ""
+      ],
+      "product delete successfully": [
+        ""
+      ],
+      "could not delete the product": [
+        ""
+      ],
+      "Tips": [
+        ""
+      ],
+      "Committed amount": [
+        ""
+      ],
+      "Exchange initial amount": [
+        ""
+      ],
+      "Merchant initial amount": [
+        ""
+      ],
+      "There is no tips yet, add more pressing the + sign": [
+        ""
+      ],
+      "cannot be empty": [
+        ""
+      ],
+      "check the id, doest look valid": [
+        ""
+      ],
+      "should have 52 characters, current %1$s": [
+        ""
+      ],
+      "URL doesn't have the right format": [
+        ""
+      ],
+      "Transfer ID": [
+        ""
+      ],
+      "Account Address": [
+        ""
+      ],
+      "Exchange URL": [
+        ""
+      ],
+      "could not inform transfer": [
+        ""
+      ],
+      "load newer transfers": [
+        ""
+      ],
+      "Credit": [
+        ""
+      ],
+      "Confirmed": [
+        ""
+      ],
+      "Verified": [
+        ""
+      ],
+      "Executed at": [
+        ""
+      ],
+      "yes": [
+        ""
+      ],
+      "no": [
+        ""
+      ],
+      "unknown": [
+        ""
+      ],
+      "load older transfers": [
+        ""
+      ],
+      "There is no transfer yet, add more pressing the + sign": [
+        ""
+      ]
+    }
+  }
+};
+
+strings['en'] = {
+  "domain": "messages",
+  "locale_data": {
+    "messages": {
+      "": {
+        "domain": "messages",
+        "plural_forms": "nplurals=2; plural=(n != 1);",
+        "lang": ""
+      },
+      "Access denied": [
+        ""
+      ],
+      "Check your token is valid": [
+        ""
+      ],
+      "Couldn't access the server.": [
+        ""
+      ],
+      "Could not infer instance id from url %1$s": [
+        ""
+      ],
+      "HTTP status #%1$s: Server reported a problem": [
+        ""
+      ],
+      "Got message: \"%1$s\" from: %2$s": [
+        ""
+      ],
+      "No default instance": [
+        ""
+      ],
+      "in order to use merchant backoffice, you should create the default 
instance": [
+        ""
+      ],
+      "Server reported a problem: HTTP status #%1$s": [
+        ""
+      ],
+      "Got message: %1$s from: %2$s": [
+        ""
+      ],
+      "Login required": [
+        ""
+      ],
+      "Please enter your auth token. Token should have \"secret-token:\" and 
start with Bearer or ApiKey": [
+        ""
+      ],
+      "Confirm": [
+        ""
+      ],
+      "The value %1$s is invalid for a payment url": [
+        ""
+      ],
+      "pick a date": [
+        ""
+      ],
+      "clear": [
+        ""
+      ],
+      "never": [
+        ""
+      ],
+      "Image should be smaller than 1 MB": [
+        ""
+      ],
+      "Country": [
+        ""
+      ],
+      "Address": [
+        ""
+      ],
+      "Building number": [
+        ""
+      ],
+      "Building name": [
+        ""
+      ],
+      "Street": [
+        ""
+      ],
+      "Post code": [
+        ""
+      ],
+      "Town location": [
+        ""
+      ],
+      "Town": [
+        ""
+      ],
+      "District": [
+        ""
+      ],
+      "Country subdivision": [
+        ""
+      ],
+      "Product id": [
+        ""
+      ],
+      "Description": [
+        ""
+      ],
+      "Name": [
+        ""
+      ],
+      "loading...": [
+        ""
+      ],
+      "no products found": [
+        ""
+      ],
+      "no results": [
+        ""
+      ],
+      "Deleting": [
+        ""
+      ],
+      "Changing": [
+        ""
+      ],
+      "Manage token": [
+        ""
+      ],
+      "Update": [
+        ""
+      ],
+      "Remove": [
+        ""
+      ],
+      "Cancel": [
+        ""
+      ],
+      "Manage stock": [
+        ""
+      ],
+      "Infinite": [
+        ""
+      ],
+      "lost cannot be greater that current + incoming (max %1$s)": [
+        ""
+      ],
+      "current stock will change from %1$s to %2$s": [
+        ""
+      ],
+      "current stock will stay at %1$s": [
+        ""
+      ],
+      "Incoming": [
+        ""
+      ],
+      "Lost": [
+        ""
+      ],
+      "Current": [
+        ""
+      ],
+      "without stock": [
+        ""
+      ],
+      "Next restock": [
+        ""
+      ],
+      "Delivery address": [
+        ""
+      ],
+      "this product has no taxes": [
+        ""
+      ],
+      "Amount": [
+        ""
+      ],
+      "currency and value separated with colon": [
+        ""
+      ],
+      "Add": [
+        ""
+      ],
+      "Instance": [
+        ""
+      ],
+      "Settings": [
+        ""
+      ],
+      "Orders": [
+        ""
+      ],
+      "Products": [
+        ""
+      ],
+      "Transfers": [
+        ""
+      ],
+      "Connection": [
+        ""
+      ],
+      "Instances": [
+        ""
+      ],
+      "New": [
+        ""
+      ],
+      "List": [
+        ""
+      ],
+      "Log out": [
+        ""
+      ],
+      "Clear": [
+        ""
+      ],
+      "should be the same": [
+        ""
+      ],
+      "cannot be the same as before": [
+        ""
+      ],
+      "You are updating the authorization token from instance %1$s with id 
%2$s": [
+        ""
+      ],
+      "Old token": [
+        ""
+      ],
+      "New token": [
+        ""
+      ],
+      "Clearing the auth token will mean public access to the instance": [
+        ""
+      ],
+      "ID": [
+        ""
+      ],
+      "Image": [
+        ""
+      ],
+      "Unit": [
+        ""
+      ],
+      "Price": [
+        ""
+      ],
+      "Stock": [
+        ""
+      ],
+      "Taxes": [
+        ""
+      ],
+      "Server not found": [
+        ""
+      ],
+      "Couldn't access the server": [
+        ""
+      ],
+      "Got message %1$s from %2$s": [
+        ""
+      ],
+      "Unexpected Error": [
+        ""
+      ],
+      "Auth token": [
+        ""
+      ],
+      "Account address": [
+        ""
+      ],
+      "Default max deposit fee": [
+        ""
+      ],
+      "Default max wire fee": [
+        ""
+      ],
+      "Default wire fee amortization": [
+        ""
+      ],
+      "Jurisdiction": [
+        ""
+      ],
+      "Default pay delay": [
+        ""
+      ],
+      "Default wire transfer delay": [
+        ""
+      ],
+      "could not create instance": [
+        ""
+      ],
+      "Delete": [
+        ""
+      ],
+      "Edit": [
+        ""
+      ],
+      "There is no instances yet, add more pressing the + sign": [
+        ""
+      ],
+      "Inventory products": [
+        ""
+      ],
+      "Total price": [
+        ""
+      ],
+      "Total tax": [
+        ""
+      ],
+      "Order price": [
+        ""
+      ],
+      "Net": [
+        ""
+      ],
+      "Summary": [
+        ""
+      ],
+      "Payments options": [
+        ""
+      ],
+      "Auto refund deadline": [
+        ""
+      ],
+      "Refund deadline": [
+        ""
+      ],
+      "Pay deadline": [
+        ""
+      ],
+      "Delivery date": [
+        ""
+      ],
+      "Location": [
+        ""
+      ],
+      "Max fee": [
+        ""
+      ],
+      "Max wire fee": [
+        ""
+      ],
+      "Wire fee amortization": [
+        ""
+      ],
+      "Fullfilment url": [
+        ""
+      ],
+      "Extra information": [
+        ""
+      ],
+      "select a product first": [
+        ""
+      ],
+      "should be greater than 0": [
+        ""
+      ],
+      "cannot be greater than current stock and quantity previously added. 
max: %1$s": [
+        ""
+      ],
+      "cannot be greater than current stock %1$s": [
+        ""
+      ],
+      "Quantity": [
+        ""
+      ],
+      "Order": [
+        ""
+      ],
+      "claimed": [
+        ""
+      ],
+      "copy url": [
+        ""
+      ],
+      "pay at": [
+        ""
+      ],
+      "created at": [
+        ""
+      ],
+      "Timeline": [
+        ""
+      ],
+      "Payment details": [
+        ""
+      ],
+      "Order status": [
+        ""
+      ],
+      "Product list": [
+        ""
+      ],
+      "paid": [
+        ""
+      ],
+      "wired": [
+        ""
+      ],
+      "refunded": [
+        ""
+      ],
+      "refund": [
+        ""
+      ],
+      "Refunded amount": [
+        ""
+      ],
+      "Deposit total": [
+        ""
+      ],
+      "unpaid": [
+        ""
+      ],
+      "Order status URL": [
+        ""
+      ],
+      "Pay URI": [
+        ""
+      ],
+      "Unknown order status. This is an error, please contact the 
administrator.": [
+        ""
+      ],
+      "refund created successfully": [
+        ""
+      ],
+      "could not create the refund": [
+        ""
+      ],
+      "load newer orders": [
+        ""
+      ],
+      "Date": [
+        ""
+      ],
+      "Refund": [
+        ""
+      ],
+      "load older orders": [
+        ""
+      ],
+      "No orders has been found": [
+        ""
+      ],
+      "date": [
+        ""
+      ],
+      "amount": [
+        ""
+      ],
+      "reason": [
+        ""
+      ],
+      "Max refundable:": [
+        ""
+      ],
+      "Reason": [
+        ""
+      ],
+      "duplicated": [
+        ""
+      ],
+      "requested by the customer": [
+        ""
+      ],
+      "other": [
+        ""
+      ],
+      "go to order id": [
+        ""
+      ],
+      "Paid": [
+        ""
+      ],
+      "Refunded": [
+        ""
+      ],
+      "Not wired": [
+        ""
+      ],
+      "All": [
+        ""
+      ],
+      "could not create product": [
+        ""
+      ],
+      "Sell": [
+        ""
+      ],
+      "Profit": [
+        ""
+      ],
+      "Sold": [
+        ""
+      ],
+      "product updated successfully": [
+        ""
+      ],
+      "could not update the product": [
+        ""
+      ],
+      "product delete successfully": [
+        ""
+      ],
+      "could not delete the product": [
+        ""
+      ],
+      "Tips": [
+        ""
+      ],
+      "Committed amount": [
+        ""
+      ],
+      "Exchange initial amount": [
+        ""
+      ],
+      "Merchant initial amount": [
+        ""
+      ],
+      "There is no tips yet, add more pressing the + sign": [
+        ""
+      ],
+      "cannot be empty": [
+        ""
+      ],
+      "check the id, doest look valid": [
+        ""
+      ],
+      "should have 52 characters, current %1$s": [
+        ""
+      ],
+      "URL doesn't have the right format": [
+        ""
+      ],
+      "Transfer ID": [
+        ""
+      ],
+      "Account Address": [
+        ""
+      ],
+      "Exchange URL": [
+        ""
+      ],
+      "could not inform transfer": [
+        ""
+      ],
+      "load newer transfers": [
+        ""
+      ],
+      "Credit": [
+        ""
+      ],
+      "Confirmed": [
+        ""
+      ],
+      "Verified": [
+        ""
+      ],
+      "Executed at": [
+        ""
+      ],
+      "yes": [
+        ""
+      ],
+      "no": [
+        ""
+      ],
+      "unknown": [
+        ""
+      ],
+      "load older transfers": [
+        ""
+      ],
+      "There is no transfer yet, add more pressing the + sign": [
+        ""
+      ]
+    }
+  }
+};
+
+strings['es'] = {
+  "domain": "messages",
+  "locale_data": {
+    "messages": {
+      "": {
+        "domain": "messages",
+        "plural_forms": "nplurals=2; plural=(n != 1);",
+        "lang": ""
+      },
+      "Access denied": [
+        "Acceso denegado"
+      ],
+      "Check your token is valid": [
+        "Verifica que el token sea valido"
+      ],
+      "Couldn't access the server.": [
+        "No se pudo acceder al servidor"
+      ],
+      "Could not infer instance id from url %1$s": [
+        "No se pudo inferir el id de la instancia con la url %1$s"
+      ],
+      "HTTP status #%1$s: Server reported a problem": [
+        "HTTP status #%1$s: Servidor reporto un problema"
+      ],
+      "Got message: \"%1$s\" from: %2$s": [
+        "Recivimos el mensaje %1$s desde %2$s"
+      ],
+      "No default instance": [
+        "Sin instancia default"
+      ],
+      "in order to use merchant backoffice, you should create the default 
instance": [
+        "para usar el merchant backoffice, debería crear la instancia default"
+      ],
+      "Server reported a problem: HTTP status #%1$s": [
+        "Servidir reporto un problema: HTTP status #%1$s"
+      ],
+      "Got message: %1$s from: %2$s": [
+        "Recivimos el mensaje %1$s desde %2$s"
+      ],
+      "Login required": [
+        "Login necesario"
+      ],
+      "Please enter your auth token. Token should have \"secret-token:\" and 
start with Bearer or ApiKey": [
+        "Por favor ingrese su token de autorización. El token debe tener 
\"secret-token\" y comenzar con Bearer o ApiKey"
+      ],
+      "Confirm": [
+        "Confirmar"
+      ],
+      "The value %1$s is invalid for a payment url": [
+        "El valor %1$s es invalido para una URL de pago"
+      ],
+      "pick a date": [
+        "elegir una fecha"
+      ],
+      "clear": [
+        "Limpiar"
+      ],
+      "never": [
+        "nunca"
+      ],
+      "Image should be smaller than 1 MB": [
+        "La imagen debe ser mas chica que 1 MB"
+      ],
+      "Country": [
+        "País"
+      ],
+      "Address": [
+        "Dirección"
+      ],
+      "Building number": [
+        "Número de edificio"
+      ],
+      "Building name": [
+        "Nombre de edificio"
+      ],
+      "Street": [
+        "Calle"
+      ],
+      "Post code": [
+        "Código postal"
+      ],
+      "Town location": [
+        "Ubicación de ciudad"
+      ],
+      "Town": [
+        "Ciudad"
+      ],
+      "District": [
+        "Distrito"
+      ],
+      "Country subdivision": [
+        "Provincia"
+      ],
+      "Product id": [
+        "Id de producto"
+      ],
+      "Description": [
+        "Descripcion"
+      ],
+      "Name": [
+        "Nombre"
+      ],
+      "loading...": [
+        "Cargando..."
+      ],
+      "no products found": [
+        "No se encontraron productos"
+      ],
+      "no results": [
+        "Sin resultados"
+      ],
+      "Deleting": [
+        "Borrando"
+      ],
+      "Changing": [
+        "Cambiando"
+      ],
+      "Manage token": [
+        "Administrar token"
+      ],
+      "Update": [
+        "Actualizar"
+      ],
+      "Remove": [
+        "Eliminar"
+      ],
+      "Cancel": [
+        "Cancelar"
+      ],
+      "Manage stock": [
+        "Administrar stock"
+      ],
+      "Infinite": [
+        "Inifinito"
+      ],
+      "lost cannot be greater that current + incoming (max %1$s)": [
+        "no puede ser mayor al stock actual %1$s"
+      ],
+      "current stock will change from %1$s to %2$s": [
+        "stock actual cambiará desde %1$s a %2$s"
+      ],
+      "current stock will stay at %1$s": [
+        "stock actual seguirá en %1$s"
+      ],
+      "Incoming": [
+        "Ingresando"
+      ],
+      "Lost": [
+        "Perdido"
+      ],
+      "Current": [
+        "Actual"
+      ],
+      "without stock": [
+        "sin stock"
+      ],
+      "Next restock": [
+        "Próximo reabastecimiento"
+      ],
+      "Delivery address": [
+        "Dirección de entrega"
+      ],
+      "this product has no taxes": [
+        "este producto no tiene impuestos"
+      ],
+      "Amount": [
+        "Monto"
+      ],
+      "currency and value separated with colon": [
+        "Moneda y valor separado por dos puntos"
+      ],
+      "Add": [
+        "Agregar"
+      ],
+      "Instance": [
+        "Instancia"
+      ],
+      "Settings": [
+        "Configuración"
+      ],
+      "Orders": [
+        "Ordenes"
+      ],
+      "Products": [
+        "Productos"
+      ],
+      "Transfers": [
+        "Transferencias"
+      ],
+      "Connection": [
+        "Conexión"
+      ],
+      "Instances": [
+        "Instancias"
+      ],
+      "New": [
+        "Nuevo"
+      ],
+      "List": [
+        "Lista"
+      ],
+      "Log out": [
+        "Salir"
+      ],
+      "Clear": [
+        "Limpiar"
+      ],
+      "should be the same": [
+        "deberían ser iguales"
+      ],
+      "cannot be the same as before": [
+        "no puede ser igual al anterior"
+      ],
+      "You are updating the authorization token from instance %1$s with id 
%2$s": [
+        "Está actualizando el token de autorización para la instancia %1$s con 
id %2$s"
+      ],
+      "Old token": [
+        "Viejo token"
+      ],
+      "New token": [
+        "Nuevo token"
+      ],
+      "Clearing the auth token will mean public access to the instance": [
+        "Limpiar el token de autorización significa acceso publico a la 
instancia"
+      ],
+      "ID": [
+        "ID"
+      ],
+      "Image": [
+        "Imagen"
+      ],
+      "Unit": [
+        "Unidad"
+      ],
+      "Price": [
+        "Precio"
+      ],
+      "Stock": [
+        "Stock"
+      ],
+      "Taxes": [
+        "Impuesto"
+      ],
+      "Server not found": [
+        "Servidor no encontrado"
+      ],
+      "Couldn't access the server": [
+        "No se pudo aceder al servidor"
+      ],
+      "Got message %1$s from %2$s": [
+        "Recivimos el mensaje %1$s desde %2$s"
+      ],
+      "Unexpected Error": [
+        "Error inesperado"
+      ],
+      "Auth token": [
+        "Token de autorización"
+      ],
+      "Account address": [
+        "Dirección de cuenta"
+      ],
+      "Default max deposit fee": [
+        "Impuesto máximo de deposito por omisión"
+      ],
+      "Default max wire fee": [
+        "Impuesto máximo de transferencia por omisión"
+      ],
+      "Default wire fee amortization": [
+        "Amortización de impuesto de transferencia por omisión"
+      ],
+      "Jurisdiction": [
+        "Jurisdicción"
+      ],
+      "Default pay delay": [
+        "Retrazo de pago por omisión"
+      ],
+      "Default wire transfer delay": [
+        "Retrazo de transferencia por omisión"
+      ],
+      "could not create instance": [
+        "no se pudo crear la instancia"
+      ],
+      "Delete": [
+        "Borrando"
+      ],
+      "Edit": [
+        ""
+      ],
+      "There is no instances yet, add more pressing the + sign": [
+        "No hay instancias todavían, agregue mas presionando el signo +"
+      ],
+      "Inventory products": [
+        "Productos de inventario"
+      ],
+      "Total price": [
+        "Precio total"
+      ],
+      "Total tax": [
+        "Impuesto total"
+      ],
+      "Order price": [
+        "Precio de la orden"
+      ],
+      "Net": [
+        "Neto"
+      ],
+      "Summary": [
+        "Resumen"
+      ],
+      "Payments options": [
+        "Opciones de pago"
+      ],
+      "Auto refund deadline": [
+        "Plazo de reembolso automático"
+      ],
+      "Refund deadline": [
+        "Plazo de reembolso"
+      ],
+      "Pay deadline": [
+        "Plazo de pago"
+      ],
+      "Delivery date": [
+        "Fecha de entrega"
+      ],
+      "Location": [
+        "Ubicación"
+      ],
+      "Max fee": [
+        "Impuesto máximo"
+      ],
+      "Max wire fee": [
+        "Impuesto de transferencia máximo"
+      ],
+      "Wire fee amortization": [
+        "Amortización de impuesto de transferencia"
+      ],
+      "Fullfilment url": [
+        "URL de completitud"
+      ],
+      "Extra information": [
+        "Información extra"
+      ],
+      "select a product first": [
+        "seleccione un producto primero"
+      ],
+      "should be greater than 0": [
+        "La imagen debe ser mas chica que 1 MB"
+      ],
+      "cannot be greater than current stock and quantity previously added. 
max: %1$s": [
+        "no puede ser mayor al stock actual y la cantidad previamente 
agregada. máximo: %1$s"
+      ],
+      "cannot be greater than current stock %1$s": [
+        "no puede ser mayor al stock actual %1$s"
+      ],
+      "Quantity": [
+        "Cantidad"
+      ],
+      "Order": [
+        "Orden"
+      ],
+      "claimed": [
+        "reclamado"
+      ],
+      "copy url": [
+        "copiar url"
+      ],
+      "pay at": [
+        "pagar en"
+      ],
+      "created at": [
+        "creado"
+      ],
+      "Timeline": [
+        "Cronología"
+      ],
+      "Payment details": [
+        "Detalles de pago"
+      ],
+      "Order status": [
+        "Estado de orden"
+      ],
+      "Product list": [
+        "Lista de producto"
+      ],
+      "paid": [
+        "pagados"
+      ],
+      "wired": [
+        "transferido"
+      ],
+      "refunded": [
+        "reembolzado"
+      ],
+      "refund": [
+        "reembolzar"
+      ],
+      "Refunded amount": [
+        "Monto reembolzado"
+      ],
+      "Deposit total": [
+        "Total depositado"
+      ],
+      "unpaid": [
+        "impago"
+      ],
+      "Order status URL": [
+        "URL de estado de orden"
+      ],
+      "Pay URI": [
+        "URI de pago"
+      ],
+      "Unknown order status. This is an error, please contact the 
administrator.": [
+        "Estado de orden desconocido. Esto es un error, por favor contacte a 
su administrador"
+      ],
+      "refund created successfully": [
+        "reembolzo creado satisfactoriamente"
+      ],
+      "could not create the refund": [
+        "No se pudo aceder al servidor"
+      ],
+      "load newer orders": [
+        "cargar nuevas ordenes"
+      ],
+      "Date": [
+        "Fecha"
+      ],
+      "Refund": [
+        "Reembolzar"
+      ],
+      "load older orders": [
+        "cargar viejas ordenes"
+      ],
+      "No orders has been found": [
+        "No se enconraron ordenes"
+      ],
+      "date": [
+        "fecha"
+      ],
+      "amount": [
+        "monto"
+      ],
+      "reason": [
+        "razón"
+      ],
+      "Max refundable:": [
+        "Máximo reembolzable:"
+      ],
+      "Reason": [
+        "Razón"
+      ],
+      "duplicated": [
+        "duplicado"
+      ],
+      "requested by the customer": [
+        "pedido por el consumidor"
+      ],
+      "other": [
+        "otro"
+      ],
+      "go to order id": [
+        "ir a id de orden"
+      ],
+      "Paid": [
+        "Pagado"
+      ],
+      "Refunded": [
+        "Reembolzado"
+      ],
+      "Not wired": [
+        "No transferido"
+      ],
+      "All": [
+        "Todo"
+      ],
+      "could not create product": [
+        "no se pudo crear el producto"
+      ],
+      "Sell": [
+        "Venta"
+      ],
+      "Profit": [
+        "Ganancia"
+      ],
+      "Sold": [
+        "Vendido"
+      ],
+      "product updated successfully": [
+        "producto actualizado correctamente"
+      ],
+      "could not update the product": [
+        "no se pudo actualizar el producto"
+      ],
+      "product delete successfully": [
+        "producto fue eliminado correctamente"
+      ],
+      "could not delete the product": [
+        "no se pudo eliminar el producto"
+      ],
+      "Tips": [
+        "Propinas"
+      ],
+      "Committed amount": [
+        ""
+      ],
+      "Exchange initial amount": [
+        ""
+      ],
+      "Merchant initial amount": [
+        ""
+      ],
+      "There is no tips yet, add more pressing the + sign": [
+        "No hay propinas todavía, agregar mas presionando el signo +"
+      ],
+      "cannot be empty": [
+        "no puede ser vacío"
+      ],
+      "check the id, doest look valid": [
+        "verificar el id, no parece válido"
+      ],
+      "should have 52 characters, current %1$s": [
+        "debería tener 52 caracteres, actualmente %1$s"
+      ],
+      "URL doesn't have the right format": [
+        "La URL no tiene el formato correcto"
+      ],
+      "Transfer ID": [
+        "Transferencias"
+      ],
+      "Account Address": [
+        "Dirección de cuenta"
+      ],
+      "Exchange URL": [
+        "URL del Exchange"
+      ],
+      "could not inform transfer": [
+        "no se pudo crear la instancia"
+      ],
+      "load newer transfers": [
+        "cargar nuevas ordenes"
+      ],
+      "Credit": [
+        "Crédito"
+      ],
+      "Confirmed": [
+        "Confirmar"
+      ],
+      "Verified": [
+        "Verificado"
+      ],
+      "Executed at": [
+        "creado"
+      ],
+      "yes": [
+        "si"
+      ],
+      "no": [
+        "no"
+      ],
+      "unknown": [
+        "desconocido"
+      ],
+      "load older transfers": [
+        "cargar viejas transferencias"
+      ],
+      "There is no transfer yet, add more pressing the + sign": [
+        "No hay transferencias todavía, agregar mas presionando el signo +"
+      ]
+    }
+  }
+};
+
+strings['fr'] = {
+  "domain": "messages",
+  "locale_data": {
+    "messages": {
+      "": {
+        "domain": "messages",
+        "plural_forms": "nplurals=2; plural=(n != 1);",
+        "lang": ""
+      },
+      "Access denied": [
+        ""
+      ],
+      "Check your token is valid": [
+        ""
+      ],
+      "Couldn't access the server.": [
+        ""
+      ],
+      "Could not infer instance id from url %1$s": [
+        ""
+      ],
+      "HTTP status #%1$s: Server reported a problem": [
+        ""
+      ],
+      "Got message: \"%1$s\" from: %2$s": [
+        ""
+      ],
+      "No default instance": [
+        ""
+      ],
+      "in order to use merchant backoffice, you should create the default 
instance": [
+        ""
+      ],
+      "Server reported a problem: HTTP status #%1$s": [
+        ""
+      ],
+      "Got message: %1$s from: %2$s": [
+        ""
+      ],
+      "Login required": [
+        ""
+      ],
+      "Please enter your auth token. Token should have \"secret-token:\" and 
start with Bearer or ApiKey": [
+        ""
+      ],
+      "Confirm": [
+        ""
+      ],
+      "The value %1$s is invalid for a payment url": [
+        ""
+      ],
+      "pick a date": [
+        ""
+      ],
+      "clear": [
+        ""
+      ],
+      "never": [
+        ""
+      ],
+      "Image should be smaller than 1 MB": [
+        ""
+      ],
+      "Country": [
+        ""
+      ],
+      "Address": [
+        ""
+      ],
+      "Building number": [
+        ""
+      ],
+      "Building name": [
+        ""
+      ],
+      "Street": [
+        ""
+      ],
+      "Post code": [
+        ""
+      ],
+      "Town location": [
+        ""
+      ],
+      "Town": [
+        ""
+      ],
+      "District": [
+        ""
+      ],
+      "Country subdivision": [
+        ""
+      ],
+      "Product id": [
+        ""
+      ],
+      "Description": [
+        ""
+      ],
+      "Name": [
+        ""
+      ],
+      "loading...": [
+        ""
+      ],
+      "no products found": [
+        ""
+      ],
+      "no results": [
+        ""
+      ],
+      "Deleting": [
+        ""
+      ],
+      "Changing": [
+        ""
+      ],
+      "Manage token": [
+        ""
+      ],
+      "Update": [
+        ""
+      ],
+      "Remove": [
+        ""
+      ],
+      "Cancel": [
+        ""
+      ],
+      "Manage stock": [
+        ""
+      ],
+      "Infinite": [
+        ""
+      ],
+      "lost cannot be greater that current + incoming (max %1$s)": [
+        ""
+      ],
+      "current stock will change from %1$s to %2$s": [
+        ""
+      ],
+      "current stock will stay at %1$s": [
+        ""
+      ],
+      "Incoming": [
+        ""
+      ],
+      "Lost": [
+        ""
+      ],
+      "Current": [
+        ""
+      ],
+      "without stock": [
+        ""
+      ],
+      "Next restock": [
+        ""
+      ],
+      "Delivery address": [
+        ""
+      ],
+      "this product has no taxes": [
+        ""
+      ],
+      "Amount": [
+        ""
+      ],
+      "currency and value separated with colon": [
+        ""
+      ],
+      "Add": [
+        ""
+      ],
+      "Instance": [
+        ""
+      ],
+      "Settings": [
+        ""
+      ],
+      "Orders": [
+        ""
+      ],
+      "Products": [
+        ""
+      ],
+      "Transfers": [
+        ""
+      ],
+      "Connection": [
+        ""
+      ],
+      "Instances": [
+        ""
+      ],
+      "New": [
+        ""
+      ],
+      "List": [
+        ""
+      ],
+      "Log out": [
+        ""
+      ],
+      "Clear": [
+        ""
+      ],
+      "should be the same": [
+        ""
+      ],
+      "cannot be the same as before": [
+        ""
+      ],
+      "You are updating the authorization token from instance %1$s with id 
%2$s": [
+        ""
+      ],
+      "Old token": [
+        ""
+      ],
+      "New token": [
+        ""
+      ],
+      "Clearing the auth token will mean public access to the instance": [
+        ""
+      ],
+      "ID": [
+        ""
+      ],
+      "Image": [
+        ""
+      ],
+      "Unit": [
+        ""
+      ],
+      "Price": [
+        ""
+      ],
+      "Stock": [
+        ""
+      ],
+      "Taxes": [
+        ""
+      ],
+      "Server not found": [
+        ""
+      ],
+      "Couldn't access the server": [
+        ""
+      ],
+      "Got message %1$s from %2$s": [
+        ""
+      ],
+      "Unexpected Error": [
+        ""
+      ],
+      "Auth token": [
+        ""
+      ],
+      "Account address": [
+        ""
+      ],
+      "Default max deposit fee": [
+        ""
+      ],
+      "Default max wire fee": [
+        ""
+      ],
+      "Default wire fee amortization": [
+        ""
+      ],
+      "Jurisdiction": [
+        ""
+      ],
+      "Default pay delay": [
+        ""
+      ],
+      "Default wire transfer delay": [
+        ""
+      ],
+      "could not create instance": [
+        ""
+      ],
+      "Delete": [
+        ""
+      ],
+      "Edit": [
+        ""
+      ],
+      "There is no instances yet, add more pressing the + sign": [
+        ""
+      ],
+      "Inventory products": [
+        ""
+      ],
+      "Total price": [
+        ""
+      ],
+      "Total tax": [
+        ""
+      ],
+      "Order price": [
+        ""
+      ],
+      "Net": [
+        ""
+      ],
+      "Summary": [
+        ""
+      ],
+      "Payments options": [
+        ""
+      ],
+      "Auto refund deadline": [
+        ""
+      ],
+      "Refund deadline": [
+        ""
+      ],
+      "Pay deadline": [
+        ""
+      ],
+      "Delivery date": [
+        ""
+      ],
+      "Location": [
+        ""
+      ],
+      "Max fee": [
+        ""
+      ],
+      "Max wire fee": [
+        ""
+      ],
+      "Wire fee amortization": [
+        ""
+      ],
+      "Fullfilment url": [
+        ""
+      ],
+      "Extra information": [
+        ""
+      ],
+      "select a product first": [
+        ""
+      ],
+      "should be greater than 0": [
+        ""
+      ],
+      "cannot be greater than current stock and quantity previously added. 
max: %1$s": [
+        ""
+      ],
+      "cannot be greater than current stock %1$s": [
+        ""
+      ],
+      "Quantity": [
+        ""
+      ],
+      "Order": [
+        ""
+      ],
+      "claimed": [
+        ""
+      ],
+      "copy url": [
+        ""
+      ],
+      "pay at": [
+        ""
+      ],
+      "created at": [
+        ""
+      ],
+      "Timeline": [
+        ""
+      ],
+      "Payment details": [
+        ""
+      ],
+      "Order status": [
+        ""
+      ],
+      "Product list": [
+        ""
+      ],
+      "paid": [
+        ""
+      ],
+      "wired": [
+        ""
+      ],
+      "refunded": [
+        ""
+      ],
+      "refund": [
+        ""
+      ],
+      "Refunded amount": [
+        ""
+      ],
+      "Deposit total": [
+        ""
+      ],
+      "unpaid": [
+        ""
+      ],
+      "Order status URL": [
+        ""
+      ],
+      "Pay URI": [
+        ""
+      ],
+      "Unknown order status. This is an error, please contact the 
administrator.": [
+        ""
+      ],
+      "refund created successfully": [
+        ""
+      ],
+      "could not create the refund": [
+        ""
+      ],
+      "load newer orders": [
+        ""
+      ],
+      "Date": [
+        ""
+      ],
+      "Refund": [
+        ""
+      ],
+      "load older orders": [
+        ""
+      ],
+      "No orders has been found": [
+        ""
+      ],
+      "date": [
+        ""
+      ],
+      "amount": [
+        ""
+      ],
+      "reason": [
+        ""
+      ],
+      "Max refundable:": [
+        ""
+      ],
+      "Reason": [
+        ""
+      ],
+      "duplicated": [
+        ""
+      ],
+      "requested by the customer": [
+        ""
+      ],
+      "other": [
+        ""
+      ],
+      "go to order id": [
+        ""
+      ],
+      "Paid": [
+        ""
+      ],
+      "Refunded": [
+        ""
+      ],
+      "Not wired": [
+        ""
+      ],
+      "All": [
+        ""
+      ],
+      "could not create product": [
+        ""
+      ],
+      "Sell": [
+        ""
+      ],
+      "Profit": [
+        ""
+      ],
+      "Sold": [
+        ""
+      ],
+      "product updated successfully": [
+        ""
+      ],
+      "could not update the product": [
+        ""
+      ],
+      "product delete successfully": [
+        ""
+      ],
+      "could not delete the product": [
+        ""
+      ],
+      "Tips": [
+        ""
+      ],
+      "Committed amount": [
+        ""
+      ],
+      "Exchange initial amount": [
+        ""
+      ],
+      "Merchant initial amount": [
+        ""
+      ],
+      "There is no tips yet, add more pressing the + sign": [
+        ""
+      ],
+      "cannot be empty": [
+        ""
+      ],
+      "check the id, doest look valid": [
+        ""
+      ],
+      "should have 52 characters, current %1$s": [
+        ""
+      ],
+      "URL doesn't have the right format": [
+        ""
+      ],
+      "Transfer ID": [
+        ""
+      ],
+      "Account Address": [
+        ""
+      ],
+      "Exchange URL": [
+        ""
+      ],
+      "could not inform transfer": [
+        ""
+      ],
+      "load newer transfers": [
+        ""
+      ],
+      "Credit": [
+        ""
+      ],
+      "Confirmed": [
+        ""
+      ],
+      "Verified": [
+        ""
+      ],
+      "Executed at": [
+        ""
+      ],
+      "yes": [
+        ""
+      ],
+      "no": [
+        ""
+      ],
+      "unknown": [
+        ""
+      ],
+      "load older transfers": [
+        ""
+      ],
+      "There is no transfer yet, add more pressing the + sign": [
+        ""
+      ]
+    }
+  }
+};
+
+strings['it'] = {
+  "domain": "messages",
+  "locale_data": {
+    "messages": {
+      "": {
+        "domain": "messages",
+        "plural_forms": "nplurals=2; plural=(n != 1);",
+        "lang": ""
+      },
+      "Access denied": [
+        ""
+      ],
+      "Check your token is valid": [
+        ""
+      ],
+      "Couldn't access the server.": [
+        ""
+      ],
+      "Could not infer instance id from url %1$s": [
+        ""
+      ],
+      "HTTP status #%1$s: Server reported a problem": [
+        ""
+      ],
+      "Got message: \"%1$s\" from: %2$s": [
+        ""
+      ],
+      "No default instance": [
+        ""
+      ],
+      "in order to use merchant backoffice, you should create the default 
instance": [
+        ""
+      ],
+      "Server reported a problem: HTTP status #%1$s": [
+        ""
+      ],
+      "Got message: %1$s from: %2$s": [
+        ""
+      ],
+      "Login required": [
+        ""
+      ],
+      "Please enter your auth token. Token should have \"secret-token:\" and 
start with Bearer or ApiKey": [
+        ""
+      ],
+      "Confirm": [
+        ""
+      ],
+      "The value %1$s is invalid for a payment url": [
+        ""
+      ],
+      "pick a date": [
+        ""
+      ],
+      "clear": [
+        ""
+      ],
+      "never": [
+        ""
+      ],
+      "Image should be smaller than 1 MB": [
+        ""
+      ],
+      "Country": [
+        ""
+      ],
+      "Address": [
+        ""
+      ],
+      "Building number": [
+        ""
+      ],
+      "Building name": [
+        ""
+      ],
+      "Street": [
+        ""
+      ],
+      "Post code": [
+        ""
+      ],
+      "Town location": [
+        ""
+      ],
+      "Town": [
+        ""
+      ],
+      "District": [
+        ""
+      ],
+      "Country subdivision": [
+        ""
+      ],
+      "Product id": [
+        ""
+      ],
+      "Description": [
+        ""
+      ],
+      "Name": [
+        ""
+      ],
+      "loading...": [
+        ""
+      ],
+      "no products found": [
+        ""
+      ],
+      "no results": [
+        ""
+      ],
+      "Deleting": [
+        ""
+      ],
+      "Changing": [
+        ""
+      ],
+      "Manage token": [
+        ""
+      ],
+      "Update": [
+        ""
+      ],
+      "Remove": [
+        ""
+      ],
+      "Cancel": [
+        ""
+      ],
+      "Manage stock": [
+        ""
+      ],
+      "Infinite": [
+        ""
+      ],
+      "lost cannot be greater that current + incoming (max %1$s)": [
+        ""
+      ],
+      "current stock will change from %1$s to %2$s": [
+        ""
+      ],
+      "current stock will stay at %1$s": [
+        ""
+      ],
+      "Incoming": [
+        ""
+      ],
+      "Lost": [
+        ""
+      ],
+      "Current": [
+        ""
+      ],
+      "without stock": [
+        ""
+      ],
+      "Next restock": [
+        ""
+      ],
+      "Delivery address": [
+        ""
+      ],
+      "this product has no taxes": [
+        ""
+      ],
+      "Amount": [
+        ""
+      ],
+      "currency and value separated with colon": [
+        ""
+      ],
+      "Add": [
+        ""
+      ],
+      "Instance": [
+        ""
+      ],
+      "Settings": [
+        ""
+      ],
+      "Orders": [
+        ""
+      ],
+      "Products": [
+        ""
+      ],
+      "Transfers": [
+        ""
+      ],
+      "Connection": [
+        ""
+      ],
+      "Instances": [
+        ""
+      ],
+      "New": [
+        ""
+      ],
+      "List": [
+        ""
+      ],
+      "Log out": [
+        ""
+      ],
+      "Clear": [
+        ""
+      ],
+      "should be the same": [
+        ""
+      ],
+      "cannot be the same as before": [
+        ""
+      ],
+      "You are updating the authorization token from instance %1$s with id 
%2$s": [
+        ""
+      ],
+      "Old token": [
+        ""
+      ],
+      "New token": [
+        ""
+      ],
+      "Clearing the auth token will mean public access to the instance": [
+        ""
+      ],
+      "ID": [
+        ""
+      ],
+      "Image": [
+        ""
+      ],
+      "Unit": [
+        ""
+      ],
+      "Price": [
+        ""
+      ],
+      "Stock": [
+        ""
+      ],
+      "Taxes": [
+        ""
+      ],
+      "Server not found": [
+        ""
+      ],
+      "Couldn't access the server": [
+        ""
+      ],
+      "Got message %1$s from %2$s": [
+        ""
+      ],
+      "Unexpected Error": [
+        ""
+      ],
+      "Auth token": [
+        ""
+      ],
+      "Account address": [
+        ""
+      ],
+      "Default max deposit fee": [
+        ""
+      ],
+      "Default max wire fee": [
+        ""
+      ],
+      "Default wire fee amortization": [
+        ""
+      ],
+      "Jurisdiction": [
+        ""
+      ],
+      "Default pay delay": [
+        ""
+      ],
+      "Default wire transfer delay": [
+        ""
+      ],
+      "could not create instance": [
+        ""
+      ],
+      "Delete": [
+        ""
+      ],
+      "Edit": [
+        ""
+      ],
+      "There is no instances yet, add more pressing the + sign": [
+        ""
+      ],
+      "Inventory products": [
+        ""
+      ],
+      "Total price": [
+        ""
+      ],
+      "Total tax": [
+        ""
+      ],
+      "Order price": [
+        ""
+      ],
+      "Net": [
+        ""
+      ],
+      "Summary": [
+        ""
+      ],
+      "Payments options": [
+        ""
+      ],
+      "Auto refund deadline": [
+        ""
+      ],
+      "Refund deadline": [
+        ""
+      ],
+      "Pay deadline": [
+        ""
+      ],
+      "Delivery date": [
+        ""
+      ],
+      "Location": [
+        ""
+      ],
+      "Max fee": [
+        ""
+      ],
+      "Max wire fee": [
+        ""
+      ],
+      "Wire fee amortization": [
+        ""
+      ],
+      "Fullfilment url": [
+        ""
+      ],
+      "Extra information": [
+        ""
+      ],
+      "select a product first": [
+        ""
+      ],
+      "should be greater than 0": [
+        ""
+      ],
+      "cannot be greater than current stock and quantity previously added. 
max: %1$s": [
+        ""
+      ],
+      "cannot be greater than current stock %1$s": [
+        ""
+      ],
+      "Quantity": [
+        ""
+      ],
+      "Order": [
+        ""
+      ],
+      "claimed": [
+        ""
+      ],
+      "copy url": [
+        ""
+      ],
+      "pay at": [
+        ""
+      ],
+      "created at": [
+        ""
+      ],
+      "Timeline": [
+        ""
+      ],
+      "Payment details": [
+        ""
+      ],
+      "Order status": [
+        ""
+      ],
+      "Product list": [
+        ""
+      ],
+      "paid": [
+        ""
+      ],
+      "wired": [
+        ""
+      ],
+      "refunded": [
+        ""
+      ],
+      "refund": [
+        ""
+      ],
+      "Refunded amount": [
+        ""
+      ],
+      "Deposit total": [
+        ""
+      ],
+      "unpaid": [
+        ""
+      ],
+      "Order status URL": [
+        ""
+      ],
+      "Pay URI": [
+        ""
+      ],
+      "Unknown order status. This is an error, please contact the 
administrator.": [
+        ""
+      ],
+      "refund created successfully": [
+        ""
+      ],
+      "could not create the refund": [
+        ""
+      ],
+      "load newer orders": [
+        ""
+      ],
+      "Date": [
+        ""
+      ],
+      "Refund": [
+        ""
+      ],
+      "load older orders": [
+        ""
+      ],
+      "No orders has been found": [
+        ""
+      ],
+      "date": [
+        ""
+      ],
+      "amount": [
+        ""
+      ],
+      "reason": [
+        ""
+      ],
+      "Max refundable:": [
+        ""
+      ],
+      "Reason": [
+        ""
+      ],
+      "duplicated": [
+        ""
+      ],
+      "requested by the customer": [
+        ""
+      ],
+      "other": [
+        ""
+      ],
+      "go to order id": [
+        ""
+      ],
+      "Paid": [
+        ""
+      ],
+      "Refunded": [
+        ""
+      ],
+      "Not wired": [
+        ""
+      ],
+      "All": [
+        ""
+      ],
+      "could not create product": [
+        ""
+      ],
+      "Sell": [
+        ""
+      ],
+      "Profit": [
+        ""
+      ],
+      "Sold": [
+        ""
+      ],
+      "product updated successfully": [
+        ""
+      ],
+      "could not update the product": [
+        ""
+      ],
+      "product delete successfully": [
+        ""
+      ],
+      "could not delete the product": [
+        ""
+      ],
+      "Tips": [
+        ""
+      ],
+      "Committed amount": [
+        ""
+      ],
+      "Exchange initial amount": [
+        ""
+      ],
+      "Merchant initial amount": [
+        ""
+      ],
+      "There is no tips yet, add more pressing the + sign": [
+        ""
+      ],
+      "cannot be empty": [
+        ""
+      ],
+      "check the id, doest look valid": [
+        ""
+      ],
+      "should have 52 characters, current %1$s": [
+        ""
+      ],
+      "URL doesn't have the right format": [
+        ""
+      ],
+      "Transfer ID": [
+        ""
+      ],
+      "Account Address": [
+        ""
+      ],
+      "Exchange URL": [
+        ""
+      ],
+      "could not inform transfer": [
+        ""
+      ],
+      "load newer transfers": [
+        ""
+      ],
+      "Credit": [
+        ""
+      ],
+      "Confirmed": [
+        ""
+      ],
+      "Verified": [
+        ""
+      ],
+      "Executed at": [
+        ""
+      ],
+      "yes": [
+        ""
+      ],
+      "no": [
+        ""
+      ],
+      "unknown": [
+        ""
+      ],
+      "load older transfers": [
+        ""
+      ],
+      "There is no transfer yet, add more pressing the + sign": [
+        ""
+      ]
+    }
+  }
+};
+
+strings['sv'] = {
+  "domain": "messages",
+  "locale_data": {
+    "messages": {
+      "": {
+        "domain": "messages",
+        "plural_forms": "nplurals=2; plural=(n != 1);",
+        "lang": ""
+      },
+      "Access denied": [
+        ""
+      ],
+      "Check your token is valid": [
+        ""
+      ],
+      "Couldn't access the server.": [
+        ""
+      ],
+      "Could not infer instance id from url %1$s": [
+        ""
+      ],
+      "HTTP status #%1$s: Server reported a problem": [
+        ""
+      ],
+      "Got message: \"%1$s\" from: %2$s": [
+        ""
+      ],
+      "No default instance": [
+        ""
+      ],
+      "in order to use merchant backoffice, you should create the default 
instance": [
+        ""
+      ],
+      "Server reported a problem: HTTP status #%1$s": [
+        ""
+      ],
+      "Got message: %1$s from: %2$s": [
+        ""
+      ],
+      "Login required": [
+        ""
+      ],
+      "Please enter your auth token. Token should have \"secret-token:\" and 
start with Bearer or ApiKey": [
+        ""
+      ],
+      "Confirm": [
+        ""
+      ],
+      "The value %1$s is invalid for a payment url": [
+        ""
+      ],
+      "pick a date": [
+        ""
+      ],
+      "clear": [
+        ""
+      ],
+      "never": [
+        ""
+      ],
+      "Image should be smaller than 1 MB": [
+        ""
+      ],
+      "Country": [
+        ""
+      ],
+      "Address": [
+        ""
+      ],
+      "Building number": [
+        ""
+      ],
+      "Building name": [
+        ""
+      ],
+      "Street": [
+        ""
+      ],
+      "Post code": [
+        ""
+      ],
+      "Town location": [
+        ""
+      ],
+      "Town": [
+        ""
+      ],
+      "District": [
+        ""
+      ],
+      "Country subdivision": [
+        ""
+      ],
+      "Product id": [
+        ""
+      ],
+      "Description": [
+        ""
+      ],
+      "Name": [
+        ""
+      ],
+      "loading...": [
+        ""
+      ],
+      "no products found": [
+        ""
+      ],
+      "no results": [
+        ""
+      ],
+      "Deleting": [
+        ""
+      ],
+      "Changing": [
+        ""
+      ],
+      "Manage token": [
+        ""
+      ],
+      "Update": [
+        ""
+      ],
+      "Remove": [
+        ""
+      ],
+      "Cancel": [
+        ""
+      ],
+      "Manage stock": [
+        ""
+      ],
+      "Infinite": [
+        ""
+      ],
+      "lost cannot be greater that current + incoming (max %1$s)": [
+        ""
+      ],
+      "current stock will change from %1$s to %2$s": [
+        ""
+      ],
+      "current stock will stay at %1$s": [
+        ""
+      ],
+      "Incoming": [
+        ""
+      ],
+      "Lost": [
+        ""
+      ],
+      "Current": [
+        ""
+      ],
+      "without stock": [
+        ""
+      ],
+      "Next restock": [
+        ""
+      ],
+      "Delivery address": [
+        ""
+      ],
+      "this product has no taxes": [
+        ""
+      ],
+      "Amount": [
+        ""
+      ],
+      "currency and value separated with colon": [
+        ""
+      ],
+      "Add": [
+        ""
+      ],
+      "Instance": [
+        ""
+      ],
+      "Settings": [
+        ""
+      ],
+      "Orders": [
+        ""
+      ],
+      "Products": [
+        ""
+      ],
+      "Transfers": [
+        ""
+      ],
+      "Connection": [
+        ""
+      ],
+      "Instances": [
+        ""
+      ],
+      "New": [
+        ""
+      ],
+      "List": [
+        ""
+      ],
+      "Log out": [
+        ""
+      ],
+      "Clear": [
+        ""
+      ],
+      "should be the same": [
+        ""
+      ],
+      "cannot be the same as before": [
+        ""
+      ],
+      "You are updating the authorization token from instance %1$s with id 
%2$s": [
+        ""
+      ],
+      "Old token": [
+        ""
+      ],
+      "New token": [
+        ""
+      ],
+      "Clearing the auth token will mean public access to the instance": [
+        ""
+      ],
+      "ID": [
+        ""
+      ],
+      "Image": [
+        ""
+      ],
+      "Unit": [
+        ""
+      ],
+      "Price": [
+        ""
+      ],
+      "Stock": [
+        ""
+      ],
+      "Taxes": [
+        ""
+      ],
+      "Server not found": [
+        ""
+      ],
+      "Couldn't access the server": [
+        ""
+      ],
+      "Got message %1$s from %2$s": [
+        ""
+      ],
+      "Unexpected Error": [
+        ""
+      ],
+      "Auth token": [
+        ""
+      ],
+      "Account address": [
+        ""
+      ],
+      "Default max deposit fee": [
+        ""
+      ],
+      "Default max wire fee": [
+        ""
+      ],
+      "Default wire fee amortization": [
+        ""
+      ],
+      "Jurisdiction": [
+        ""
+      ],
+      "Default pay delay": [
+        ""
+      ],
+      "Default wire transfer delay": [
+        ""
+      ],
+      "could not create instance": [
+        ""
+      ],
+      "Delete": [
+        ""
+      ],
+      "Edit": [
+        ""
+      ],
+      "There is no instances yet, add more pressing the + sign": [
+        ""
+      ],
+      "Inventory products": [
+        ""
+      ],
+      "Total price": [
+        ""
+      ],
+      "Total tax": [
+        ""
+      ],
+      "Order price": [
+        ""
+      ],
+      "Net": [
+        ""
+      ],
+      "Summary": [
+        ""
+      ],
+      "Payments options": [
+        ""
+      ],
+      "Auto refund deadline": [
+        ""
+      ],
+      "Refund deadline": [
+        ""
+      ],
+      "Pay deadline": [
+        ""
+      ],
+      "Delivery date": [
+        ""
+      ],
+      "Location": [
+        ""
+      ],
+      "Max fee": [
+        ""
+      ],
+      "Max wire fee": [
+        ""
+      ],
+      "Wire fee amortization": [
+        ""
+      ],
+      "Fullfilment url": [
+        ""
+      ],
+      "Extra information": [
+        ""
+      ],
+      "select a product first": [
+        ""
+      ],
+      "should be greater than 0": [
+        ""
+      ],
+      "cannot be greater than current stock and quantity previously added. 
max: %1$s": [
+        ""
+      ],
+      "cannot be greater than current stock %1$s": [
+        ""
+      ],
+      "Quantity": [
+        ""
+      ],
+      "Order": [
+        ""
+      ],
+      "claimed": [
+        ""
+      ],
+      "copy url": [
+        ""
+      ],
+      "pay at": [
+        ""
+      ],
+      "created at": [
+        ""
+      ],
+      "Timeline": [
+        ""
+      ],
+      "Payment details": [
+        ""
+      ],
+      "Order status": [
+        ""
+      ],
+      "Product list": [
+        ""
+      ],
+      "paid": [
+        ""
+      ],
+      "wired": [
+        ""
+      ],
+      "refunded": [
+        ""
+      ],
+      "refund": [
+        ""
+      ],
+      "Refunded amount": [
+        ""
+      ],
+      "Deposit total": [
+        ""
+      ],
+      "unpaid": [
+        ""
+      ],
+      "Order status URL": [
+        ""
+      ],
+      "Pay URI": [
+        ""
+      ],
+      "Unknown order status. This is an error, please contact the 
administrator.": [
+        ""
+      ],
+      "refund created successfully": [
+        ""
+      ],
+      "could not create the refund": [
+        ""
+      ],
+      "load newer orders": [
+        ""
+      ],
+      "Date": [
+        ""
+      ],
+      "Refund": [
+        ""
+      ],
+      "load older orders": [
+        ""
+      ],
+      "No orders has been found": [
+        ""
+      ],
+      "date": [
+        ""
+      ],
+      "amount": [
+        ""
+      ],
+      "reason": [
+        ""
+      ],
+      "Max refundable:": [
+        ""
+      ],
+      "Reason": [
+        ""
+      ],
+      "duplicated": [
+        ""
+      ],
+      "requested by the customer": [
+        ""
+      ],
+      "other": [
+        ""
+      ],
+      "go to order id": [
+        ""
+      ],
+      "Paid": [
+        ""
+      ],
+      "Refunded": [
+        ""
+      ],
+      "Not wired": [
+        ""
+      ],
+      "All": [
+        ""
+      ],
+      "could not create product": [
+        ""
+      ],
+      "Sell": [
+        ""
+      ],
+      "Profit": [
+        ""
+      ],
+      "Sold": [
+        ""
+      ],
+      "product updated successfully": [
+        ""
+      ],
+      "could not update the product": [
+        ""
+      ],
+      "product delete successfully": [
+        ""
+      ],
+      "could not delete the product": [
+        ""
+      ],
+      "Tips": [
+        ""
+      ],
+      "Committed amount": [
+        ""
+      ],
+      "Exchange initial amount": [
+        ""
+      ],
+      "Merchant initial amount": [
+        ""
+      ],
+      "There is no tips yet, add more pressing the + sign": [
+        ""
+      ],
+      "cannot be empty": [
+        ""
+      ],
+      "check the id, doest look valid": [
+        ""
+      ],
+      "should have 52 characters, current %1$s": [
+        ""
+      ],
+      "URL doesn't have the right format": [
+        ""
+      ],
+      "Transfer ID": [
+        ""
+      ],
+      "Account Address": [
+        ""
+      ],
+      "Exchange URL": [
+        ""
+      ],
+      "could not inform transfer": [
+        ""
+      ],
+      "load newer transfers": [
+        ""
+      ],
+      "Credit": [
+        ""
+      ],
+      "Confirmed": [
+        ""
+      ],
+      "Verified": [
+        ""
+      ],
+      "Executed at": [
+        ""
+      ],
+      "yes": [
+        ""
+      ],
+      "no": [
+        ""
+      ],
+      "unknown": [
+        ""
+      ],
+      "load older transfers": [
+        ""
+      ],
+      "There is no transfer yet, add more pressing the + sign": [
+        ""
+      ]
+    }
+  }
+};
+
diff --git a/packages/merchant-backoffice-ui/src/i18n/sv.po 
b/packages/merchant-backoffice-ui/src/i18n/sv.po
new file mode 100644
index 000000000..6b35bd0ce
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/i18n/sv.po
@@ -0,0 +1,1057 @@
+# This file is part of TALER
+# (C) 2016 GNUnet e.V.
+#
+# TALER is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3, or (at your option) any later version.
+#
+# TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Taler Wallet\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2016-11-23 00:00+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: src/ApplicationReadyRoutes.tsx:50 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:299
+#, c-format
+msgid "Access denied"
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:51 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:300
+#, c-format
+msgid "Check your token is valid"
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:72
+#, c-format
+msgid "Couldn't access the server."
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:73
+#, c-format
+msgid "Could not infer instance id from url %1$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:109
+#, c-format
+msgid "HTTP status #%1$s: Server reported a problem"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:110
+#, c-format
+msgid "Got message: \"%1$s\" from: %2$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:127
+#, c-format
+msgid "No default instance"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:128
+#, c-format
+msgid ""
+"in order to use merchant backoffice, you should create the default instance"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:288
+#, c-format
+msgid "Server reported a problem: HTTP status #%1$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:289
+#, c-format
+msgid "Got message: %1$s from: %2$s"
+msgstr ""
+
+#: src/components/exception/login.tsx:46
+#, c-format
+msgid "Login required"
+msgstr ""
+
+#: src/components/exception/login.tsx:49
+#, c-format
+msgid ""
+"Please enter your auth token. Token should have \"secret-token:\" and start "
+"with Bearer or ApiKey"
+msgstr ""
+
+#: src/components/exception/login.tsx:86 src/components/modal/index.tsx:53
+#: src/components/modal/index.tsx:75 src/paths/admin/create/CreatePage.tsx:115
+#: src/paths/instance/orders/create/CreatePage.tsx:325
+#: src/paths/instance/products/create/CreatePage.tsx:51
+#: src/paths/instance/products/list/Table.tsx:174
+#: src/paths/instance/products/list/Table.tsx:228
+#: src/paths/instance/products/update/UpdatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:134
+#, c-format
+msgid "Confirm"
+msgstr ""
+
+#: src/components/form/InputArray.tsx:72
+#, c-format
+msgid "The value %1$s is invalid for a payment url"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:67
+#: src/paths/instance/orders/list/index.tsx:123
+#, c-format
+msgid "pick a date"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:81
+#, c-format
+msgid "clear"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:83
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "never"
+msgstr ""
+
+#: src/components/form/InputImage.tsx:80
+#, c-format
+msgid "Image should be smaller than 1 MB"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:28
+#, c-format
+msgid "Country"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:30
+#: src/paths/admin/create/CreatePage.tsx:99
+#: src/paths/instance/transfers/list/Table.tsx:124
+#: src/paths/instance/update/UpdatePage.tsx:118
+#, c-format
+msgid "Address"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:34
+#, c-format
+msgid "Building number"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:35
+#, c-format
+msgid "Building name"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:36
+#, c-format
+msgid "Street"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:37
+#, c-format
+msgid "Post code"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:38
+#, c-format
+msgid "Town location"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:39
+#, c-format
+msgid "Town"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:40
+#, c-format
+msgid "District"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:41
+#, c-format
+msgid "Country subdivision"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:59
+#, c-format
+msgid "Product id"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:60
+#: src/components/product/ProductForm.tsx:99
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:122
+#: src/paths/instance/orders/list/Table.tsx:227
+#: src/paths/instance/products/list/Table.tsx:86
+#, c-format
+msgid "Description"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:73
+#: src/components/form/InputTaxes.tsx:81
+#: src/paths/admin/create/CreatePage.tsx:87 src/paths/admin/list/Table.tsx:110
+#: src/paths/instance/details/DetailPage.tsx:76
+#: src/paths/instance/update/UpdatePage.tsx:106
+#, c-format
+msgid "Name"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:102
+#, c-format
+msgid "loading..."
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:108
+#, c-format
+msgid "no products found"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:116
+#, c-format
+msgid "no results"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:33
+#, c-format
+msgid "Deleting"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:34
+#, c-format
+msgid "Changing"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:60
+#, c-format
+msgid "Manage token"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:83
+#, c-format
+msgid "Update"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:100
+#: src/paths/instance/orders/create/CreatePage.tsx:252
+#: src/paths/instance/orders/create/CreatePage.tsx:273
+#, c-format
+msgid "Remove"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:106 src/components/modal/index.tsx:52
+#: src/components/modal/index.tsx:73 src/paths/admin/create/CreatePage.tsx:114
+#: src/paths/instance/orders/create/CreatePage.tsx:324
+#: src/paths/instance/products/create/CreatePage.tsx:50
+#: src/paths/instance/products/list/Table.tsx:166
+#: src/paths/instance/products/list/Table.tsx:218
+#: src/paths/instance/products/update/UpdatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:88
+#: src/paths/instance/update/UpdatePage.tsx:133
+#, c-format
+msgid "Cancel"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:91
+#, c-format
+msgid "Manage stock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:93
+#, c-format
+msgid "Infinite"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:105
+#, c-format
+msgid "lost cannot be greater that current + incoming (max %1$s)"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:111
+#, c-format
+msgid "current stock will change from %1$s to %2$s"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:112
+#, c-format
+msgid "current stock will stay at %1$s"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:129
+#: src/paths/instance/products/list/Table.tsx:204
+#, c-format
+msgid "Incoming"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:130
+#: src/paths/instance/products/list/Table.tsx:205
+#, c-format
+msgid "Lost"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:142
+#, c-format
+msgid "Current"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:145
+#, c-format
+msgid "without stock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:150
+#, c-format
+msgid "Next restock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:152
+#, c-format
+msgid "Delivery address"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:73
+#, c-format
+msgid "this product has no taxes"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:77
+#: src/paths/instance/orders/details/DetailPage.tsx:145
+#: src/paths/instance/orders/details/DetailPage.tsx:296
+#: src/paths/instance/orders/list/Table.tsx:116
+#: src/paths/instance/transfers/create/CreatePage.tsx:84
+#, c-format
+msgid "Amount"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:78
+#, c-format
+msgid "currency and value separated with colon"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:84
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:78
+#, c-format
+msgid "Add"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:53
+#, c-format
+msgid "Instance"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:59
+#, c-format
+msgid "Settings"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:65
+#: src/paths/instance/orders/list/Table.tsx:60
+#, c-format
+msgid "Orders"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:71
+#: src/paths/instance/orders/create/CreatePage.tsx:258
+#: src/paths/instance/products/list/Table.tsx:48
+#, c-format
+msgid "Products"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:77
+#: src/paths/instance/transfers/list/Table.tsx:65
+#, c-format
+msgid "Transfers"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:87
+#, c-format
+msgid "Connection"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:112 src/paths/admin/list/Table.tsx:57
+#, c-format
+msgid "Instances"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:116
+#, c-format
+msgid "New"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:122
+#, c-format
+msgid "List"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:129
+#, c-format
+msgid "Log out"
+msgstr ""
+
+#: src/components/modal/index.tsx:74
+#, c-format
+msgid "Clear"
+msgstr ""
+
+#: src/components/modal/index.tsx:110 src/components/modal/index.tsx:111
+#, c-format
+msgid "should be the same"
+msgstr ""
+
+#: src/components/modal/index.tsx:111
+#, c-format
+msgid "cannot be the same as before"
+msgstr ""
+
+#: src/components/modal/index.tsx:114
+#, c-format
+msgid ""
+"You are updating the authorization token from instance %1$s with id %2$s"
+msgstr ""
+
+#: src/components/modal/index.tsx:124
+#, c-format
+msgid "Old token"
+msgstr ""
+
+#: src/components/modal/index.tsx:125
+#, c-format
+msgid "New token"
+msgstr ""
+
+#: src/components/modal/index.tsx:127
+#, c-format
+msgid "Clearing the auth token will mean public access to the instance"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:96
+#: src/paths/admin/create/CreatePage.tsx:85 src/paths/admin/list/Table.tsx:109
+#: src/paths/instance/transfers/list/Table.tsx:122
+#, c-format
+msgid "ID"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:98
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:121
+#: src/paths/instance/products/list/Table.tsx:85
+#, c-format
+msgid "Image"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:100
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:123
+#, c-format
+msgid "Unit"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:101
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:124
+#: src/paths/instance/products/list/Table.tsx:162
+#: src/paths/instance/products/list/Table.tsx:214
+#, c-format
+msgid "Price"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:103
+#: src/paths/instance/products/list/Table.tsx:90
+#, c-format
+msgid "Stock"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:105
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:128
+#: src/paths/instance/products/list/Table.tsx:88
+#, c-format
+msgid "Taxes"
+msgstr ""
+
+#: src/index.tsx:75
+#, c-format
+msgid "Server not found"
+msgstr ""
+
+#: src/index.tsx:85
+#, c-format
+msgid "Couldn't access the server"
+msgstr ""
+
+#: src/index.tsx:87 src/index.tsx:99
+#, c-format
+msgid "Got message %1$s from %2$s"
+msgstr ""
+
+#: src/index.tsx:97
+#, c-format
+msgid "Unexpected Error"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:108
+#, c-format
+msgid "Auth token"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:91
+#: src/paths/instance/details/DetailPage.tsx:77
+#: src/paths/instance/update/UpdatePage.tsx:110
+#, c-format
+msgid "Account address"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:93
+#: src/paths/instance/update/UpdatePage.tsx:112
+#, c-format
+msgid "Default max deposit fee"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:95
+#: src/paths/instance/update/UpdatePage.tsx:114
+#, c-format
+msgid "Default max wire fee"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:97
+#: src/paths/instance/update/UpdatePage.tsx:116
+#, c-format
+msgid "Default wire fee amortization"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:103
+#: src/paths/instance/update/UpdatePage.tsx:122
+#, c-format
+msgid "Jurisdiction"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:107
+#: src/paths/instance/update/UpdatePage.tsx:126
+#, c-format
+msgid "Default pay delay"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:109
+#: src/paths/instance/update/UpdatePage.tsx:128
+#, c-format
+msgid "Default wire transfer delay"
+msgstr ""
+
+#: src/paths/admin/create/index.tsx:58
+#, c-format
+msgid "could not create instance"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:63 src/paths/admin/list/Table.tsx:131
+#: src/paths/instance/transfers/list/Table.tsx:71
+#, c-format
+msgid "Delete"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:128
+#, c-format
+msgid "Edit"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:149
+#: src/paths/instance/products/list/Table.tsx:245
+#, c-format
+msgid "There is no instances yet, add more pressing the + sign"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:237
+#, c-format
+msgid "Inventory products"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:286
+#, c-format
+msgid "Total price"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:287
+#, c-format
+msgid "Total tax"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:289
+#: src/paths/instance/orders/create/CreatePage.tsx:297
+#, c-format
+msgid "Order price"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:295
+#, c-format
+msgid "Net"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:300
+#: src/paths/instance/orders/details/DetailPage.tsx:144
+#: src/paths/instance/orders/details/DetailPage.tsx:295
+#: src/paths/instance/orders/list/Table.tsx:117
+#, c-format
+msgid "Summary"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:302
+#, c-format
+msgid "Payments options"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:303
+#, c-format
+msgid "Auto refund deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:304
+#, c-format
+msgid "Refund deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:305
+#, c-format
+msgid "Pay deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:307
+#, c-format
+msgid "Delivery date"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:308
+#, c-format
+msgid "Location"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:312
+#, c-format
+msgid "Max fee"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:313
+#, c-format
+msgid "Max wire fee"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:314
+#, c-format
+msgid "Wire fee amortization"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:315
+#, c-format
+msgid "Fullfilment url"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:318
+#, c-format
+msgid "Extra information"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:44
+#, c-format
+msgid "select a product first"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:51
+#, c-format
+msgid "should be greater than 0"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:58
+#, c-format
+msgid ""
+"cannot be greater than current stock and quantity previously added. max: %1$s"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:64
+#, c-format
+msgid "cannot be greater than current stock %1$s"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:76
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:126
+#, c-format
+msgid "Quantity"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:92
+#: src/paths/instance/orders/details/DetailPage.tsx:235
+#: src/paths/instance/orders/details/DetailPage.tsx:333
+#, c-format
+msgid "Order"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:93
+#, c-format
+msgid "claimed"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:110
+#: src/paths/instance/orders/details/DetailPage.tsx:261
+#: src/paths/instance/orders/list/Table.tsx:136
+#, c-format
+msgid "copy url"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:126
+#: src/paths/instance/orders/details/DetailPage.tsx:349
+#, c-format
+msgid "pay at"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:127
+#: src/paths/instance/orders/details/DetailPage.tsx:350
+#, c-format
+msgid "created at"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:138
+#: src/paths/instance/orders/details/DetailPage.tsx:289
+#, c-format
+msgid "Timeline"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:142
+#: src/paths/instance/orders/details/DetailPage.tsx:293
+#, c-format
+msgid "Payment details"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:146
+#: src/paths/instance/orders/details/DetailPage.tsx:299
+#: src/paths/instance/orders/details/DetailPage.tsx:363
+#, c-format
+msgid "Order status"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:156
+#: src/paths/instance/orders/details/DetailPage.tsx:308
+#, c-format
+msgid "Product list"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:236
+#, c-format
+msgid "paid"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:238
+#, c-format
+msgid "wired"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:241
+#, c-format
+msgid "refunded"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:258
+#, c-format
+msgid "refund"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:297
+#, c-format
+msgid "Refunded amount"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:298
+#, c-format
+msgid "Deposit total"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:336
+#, c-format
+msgid "unpaid"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:364
+#, c-format
+msgid "Order status URL"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:365
+#, c-format
+msgid "Pay URI"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:383
+#, c-format
+msgid ""
+"Unknown order status. This is an error, please contact the administrator."
+msgstr ""
+
+#: src/paths/instance/orders/details/index.tsx:56
+#: src/paths/instance/orders/list/index.tsx:147
+#, c-format
+msgid "refund created successfully"
+msgstr ""
+
+#: src/paths/instance/orders/details/index.tsx:59
+#: src/paths/instance/orders/list/index.tsx:150
+#, c-format
+msgid "could not create the refund"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:111
+#, c-format
+msgid "load newer orders"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:115
+#, c-format
+msgid "Date"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:131
+#: src/paths/instance/orders/list/Table.tsx:223
+#, c-format
+msgid "Refund"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:145
+#, c-format
+msgid "load older orders"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:154
+#, c-format
+msgid "No orders has been found"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:202
+#, c-format
+msgid "date"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:203
+#, c-format
+msgid "amount"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:204
+#, c-format
+msgid "reason"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:224
+#, c-format
+msgid "Max refundable:"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "Reason"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "duplicated"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "requested by the customer"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "other"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:91
+#, c-format
+msgid "go to order id"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:107
+#, c-format
+msgid "Paid"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:108
+#, c-format
+msgid "Refunded"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:109
+#, c-format
+msgid "Not wired"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:110
+#, c-format
+msgid "All"
+msgstr ""
+
+#: src/paths/instance/products/create/index.tsx:48
+#: src/paths/instance/products/update/index.tsx:64
+#, c-format
+msgid "could not create product"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:87
+#, c-format
+msgid "Sell"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:89
+#, c-format
+msgid "Profit"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:91
+#, c-format
+msgid "Sold"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:59
+#, c-format
+msgid "product updated successfully"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:62
+#, c-format
+msgid "could not update the product"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:70
+#, c-format
+msgid "product delete successfully"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:73
+#, c-format
+msgid "could not delete the product"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:59
+#, c-format
+msgid "Tips"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:111
+#, c-format
+msgid "Committed amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:112
+#, c-format
+msgid "Exchange initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:113
+#, c-format
+msgid "Merchant initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:148
+#, c-format
+msgid "There is no tips yet, add more pressing the + sign"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:50
+#: src/paths/instance/transfers/create/CreatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:56
+#, c-format
+msgid "cannot be empty"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:51
+#, c-format
+msgid "check the id, doest look valid"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:52
+#, c-format
+msgid "should have 52 characters, current %1$s"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:57
+#, c-format
+msgid "URL doesn't have the right format"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:74
+#, c-format
+msgid "Transfer ID"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:76
+#, c-format
+msgid "Account Address"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:82
+#: src/paths/instance/transfers/list/Table.tsx:125
+#, c-format
+msgid "Exchange URL"
+msgstr ""
+
+#: src/paths/instance/transfers/create/index.tsx:49
+#, c-format
+msgid "could not inform transfer"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:118
+#, c-format
+msgid "load newer transfers"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:123
+#, c-format
+msgid "Credit"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:126
+#, c-format
+msgid "Confirmed"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:127
+#: src/paths/instance/transfers/list/index.tsx:60
+#, c-format
+msgid "Verified"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:128
+#, c-format
+msgid "Executed at"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "yes"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "no"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "unknown"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:145
+#, c-format
+msgid "load older transfers"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:154
+#, c-format
+msgid "There is no transfer yet, add more pressing the + sign"
+msgstr ""
diff --git 
a/packages/merchant-backoffice-ui/src/i18n/taler-merchant-backoffice.pot 
b/packages/merchant-backoffice-ui/src/i18n/taler-merchant-backoffice.pot
new file mode 100644
index 000000000..21fd863b0
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/i18n/taler-merchant-backoffice.pot
@@ -0,0 +1,1054 @@
+#  This file is part of GNU Taler
+#  (C) 2021 Taler Systems S.A.
+#  GNU Taler is free software; you can redistribute it and/or modify it under 
the
+#  terms of the GNU General Public License as published by the Free Software
+#  Foundation; either version 3, or (at your option) any later version.
+#  GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+#  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+#  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#  You should have received a copy of the GNU General Public License along with
+#  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: Taler Wallet\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2016-11-23 00:00+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: src/ApplicationReadyRoutes.tsx:50 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:299
+#, c-format
+msgid "Access denied"
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:51 src/InstanceRoutes.tsx:118
+#: src/InstanceRoutes.tsx:300
+#, c-format
+msgid "Check your token is valid"
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:72
+#, c-format
+msgid "Couldn't access the server."
+msgstr ""
+
+#: src/ApplicationReadyRoutes.tsx:73
+#, c-format
+msgid "Could not infer instance id from url %1$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:109
+#, c-format
+msgid "HTTP status #%1$s: Server reported a problem"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:110
+#, c-format
+msgid "Got message: \"%1$s\" from: %2$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:127
+#, c-format
+msgid "No default instance"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:128
+#, c-format
+msgid ""
+"in order to use merchant backoffice, you should create the default instance"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:288
+#, c-format
+msgid "Server reported a problem: HTTP status #%1$s"
+msgstr ""
+
+#: src/InstanceRoutes.tsx:289
+#, c-format
+msgid "Got message: %1$s from: %2$s"
+msgstr ""
+
+#: src/components/exception/login.tsx:46
+#, c-format
+msgid "Login required"
+msgstr ""
+
+#: src/components/exception/login.tsx:49
+#, c-format
+msgid ""
+"Please enter your auth token. Token should have \"secret-token:\" and start "
+"with Bearer or ApiKey"
+msgstr ""
+
+#: src/components/exception/login.tsx:86 src/components/modal/index.tsx:53
+#: src/components/modal/index.tsx:75 src/paths/admin/create/CreatePage.tsx:115
+#: src/paths/instance/orders/create/CreatePage.tsx:325
+#: src/paths/instance/products/create/CreatePage.tsx:51
+#: src/paths/instance/products/list/Table.tsx:174
+#: src/paths/instance/products/list/Table.tsx:228
+#: src/paths/instance/products/update/UpdatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:134
+#, c-format
+msgid "Confirm"
+msgstr ""
+
+#: src/components/form/InputArray.tsx:72
+#, c-format
+msgid "The value %1$s is invalid for a payment url"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:67
+#: src/paths/instance/orders/list/index.tsx:123
+#, c-format
+msgid "pick a date"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:81
+#, c-format
+msgid "clear"
+msgstr ""
+
+#: src/components/form/InputDate.tsx:83
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "never"
+msgstr ""
+
+#: src/components/form/InputImage.tsx:80
+#, c-format
+msgid "Image should be smaller than 1 MB"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:28
+#, c-format
+msgid "Country"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:30
+#: src/paths/admin/create/CreatePage.tsx:99
+#: src/paths/instance/transfers/list/Table.tsx:124
+#: src/paths/instance/update/UpdatePage.tsx:118
+#, c-format
+msgid "Address"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:34
+#, c-format
+msgid "Building number"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:35
+#, c-format
+msgid "Building name"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:36
+#, c-format
+msgid "Street"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:37
+#, c-format
+msgid "Post code"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:38
+#, c-format
+msgid "Town location"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:39
+#, c-format
+msgid "Town"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:40
+#, c-format
+msgid "District"
+msgstr ""
+
+#: src/components/form/InputLocation.tsx:41
+#, c-format
+msgid "Country subdivision"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:59
+#, c-format
+msgid "Product id"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:60
+#: src/components/product/ProductForm.tsx:99
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:122
+#: src/paths/instance/orders/list/Table.tsx:227
+#: src/paths/instance/products/list/Table.tsx:86
+#, c-format
+msgid "Description"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:73
+#: src/components/form/InputTaxes.tsx:81
+#: src/paths/admin/create/CreatePage.tsx:87 src/paths/admin/list/Table.tsx:110
+#: src/paths/instance/details/DetailPage.tsx:76
+#: src/paths/instance/update/UpdatePage.tsx:106
+#, c-format
+msgid "Name"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:102
+#, c-format
+msgid "loading..."
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:108
+#, c-format
+msgid "no products found"
+msgstr ""
+
+#: src/components/form/InputSearchProduct.tsx:116
+#, c-format
+msgid "no results"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:33
+#, c-format
+msgid "Deleting"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:34
+#, c-format
+msgid "Changing"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:60
+#, c-format
+msgid "Manage token"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:83
+#, c-format
+msgid "Update"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:100
+#: src/paths/instance/orders/create/CreatePage.tsx:252
+#: src/paths/instance/orders/create/CreatePage.tsx:273
+#, c-format
+msgid "Remove"
+msgstr ""
+
+#: src/components/form/InputSecured.tsx:106 src/components/modal/index.tsx:52
+#: src/components/modal/index.tsx:73 src/paths/admin/create/CreatePage.tsx:114
+#: src/paths/instance/orders/create/CreatePage.tsx:324
+#: src/paths/instance/products/create/CreatePage.tsx:50
+#: src/paths/instance/products/list/Table.tsx:166
+#: src/paths/instance/products/list/Table.tsx:218
+#: src/paths/instance/products/update/UpdatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:88
+#: src/paths/instance/update/UpdatePage.tsx:133
+#, c-format
+msgid "Cancel"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:91
+#, c-format
+msgid "Manage stock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:93
+#, c-format
+msgid "Infinite"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:105
+#, c-format
+msgid "lost cannot be greater that current + incoming (max %1$s)"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:111
+#, c-format
+msgid "current stock will change from %1$s to %2$s"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:112
+#, c-format
+msgid "current stock will stay at %1$s"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:129
+#: src/paths/instance/products/list/Table.tsx:204
+#, c-format
+msgid "Incoming"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:130
+#: src/paths/instance/products/list/Table.tsx:205
+#, c-format
+msgid "Lost"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:142
+#, c-format
+msgid "Current"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:145
+#, c-format
+msgid "without stock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:150
+#, c-format
+msgid "Next restock"
+msgstr ""
+
+#: src/components/form/InputStock.tsx:152
+#, c-format
+msgid "Delivery address"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:73
+#, c-format
+msgid "this product has no taxes"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:77
+#: src/paths/instance/orders/details/DetailPage.tsx:145
+#: src/paths/instance/orders/details/DetailPage.tsx:296
+#: src/paths/instance/orders/list/Table.tsx:116
+#: src/paths/instance/transfers/create/CreatePage.tsx:84
+#, c-format
+msgid "Amount"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:78
+#, c-format
+msgid "currency and value separated with colon"
+msgstr ""
+
+#: src/components/form/InputTaxes.tsx:84
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:78
+#, c-format
+msgid "Add"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:53
+#, c-format
+msgid "Instance"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:59
+#, c-format
+msgid "Settings"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:65
+#: src/paths/instance/orders/list/Table.tsx:60
+#, c-format
+msgid "Orders"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:71
+#: src/paths/instance/orders/create/CreatePage.tsx:258
+#: src/paths/instance/products/list/Table.tsx:48
+#, c-format
+msgid "Products"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:77
+#: src/paths/instance/transfers/list/Table.tsx:65
+#, c-format
+msgid "Transfers"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:87
+#, c-format
+msgid "Connection"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:112 src/paths/admin/list/Table.tsx:57
+#, c-format
+msgid "Instances"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:116
+#, c-format
+msgid "New"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:122
+#, c-format
+msgid "List"
+msgstr ""
+
+#: src/components/menu/SideBar.tsx:129
+#, c-format
+msgid "Log out"
+msgstr ""
+
+#: src/components/modal/index.tsx:74
+#, c-format
+msgid "Clear"
+msgstr ""
+
+#: src/components/modal/index.tsx:110 src/components/modal/index.tsx:111
+#, c-format
+msgid "should be the same"
+msgstr ""
+
+#: src/components/modal/index.tsx:111
+#, c-format
+msgid "cannot be the same as before"
+msgstr ""
+
+#: src/components/modal/index.tsx:114
+#, c-format
+msgid ""
+"You are updating the authorization token from instance %1$s with id %2$s"
+msgstr ""
+
+#: src/components/modal/index.tsx:124
+#, c-format
+msgid "Old token"
+msgstr ""
+
+#: src/components/modal/index.tsx:125
+#, c-format
+msgid "New token"
+msgstr ""
+
+#: src/components/modal/index.tsx:127
+#, c-format
+msgid "Clearing the auth token will mean public access to the instance"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:96
+#: src/paths/admin/create/CreatePage.tsx:85 src/paths/admin/list/Table.tsx:109
+#: src/paths/instance/transfers/list/Table.tsx:122
+#, c-format
+msgid "ID"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:98
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:121
+#: src/paths/instance/products/list/Table.tsx:85
+#, c-format
+msgid "Image"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:100
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:123
+#, c-format
+msgid "Unit"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:101
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:124
+#: src/paths/instance/products/list/Table.tsx:162
+#: src/paths/instance/products/list/Table.tsx:214
+#, c-format
+msgid "Price"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:103
+#: src/paths/instance/products/list/Table.tsx:90
+#, c-format
+msgid "Stock"
+msgstr ""
+
+#: src/components/product/ProductForm.tsx:105
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:128
+#: src/paths/instance/products/list/Table.tsx:88
+#, c-format
+msgid "Taxes"
+msgstr ""
+
+#: src/index.tsx:75
+#, c-format
+msgid "Server not found"
+msgstr ""
+
+#: src/index.tsx:85
+#, c-format
+msgid "Couldn't access the server"
+msgstr ""
+
+#: src/index.tsx:87 src/index.tsx:99
+#, c-format
+msgid "Got message %1$s from %2$s"
+msgstr ""
+
+#: src/index.tsx:97
+#, c-format
+msgid "Unexpected Error"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:89
+#: src/paths/instance/update/UpdatePage.tsx:108
+#, c-format
+msgid "Auth token"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:91
+#: src/paths/instance/details/DetailPage.tsx:77
+#: src/paths/instance/update/UpdatePage.tsx:110
+#, c-format
+msgid "Account address"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:93
+#: src/paths/instance/update/UpdatePage.tsx:112
+#, c-format
+msgid "Default max deposit fee"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:95
+#: src/paths/instance/update/UpdatePage.tsx:114
+#, c-format
+msgid "Default max wire fee"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:97
+#: src/paths/instance/update/UpdatePage.tsx:116
+#, c-format
+msgid "Default wire fee amortization"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:103
+#: src/paths/instance/update/UpdatePage.tsx:122
+#, c-format
+msgid "Jurisdiction"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:107
+#: src/paths/instance/update/UpdatePage.tsx:126
+#, c-format
+msgid "Default pay delay"
+msgstr ""
+
+#: src/paths/admin/create/CreatePage.tsx:109
+#: src/paths/instance/update/UpdatePage.tsx:128
+#, c-format
+msgid "Default wire transfer delay"
+msgstr ""
+
+#: src/paths/admin/create/index.tsx:58
+#, c-format
+msgid "could not create instance"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:63 src/paths/admin/list/Table.tsx:131
+#: src/paths/instance/transfers/list/Table.tsx:71
+#, c-format
+msgid "Delete"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:128
+#, c-format
+msgid "Edit"
+msgstr ""
+
+#: src/paths/admin/list/Table.tsx:149
+#: src/paths/instance/products/list/Table.tsx:245
+#, c-format
+msgid "There is no instances yet, add more pressing the + sign"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:237
+#, c-format
+msgid "Inventory products"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:286
+#, c-format
+msgid "Total price"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:287
+#, c-format
+msgid "Total tax"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:289
+#: src/paths/instance/orders/create/CreatePage.tsx:297
+#, c-format
+msgid "Order price"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:295
+#, c-format
+msgid "Net"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:300
+#: src/paths/instance/orders/details/DetailPage.tsx:144
+#: src/paths/instance/orders/details/DetailPage.tsx:295
+#: src/paths/instance/orders/list/Table.tsx:117
+#, c-format
+msgid "Summary"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:302
+#, c-format
+msgid "Payments options"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:303
+#, c-format
+msgid "Auto refund deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:304
+#, c-format
+msgid "Refund deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:305
+#, c-format
+msgid "Pay deadline"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:307
+#, c-format
+msgid "Delivery date"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:308
+#, c-format
+msgid "Location"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:312
+#, c-format
+msgid "Max fee"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:313
+#, c-format
+msgid "Max wire fee"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:314
+#, c-format
+msgid "Wire fee amortization"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:315
+#, c-format
+msgid "Fullfilment url"
+msgstr ""
+
+#: src/paths/instance/orders/create/CreatePage.tsx:318
+#, c-format
+msgid "Extra information"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:44
+#, c-format
+msgid "select a product first"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:51
+#, c-format
+msgid "should be greater than 0"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:58
+#, c-format
+msgid ""
+"cannot be greater than current stock and quantity previously added. max: %1$s"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:64
+#, c-format
+msgid "cannot be greater than current stock %1$s"
+msgstr ""
+
+#: src/paths/instance/orders/create/InventoryProductForm.tsx:76
+#: src/paths/instance/orders/create/NonInventoryProductForm.tsx:126
+#, c-format
+msgid "Quantity"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:92
+#: src/paths/instance/orders/details/DetailPage.tsx:235
+#: src/paths/instance/orders/details/DetailPage.tsx:333
+#, c-format
+msgid "Order"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:93
+#, c-format
+msgid "claimed"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:110
+#: src/paths/instance/orders/details/DetailPage.tsx:261
+#: src/paths/instance/orders/list/Table.tsx:136
+#, c-format
+msgid "copy url"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:126
+#: src/paths/instance/orders/details/DetailPage.tsx:349
+#, c-format
+msgid "pay at"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:127
+#: src/paths/instance/orders/details/DetailPage.tsx:350
+#, c-format
+msgid "created at"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:138
+#: src/paths/instance/orders/details/DetailPage.tsx:289
+#, c-format
+msgid "Timeline"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:142
+#: src/paths/instance/orders/details/DetailPage.tsx:293
+#, c-format
+msgid "Payment details"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:146
+#: src/paths/instance/orders/details/DetailPage.tsx:299
+#: src/paths/instance/orders/details/DetailPage.tsx:363
+#, c-format
+msgid "Order status"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:156
+#: src/paths/instance/orders/details/DetailPage.tsx:308
+#, c-format
+msgid "Product list"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:236
+#, c-format
+msgid "paid"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:238
+#, c-format
+msgid "wired"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:241
+#, c-format
+msgid "refunded"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:258
+#, c-format
+msgid "refund"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:297
+#, c-format
+msgid "Refunded amount"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:298
+#, c-format
+msgid "Deposit total"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:336
+#, c-format
+msgid "unpaid"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:364
+#, c-format
+msgid "Order status URL"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:365
+#, c-format
+msgid "Pay URI"
+msgstr ""
+
+#: src/paths/instance/orders/details/DetailPage.tsx:383
+#, c-format
+msgid ""
+"Unknown order status. This is an error, please contact the administrator."
+msgstr ""
+
+#: src/paths/instance/orders/details/index.tsx:56
+#: src/paths/instance/orders/list/index.tsx:147
+#, c-format
+msgid "refund created successfully"
+msgstr ""
+
+#: src/paths/instance/orders/details/index.tsx:59
+#: src/paths/instance/orders/list/index.tsx:150
+#, c-format
+msgid "could not create the refund"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:111
+#, c-format
+msgid "load newer orders"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:115
+#, c-format
+msgid "Date"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:131
+#: src/paths/instance/orders/list/Table.tsx:223
+#, c-format
+msgid "Refund"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:145
+#, c-format
+msgid "load older orders"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:154
+#, c-format
+msgid "No orders has been found"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:202
+#, c-format
+msgid "date"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:203
+#, c-format
+msgid "amount"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:204
+#, c-format
+msgid "reason"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:224
+#, c-format
+msgid "Max refundable:"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "Reason"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "duplicated"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "requested by the customer"
+msgstr ""
+
+#: src/paths/instance/orders/list/Table.tsx:226
+#, c-format
+msgid "other"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:91
+#, c-format
+msgid "go to order id"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:107
+#, c-format
+msgid "Paid"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:108
+#, c-format
+msgid "Refunded"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:109
+#, c-format
+msgid "Not wired"
+msgstr ""
+
+#: src/paths/instance/orders/list/index.tsx:110
+#, c-format
+msgid "All"
+msgstr ""
+
+#: src/paths/instance/products/create/index.tsx:48
+#: src/paths/instance/products/update/index.tsx:64
+#, c-format
+msgid "could not create product"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:87
+#, c-format
+msgid "Sell"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:89
+#, c-format
+msgid "Profit"
+msgstr ""
+
+#: src/paths/instance/products/list/Table.tsx:91
+#, c-format
+msgid "Sold"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:59
+#, c-format
+msgid "product updated successfully"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:62
+#, c-format
+msgid "could not update the product"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:70
+#, c-format
+msgid "product delete successfully"
+msgstr ""
+
+#: src/paths/instance/products/list/index.tsx:73
+#, c-format
+msgid "could not delete the product"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:59
+#, c-format
+msgid "Tips"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:111
+#, c-format
+msgid "Committed amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:112
+#, c-format
+msgid "Exchange initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:113
+#, c-format
+msgid "Merchant initial amount"
+msgstr ""
+
+#: src/paths/instance/tips/list/Table.tsx:148
+#, c-format
+msgid "There is no tips yet, add more pressing the + sign"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:50
+#: src/paths/instance/transfers/create/CreatePage.tsx:54
+#: src/paths/instance/transfers/create/CreatePage.tsx:55
+#: src/paths/instance/transfers/create/CreatePage.tsx:56
+#, c-format
+msgid "cannot be empty"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:51
+#, c-format
+msgid "check the id, doest look valid"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:52
+#, c-format
+msgid "should have 52 characters, current %1$s"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:57
+#, c-format
+msgid "URL doesn't have the right format"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:74
+#, c-format
+msgid "Transfer ID"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:76
+#, c-format
+msgid "Account Address"
+msgstr ""
+
+#: src/paths/instance/transfers/create/CreatePage.tsx:82
+#: src/paths/instance/transfers/list/Table.tsx:125
+#, c-format
+msgid "Exchange URL"
+msgstr ""
+
+#: src/paths/instance/transfers/create/index.tsx:49
+#, c-format
+msgid "could not inform transfer"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:118
+#, c-format
+msgid "load newer transfers"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:123
+#, c-format
+msgid "Credit"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:126
+#, c-format
+msgid "Confirmed"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:127
+#: src/paths/instance/transfers/list/index.tsx:60
+#, c-format
+msgid "Verified"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:128
+#, c-format
+msgid "Executed at"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "yes"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:138
+#: src/paths/instance/transfers/list/Table.tsx:139
+#, c-format
+msgid "no"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:140
+#, c-format
+msgid "unknown"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:145
+#, c-format
+msgid "load older transfers"
+msgstr ""
+
+#: src/paths/instance/transfers/list/Table.tsx:154
+#, c-format
+msgid "There is no transfer yet, add more pressing the + sign"
+msgstr ""
diff --git a/packages/merchant-backoffice-ui/src/index.tsx 
b/packages/merchant-backoffice-ui/src/index.tsx
new file mode 100644
index 000000000..26dcc3eb8
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/index.tsx
@@ -0,0 +1,111 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode } from 'preact';
+import { route } from 'preact-router';
+import { useMemo } from "preact/hooks";
+import { ApplicationReadyRoutes } from "./ApplicationReadyRoutes";
+import { Loading } from "./components/exception/loading";
+import { NotificationCard, NotYetReadyAppMenu } from "./components/menu";
+import { BackendContextProvider, useBackendContext } from './context/backend';
+import { ConfigContextProvider } from './context/config';
+import { FetchContextProvider } from './context/fetch';
+import { TranslationProvider } from './context/translation';
+import { useBackendConfig } from "./hooks/backend";
+import { useTranslator } from './i18n';
+import LoginPage from './paths/login';
+import "./scss/main.scss";
+
+export default function Application(): VNode {
+  return (
+    // <FetchContextProvider>
+      <BackendContextProvider>
+        <TranslationProvider>
+          <ApplicationStatusRoutes />
+        </TranslationProvider>
+      </BackendContextProvider>
+    // </FetchContextProvider>
+  );
+}
+
+function ApplicationStatusRoutes(): VNode {
+  const { updateLoginStatus, triedToLog } = useBackendContext()
+  const result = useBackendConfig();
+  const i18n = useTranslator()
+
+  const updateLoginInfoAndGoToRoot = (url: string, token?: string) => {
+    updateLoginStatus(url, token)
+    route('/')
+  }
+
+  const { currency, version } = result.ok ? result.data : { currency: 
'unknown', version: 'unknown' }
+  const ctx = useMemo(() => ({ currency, version }), [currency, version])
+
+  if (!triedToLog) {
+    return <div id="app">
+      <NotYetReadyAppMenu title="Welcome!" />
+      <LoginPage onConfirm={updateLoginInfoAndGoToRoot} />
+    </div>
+  }
+
+  if (result.clientError && result.isUnauthorized) return <div id="app">
+    <NotYetReadyAppMenu title="Login" />
+    <LoginPage onConfirm={updateLoginInfoAndGoToRoot} />
+  </div>
+
+  if (result.clientError && result.isNotfound) return <div id="app">
+    <NotYetReadyAppMenu title="Error" />
+    <NotificationCard notification={{
+      message: i18n`Server not found`,
+      type: 'ERROR',
+      description: `Check your url`,
+    }} />
+    <LoginPage onConfirm={updateLoginInfoAndGoToRoot} />
+  </div>
+
+  if (result.serverError) return <div id="app">
+    <NotYetReadyAppMenu title="Error" />
+    <NotificationCard notification={{
+      message: i18n`Couldn't access the server`,
+      type: 'ERROR',
+      description: i18n`Got message ${result.message} from 
${result.info?.url}`,
+    }} />
+    <LoginPage onConfirm={updateLoginInfoAndGoToRoot} />
+  </div>
+
+  if (result.loading) return <Loading />
+
+  if (!result.ok) return <div id="app">
+    <NotYetReadyAppMenu title="Error" />
+    <NotificationCard notification={{
+      message: i18n`Unexpected Error`,
+      type: 'ERROR',
+      description: i18n`Got message ${result.message} from 
${result.info?.url}`,
+    }} />
+    <LoginPage onConfirm={updateLoginInfoAndGoToRoot} />
+  </div>
+
+  return <div id="app" class="has-navbar-fixed-top">
+    <ConfigContextProvider value={ctx}>
+      <ApplicationReadyRoutes />
+    </ConfigContextProvider>
+  </div>
+}
diff --git a/packages/merchant-backoffice-ui/src/manifest.json 
b/packages/merchant-backoffice-ui/src/manifest.json
new file mode 100644
index 000000000..d0d3ea463
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/manifest.json
@@ -0,0 +1,21 @@
+{
+  "name": "backoffice-preact",
+  "short_name": "backoffice-preact",
+  "start_url": "/",
+  "display": "standalone",
+  "orientation": "portrait",
+  "background_color": "#fff",
+  "theme_color": "#673ab8",
+  "icons": [
+    {
+      "src": "/assets/icons/android-chrome-192x192.png",
+      "type": "image/png",
+      "sizes": "192x192"
+    },
+    {
+      "src": "/assets/icons/android-chrome-512x512.png",
+      "type": "image/png",
+      "sizes": "512x512"
+    }
+  ]
+}
\ No newline at end of file
diff --git 
a/packages/merchant-backoffice-ui/src/paths/admin/create/Create.stories.tsx 
b/packages/merchant-backoffice-ui/src/paths/admin/create/Create.stories.tsx
new file mode 100644
index 000000000..c1287557d
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/paths/admin/create/Create.stories.tsx
@@ -0,0 +1,46 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode, FunctionalComponent } from 'preact';
+import { CreatePage as TestedComponent } from './CreatePage';
+
+
+export default {
+  title: 'Pages/Instance/Create',
+  component: TestedComponent,
+  argTypes: {
+    onCreate: { action: 'onCreate' },
+    goBack: { action: 'goBack' },
+  }
+};
+
+function createExample<Props>(Component: FunctionalComponent<Props>, props: 
Partial<Props>) {
+  const r = (args: any) => <Component {...args} />
+  r.args = props
+  return r
+}
+
+export const Example = createExample(TestedComponent, {
+});
+// export const Example = (a: any): VNode => <CreatePage {...a} />;
+// Example.args = {
+//   isLoading: false
+// }
diff --git 
a/packages/merchant-backoffice-ui/src/paths/admin/create/CreatePage.tsx 
b/packages/merchant-backoffice-ui/src/paths/admin/create/CreatePage.tsx
new file mode 100644
index 000000000..1851e52f1
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/paths/admin/create/CreatePage.tsx
@@ -0,0 +1,234 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import * as yup from "yup";
+import { AsyncButton } from "../../../components/exception/AsyncButton";
+import {
+  FormErrors,
+  FormProvider,
+} from "../../../components/form/FormProvider";
+import { SetTokenNewInstanceModal } from "../../../components/modal";
+import { MerchantBackend } from "../../../declaration";
+import { Translate, useTranslator } from "../../../i18n";
+import { DefaultInstanceFormFields } from 
"../../../components/instance/DefaultInstanceFormFields";
+import { INSTANCE_ID_REGEX, PAYTO_REGEX } from "../../../utils/constants";
+import { Amounts } from "@gnu-taler/taler-util";
+
+export type Entity = MerchantBackend.Instances.InstanceConfigurationMessage & {
+  auth_token?: string;
+};
+
+interface Props {
+  onCreate: (d: Entity) => Promise<void>;
+  onBack?: () => void;
+  forceId?: string;
+}
+
+function with_defaults(id?: string): Partial<Entity> {
+  return {
+    id,
+    payto_uris: [],
+    default_pay_delay: { d_us: 2 * 1000 * 60 * 60 * 1000 }, // two hours
+    default_wire_fee_amortization: 1,
+    default_wire_transfer_delay: { d_us: 1000 * 2 * 60 * 60 * 24 * 1000 }, // 
two days
+  };
+}
+
+function undefinedIfEmpty<T>(obj: T): T | undefined {
+  return Object.keys(obj).some((k) => (obj as any)[k] !== undefined)
+    ? obj
+    : undefined;
+}
+
+export function CreatePage({ onCreate, onBack, forceId }: Props): VNode {
+  const [value, valueHandler] = useState(with_defaults(forceId));
+  const [isTokenSet, updateIsTokenSet] = useState<boolean>(false);
+  const [isTokenDialogActive, updateIsTokenDialogActive] =
+    useState<boolean>(false);
+
+  const i18n = useTranslator();
+
+  const errors: FormErrors<Entity> = {
+    id: !value.id
+      ? i18n`required`
+      : !INSTANCE_ID_REGEX.test(value.id)
+      ? i18n`is not valid`
+      : undefined,
+    name: !value.name ? i18n`required` : undefined,
+    payto_uris:
+      !value.payto_uris || !value.payto_uris.length
+        ? i18n`required`
+        : undefinedIfEmpty(
+            value.payto_uris.map((p) => {
+              return !PAYTO_REGEX.test(p) ? i18n`is not valid` : undefined;
+            })
+          ),
+    default_max_deposit_fee: !value.default_max_deposit_fee
+      ? i18n`required`
+      : !Amounts.parse(value.default_max_deposit_fee)
+      ? i18n`invalid format`
+      : undefined,
+    default_max_wire_fee: !value.default_max_wire_fee
+      ? i18n`required`
+      : !Amounts.parse(value.default_max_wire_fee)
+      ? i18n`invalid format`
+      : undefined,
+    default_wire_fee_amortization:
+      value.default_wire_fee_amortization === undefined
+        ? i18n`required`
+        : isNaN(value.default_wire_fee_amortization)
+        ? i18n`is not a number`
+        : value.default_wire_fee_amortization < 1
+        ? i18n`must be 1 or greater`
+        : undefined,
+    default_pay_delay: !value.default_pay_delay ? i18n`required` : undefined,
+    default_wire_transfer_delay: !value.default_wire_transfer_delay
+      ? i18n`required`
+      : undefined,
+    address: undefinedIfEmpty({
+      address_lines:
+        value.address?.address_lines && value.address?.address_lines.length > 7
+          ? i18n`max 7 lines`
+          : undefined,
+    }),
+    jurisdiction: undefinedIfEmpty({
+      address_lines:
+        value.address?.address_lines && value.address?.address_lines.length > 7
+          ? i18n`max 7 lines`
+          : undefined,
+    }),
+  };
+
+  const hasErrors = Object.keys(errors).some(
+    (k) => (errors as any)[k] !== undefined
+  );
+
+  const submit = (): Promise<void> => {
+    // use conversion instead of this
+    const newToken = value.auth_token;
+    value.auth_token = undefined;
+    value.auth =
+      newToken === null || newToken === undefined
+        ? { method: "external" }
+        : { method: "token", token: `secret-token:${newToken}` };
+    if (!value.address) value.address = {};
+    if (!value.jurisdiction) value.jurisdiction = {};
+    // remove above use conversion
+    // schema.validateSync(value, { abortEarly: false })
+    return onCreate(value as Entity);
+  };
+
+  function updateToken(token: string | null) {
+    valueHandler((old) => ({
+      ...old,
+      auth_token: token === null ? undefined : token,
+    }));
+  }
+
+  return (
+    <div>
+      <div class="columns">
+        <div class="column" />
+        <div class="column is-four-fifths">
+          {isTokenDialogActive && (
+            <SetTokenNewInstanceModal
+              onCancel={() => {
+                updateIsTokenDialogActive(false);
+                updateIsTokenSet(false);
+              }}
+              onClear={() => {
+                updateToken(null);
+                updateIsTokenDialogActive(false);
+                updateIsTokenSet(true);
+              }}
+              onConfirm={(newToken) => {
+                updateToken(newToken);
+                updateIsTokenDialogActive(false);
+                updateIsTokenSet(true);
+              }}
+            />
+          )}
+        </div>
+        <div class="column" />
+      </div>
+
+      <section class="hero is-hero-bar">
+        <div class="hero-body">
+          <div class="level">
+            <div class="level-item has-text-centered">
+              <h1 class="title">
+                <button
+                  class="button is-danger has-tooltip-bottom"
+                  data-tooltip={i18n`change authorization configuration`}
+                  onClick={() => updateIsTokenDialogActive(true)}
+                >
+                  <div class="icon is-centered">
+                    <i class="mdi mdi-lock-reset" />
+                  </div>
+                  <span>
+                    <Translate>Set access token</Translate>
+                  </span>
+                </button>
+              </h1>
+            </div>
+          </div>
+        </div>
+      </section>
+
+      <section class="section is-main-section">
+        <div class="columns">
+          <div class="column" />
+          <div class="column is-four-fifths">
+            <FormProvider<Entity>
+              errors={errors}
+              object={value}
+              valueHandler={valueHandler}
+            >
+              <DefaultInstanceFormFields readonlyId={!!forceId} showId={true} 
/>
+            </FormProvider>
+
+            <div class="buttons is-right mt-5">
+              {onBack && (
+                <button class="button" onClick={onBack}>
+                  <Translate>Cancel</Translate>
+                </button>
+              )}
+              <AsyncButton
+                onClick={submit}
+                disabled={!isTokenSet || hasErrors}
+                data-tooltip={
+                  hasErrors
+                    ? i18n`Need to complete marked fields and choose 
authorization method`
+                    : "confirm operation"
+                }
+              >
+                <Translate>Confirm</Translate>
+              </AsyncButton>
+            </div>
+          </div>
+          <div class="column" />
+        </div>
+      </section>
+    </div>
+  );
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/admin/create/InstanceCreatedSuccessfully.tsx
 
b/packages/merchant-backoffice-ui/src/paths/admin/create/InstanceCreatedSuccessfully.tsx
new file mode 100644
index 000000000..00b3f20fc
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/admin/create/InstanceCreatedSuccessfully.tsx
@@ -0,0 +1,65 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import { h, VNode } from "preact";
+import { CreatedSuccessfully } from 
"../../../components/notifications/CreatedSuccessfully";
+import { Entity } from "./index";
+
+export function InstanceCreatedSuccessfully({ entity, onConfirm }: { entity: 
Entity; onConfirm: () => void; }): VNode {
+  return <CreatedSuccessfully onConfirm={onConfirm}>
+    <div class="field is-horizontal">
+      <div class="field-label is-normal">
+        <label class="label">ID</label>
+      </div>
+      <div class="field-body is-flex-grow-3">
+        <div class="field">
+          <p class="control">
+            <input class="input" readonly value={entity.id} />
+          </p>
+        </div>
+      </div>
+    </div>
+    <div class="field is-horizontal">
+      <div class="field-label is-normal">
+        <label class="label">Business Name</label>
+      </div>
+      <div class="field-body is-flex-grow-3">
+        <div class="field">
+          <p class="control">
+            <input class="input" readonly value={entity.name} />
+          </p>
+        </div>
+      </div>
+    </div>
+    <div class="field is-horizontal">
+      <div class="field-label is-normal">
+        <label class="label">Access token</label>
+      </div>
+      <div class="field-body is-flex-grow-3">
+        <div class="field">
+          <p class="control">
+            {entity.auth.method === 'external' && 'external'}
+            {entity.auth.method === 'token' &&
+              <input class="input" readonly value={entity.auth.token} />}
+          </p>
+        </div>
+      </div>
+    </div>
+  </CreatedSuccessfully>;
+}
diff --git a/packages/merchant-backoffice-ui/src/paths/admin/create/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/admin/create/index.tsx
new file mode 100644
index 000000000..aaed6d666
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/paths/admin/create/index.tsx
@@ -0,0 +1,74 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { Fragment, h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { NotificationCard } from "../../../components/menu";
+import { MerchantBackend } from "../../../declaration";
+import { useAdminAPI } from "../../../hooks/instance";
+import { useTranslator } from "../../../i18n";
+import { Notification } from "../../../utils/types";
+import { CreatePage } from "./CreatePage";
+import { InstanceCreatedSuccessfully } from "./InstanceCreatedSuccessfully";
+
+interface Props {
+  onBack?: () => void;
+  onConfirm: () => void;
+  forceId?: string;
+}
+export type Entity = MerchantBackend.Instances.InstanceConfigurationMessage;
+
+export default function Create({ onBack, onConfirm, forceId }: Props): VNode {
+  const { createInstance } = useAdminAPI();
+  const [notif, setNotif] = useState<Notification | undefined>(undefined);
+  const [createdOk, setCreatedOk] = useState<Entity | undefined>(undefined);
+  const i18n = useTranslator();
+
+  if (createdOk) {
+    return (
+      <InstanceCreatedSuccessfully entity={createdOk} onConfirm={onConfirm} />
+    );
+  }
+
+  return (
+    <Fragment>
+      <NotificationCard notification={notif} />
+
+      <CreatePage
+        onBack={onBack}
+        forceId={forceId}
+        onCreate={(
+          d: MerchantBackend.Instances.InstanceConfigurationMessage
+        ) => {
+          return createInstance(d)
+            .then(() => {
+              setCreatedOk(d);
+            })
+            .catch((error) => {
+              setNotif({
+                message: i18n`Failed to create instance`,
+                type: "ERROR",
+                description: error.message,
+              });
+            });
+        }}
+      />
+    </Fragment>
+  );
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/admin/list/TableActive.tsx 
b/packages/merchant-backoffice-ui/src/paths/admin/list/TableActive.tsx
new file mode 100644
index 000000000..928658910
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/paths/admin/list/TableActive.tsx
@@ -0,0 +1,184 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode } from "preact";
+import { StateUpdater, useEffect, useState } from "preact/hooks";
+import { MerchantBackend } from "../../../declaration";
+import { Translate, useTranslator } from "../../../i18n";
+
+interface Props {
+  instances: MerchantBackend.Instances.Instance[];
+  onUpdate: (id: string) => void;
+  onDelete: (id: MerchantBackend.Instances.Instance) => void;
+  onPurge: (id: MerchantBackend.Instances.Instance) => void;
+  onCreate: () => void;
+  selected?: boolean;
+  setInstanceName: (s: string) => void;
+}
+
+export function CardTable({ instances, onCreate, onUpdate, onPurge, 
setInstanceName, onDelete, selected }: Props): VNode {
+  const [actionQueue, actionQueueHandler] = useState<Actions[]>([]);
+  const [rowSelection, rowSelectionHandler] = useState<string[]>([])
+
+  useEffect(() => {
+    if (actionQueue.length > 0 && !selected && actionQueue[0].type == 
'DELETE') {
+      onDelete(actionQueue[0].element)
+      actionQueueHandler(actionQueue.slice(1))
+    }
+  }, [actionQueue, selected, onDelete])
+
+  useEffect(() => {
+    if (actionQueue.length > 0 && !selected && actionQueue[0].type == 
'UPDATE') {
+      onUpdate(actionQueue[0].element.id)
+      actionQueueHandler(actionQueue.slice(1))
+    }
+  }, [actionQueue, selected, onUpdate])
+
+  const i18n = useTranslator()
+
+  return <div class="card has-table">
+    <header class="card-header">
+      <p class="card-header-title"><span class="icon"><i class="mdi 
mdi-desktop-mac" /></span><Translate>Instances</Translate></p>
+
+      <div class="card-header-icon" aria-label="more options">
+
+        <button class={rowSelection.length > 0 ? "button is-danger" : 
"is-hidden"}
+          type="button" onClick={(): void => 
actionQueueHandler(buildActions(instances, rowSelection, 'DELETE'))} >
+          <Translate>Delete</Translate>
+        </button>
+      </div>
+      <div class="card-header-icon" aria-label="more options">
+        <span class="has-tooltip-left" data-tooltip={i18n`add new instance`}>
+          <button class="button is-info" type="button" onClick={onCreate}>
+            <span class="icon is-small" ><i class="mdi mdi-plus mdi-36px" 
/></span>
+          </button>
+        </span>
+      </div>
+
+    </header>
+    <div class="card-content">
+      <div class="b-table has-pagination">
+        <div class="table-wrapper has-mobile-cards">
+          {instances.length > 0 ?
+            <Table instances={instances} onPurge={onPurge} onUpdate={onUpdate} 
setInstanceName={setInstanceName} onDelete={onDelete} 
rowSelection={rowSelection} rowSelectionHandler={rowSelectionHandler} /> :
+            <EmptyTable />
+          }
+        </div>
+      </div>
+    </div>
+  </div>
+}
+interface TableProps {
+  rowSelection: string[];
+  instances: MerchantBackend.Instances.Instance[];
+  onUpdate: (id: string) => void;
+  onDelete: (id: MerchantBackend.Instances.Instance) => void;
+  onPurge: (id: MerchantBackend.Instances.Instance) => void;
+  rowSelectionHandler: StateUpdater<string[]>;
+  setInstanceName: (s:string) => void;
+}
+
+function toggleSelected<T>(id: T): (prev: T[]) => T[] {
+  return (prev: T[]): T[] => prev.indexOf(id) == -1 ? [...prev, id] : 
prev.filter(e => e != id)
+}
+
+function Table({ rowSelection, rowSelectionHandler, setInstanceName, 
instances, onUpdate, onDelete, onPurge }: TableProps): VNode {
+  return (
+    <div class="table-container">
+      <table class="table is-fullwidth is-striped is-hoverable is-fullwidth">
+        <thead>
+          <tr>
+            <th class="is-checkbox-cell">
+              <label class="b-checkbox checkbox">
+                <input type="checkbox" checked={rowSelection.length === 
instances.length} onClick={(): void => rowSelectionHandler(rowSelection.length 
=== instances.length ? [] : instances.map(i => i.id))} />
+                <span class="check" />
+              </label>
+            </th>
+            <th><Translate>ID</Translate></th>
+            <th><Translate>Name</Translate></th>
+            <th />
+          </tr>
+        </thead>
+        <tbody>
+          {instances.map(i => {
+            return <tr key={i.id}>
+              <td class="is-checkbox-cell">
+                <label class="b-checkbox checkbox">
+                  <input type="checkbox" checked={rowSelection.indexOf(i.id) 
!= -1} onClick={(): void => rowSelectionHandler(toggleSelected(i.id))} />
+                  <span class="check" />
+                </label>
+              </td>
+              <td><a href={`#/orders?instance=${i.id}`} onClick={(e) => {
+                setInstanceName(i.id);
+              }}>{i.id}</a></td>
+              <td >{i.name}</td>
+              <td class="is-actions-cell right-sticky">
+                <div class="buttons is-right">
+                  <button class="button is-small is-success jb-modal" 
type="button" onClick={(): void => onUpdate(i.id)}>
+                    <Translate>Edit</Translate>
+                  </button>
+                  {!i.deleted &&
+                  <button class="button is-small is-danger jb-modal 
is-outlined" type="button" onClick={(): void => onDelete(i)}>
+                    <Translate>Delete</Translate>
+                  </button>
+                  }
+                  {i.deleted &&
+                  <button class="button is-small is-danger jb-modal" 
type="button" onClick={(): void => onPurge(i)}>
+                    <Translate>Purge</Translate>
+                  </button>
+                  }
+                </div>
+              </td>
+            </tr>
+          })}
+
+        </tbody>
+      </table>
+    </div>
+  )
+}
+
+function EmptyTable(): VNode {
+  return <div class="content has-text-grey has-text-centered">
+    <p>
+      <span class="icon is-large"><i class="mdi mdi-emoticon-sad mdi-48px" 
/></span>
+    </p>
+    <p><Translate>There is no instances yet, add more pressing the + 
sign</Translate></p>
+  </div>
+}
+
+
+interface Actions {
+  element: MerchantBackend.Instances.Instance;
+  type: 'DELETE' | 'UPDATE';
+}
+
+function notEmpty<TValue>(value: TValue | null | undefined): value is TValue {
+  return value !== null && value !== undefined;
+}
+
+function buildActions(intances: MerchantBackend.Instances.Instance[], 
selected: string[], action: 'DELETE'): Actions[] {
+  return selected.map(id => intances.find(i => i.id === id))
+    .filter(notEmpty)
+    .map(id => ({ element: id, type: action }))
+}
+
+
diff --git 
a/packages/merchant-backoffice-ui/src/paths/admin/list/View.stories.tsx 
b/packages/merchant-backoffice-ui/src/paths/admin/list/View.stories.tsx
new file mode 100644
index 000000000..3da8c2e50
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/paths/admin/list/View.stories.tsx
@@ -0,0 +1,82 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h } from 'preact';
+import { View } from './View';
+
+
+export default {
+  title: 'Pages/Instance/List',
+  component: View,
+  argTypes: {
+    onSelect: { action: 'onSelect' },
+  },
+};
+
+export const Empty = (a: any) => <View {...a} />;
+Empty.args = {
+  instances: []
+}
+
+export const WithDefaultInstance = (a: any) => <View {...a} />;
+WithDefaultInstance.args = {
+  instances: [{
+    id: 'default',
+    name: 'the default instance',
+    merchant_pub: 'abcdef',
+    payment_targets: []
+  }]
+}
+
+export const WithFiveInstance = (a: any) => <View {...a} />;
+WithFiveInstance.args = {
+  instances: [{
+    id: 'first',
+    name: 'the first instance',
+    merchant_pub: 'abcdefgh',
+    payment_targets: ['asd']
+  }, {
+    id: 'second',
+    name: 'the second instance',
+    merchant_pub: 'zxczxcz',
+    payment_targets: ['asd']
+  }, {
+    id: 'third',
+    name: 'the third instance',
+    merchant_pub: 'QWEQWEWQE',
+    payment_targets: ['asd']
+  }, {
+    id: 'other',
+    name: 'the other instance',
+    merchant_pub: 'FHJHGJGHJ',
+    payment_targets: ['asd']
+  }, {
+    id: 'another',
+    name: 'the another instance',
+    merchant_pub: 'abcd3423423efgh',
+    payment_targets: ['asd']
+  }, {
+    id: 'last',
+    name: 'last instance',
+    merchant_pub: 'zxcvvbnm',
+    payment_targets: ['pay-to', 'asd']
+  }]
+}
diff --git a/packages/merchant-backoffice-ui/src/paths/admin/list/View.tsx 
b/packages/merchant-backoffice-ui/src/paths/admin/list/View.tsx
new file mode 100644
index 000000000..a77a5a1bf
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/paths/admin/list/View.tsx
@@ -0,0 +1,80 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode } from "preact";
+import { MerchantBackend } from "../../../declaration";
+import { CardTable as CardTableActive } from './TableActive';
+import { useState } from 'preact/hooks';
+import { Translate, useTranslator } from "../../../i18n";
+
+interface Props {
+  instances: MerchantBackend.Instances.Instance[];
+  onCreate: () => void;
+  onUpdate: (id: string) => void;
+  onDelete: (id: MerchantBackend.Instances.Instance) => void;
+  onPurge: (id: MerchantBackend.Instances.Instance) => void;
+  selected?: boolean;
+  setInstanceName: (s: string) => void;
+}
+
+export function View({ instances, onCreate, onDelete, onPurge, onUpdate, 
setInstanceName, selected }: Props): VNode {
+  const [show, setShow] = useState<"active" | "deleted" | null>("active");
+  const showIsActive = show === 'active' ? "is-active" : ''
+  const showIsDeleted = show === 'deleted' ? "is-active" : ''
+  const showAll = show === null ? "is-active" : ''
+  const i18n = useTranslator()
+
+  const showingInstances = showIsDeleted ? 
+    instances.filter(i => i.deleted) : (showIsActive ?
+      instances.filter(i => !i.deleted) :
+      instances)
+  
+  return <div id="app">
+
+    <section class="section is-main-section">
+      <div class="columns">
+        <div class="column is-two-thirds">
+          <div class="tabs" style={{ overflow: 'inherit' }}>
+            <ul>
+              <li class={showIsActive}>
+                <div class="has-tooltip-right" data-tooltip={i18n`Only show 
active instances`}>
+                  <a onClick={() => 
setShow("active")}><Translate>Active</Translate></a>
+                </div>
+              </li>
+              <li class={showIsDeleted}>
+                <div class="has-tooltip-right" data-tooltip={i18n`Only show 
deleted instances`}>
+                  <a onClick={() => 
setShow("deleted")}><Translate>Deleted</Translate></a>
+                </div>
+              </li>
+              <li class={showAll}>
+                <div class="has-tooltip-right" data-tooltip={i18n`Show all 
instances`}>
+                  <a onClick={() => 
setShow(null)}><Translate>All</Translate></a>
+                </div>
+              </li>
+            </ul>
+          </div>
+        </div>
+      </div>
+      <CardTableActive instances={showingInstances} onDelete={onDelete} 
onPurge={onPurge} setInstanceName={setInstanceName} onUpdate={onUpdate} 
selected={selected} onCreate={onCreate} />
+    </section>
+
+  </div >
+}
diff --git a/packages/merchant-backoffice-ui/src/paths/admin/list/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/admin/list/index.tsx
new file mode 100644
index 000000000..c5609fd10
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/paths/admin/list/index.tsx
@@ -0,0 +1,126 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { Fragment, h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { Loading } from "../../../components/exception/loading";
+import { NotificationCard } from "../../../components/menu";
+import { DeleteModal, PurgeModal } from "../../../components/modal";
+import { MerchantBackend } from "../../../declaration";
+import { HttpError } from "../../../hooks/backend";
+import { useAdminAPI, useBackendInstances } from "../../../hooks/instance";
+import { useTranslator } from "../../../i18n";
+import { Notification } from "../../../utils/types";
+import { View } from "./View";
+
+interface Props {
+  onCreate: () => void;
+  onUpdate: (id: string) => void;
+  instances: MerchantBackend.Instances.Instance[];
+  onUnauthorized: () => VNode;
+  onNotFound: () => VNode;
+  onLoadError: (error: HttpError) => VNode;
+  setInstanceName: (s: string) => void;
+}
+
+export default function Instances({
+  onUnauthorized,
+  onLoadError,
+  onNotFound,
+  onCreate,
+  onUpdate,
+  setInstanceName,
+}: Props): VNode {
+  const result = useBackendInstances();
+  const [deleting, setDeleting] =
+    useState<MerchantBackend.Instances.Instance | null>(null);
+  const [purging, setPurging] =
+    useState<MerchantBackend.Instances.Instance | null>(null);
+  const { deleteInstance, purgeInstance } = useAdminAPI();
+  const [notif, setNotif] = useState<Notification | undefined>(undefined);
+  const i18n = useTranslator();
+
+  if (result.clientError && result.isUnauthorized) return onUnauthorized();
+  if (result.clientError && result.isNotfound) return onNotFound();
+  if (result.loading) return <Loading />;
+  if (!result.ok) return onLoadError(result);
+
+  return (
+    <Fragment>
+      <NotificationCard notification={notif} />
+      <View
+        instances={result.data.instances}
+        onDelete={setDeleting}
+        onCreate={onCreate}
+        onPurge={setPurging}
+        onUpdate={onUpdate}
+        setInstanceName={setInstanceName}
+        selected={!!deleting}
+      />
+      {deleting && (
+        <DeleteModal
+          element={deleting}
+          onCancel={() => setDeleting(null)}
+          onConfirm={async (): Promise<void> => {
+            try {
+              await deleteInstance(deleting.id);
+              // pushNotification({ message: 'delete_success', type: 'SUCCESS' 
})
+              setNotif({
+                message: i18n`Instance "${deleting.name}" (ID: ${deleting.id}) 
has been deleted`,
+                type: "SUCCESS",
+              });
+            } catch (error) {
+              setNotif({
+                message: i18n`Failed to delete instance`,
+                type: "ERROR",
+                description: error instanceof Error ? error.message : 
undefined,
+              });
+              // pushNotification({ message: 'delete_error', type: 'ERROR' })
+            }
+            setDeleting(null);
+          }}
+        />
+      )}
+      {purging && (
+        <PurgeModal
+          element={purging}
+          onCancel={() => setPurging(null)}
+          onConfirm={async (): Promise<void> => {
+            try {
+              await purgeInstance(purging.id);
+              setNotif({
+                message: i18n`Instance "${purging.name}" (ID: ${purging.id}) 
has been disabled`,
+                type: "SUCCESS",
+              });
+            } catch (error) {
+              setNotif({
+                message: i18n`Failed to purge instance`,
+                type: "ERROR",
+                description: error instanceof Error ? error.message : 
undefined,
+              });
+            }
+            setPurging(null);
+          }}
+        />
+      )}
+    </Fragment>
+  );
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/details/DetailPage.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/details/DetailPage.tsx
new file mode 100644
index 000000000..2561f5842
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/paths/instance/details/DetailPage.tsx
@@ -0,0 +1,87 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { FormProvider } from "../../../components/form/FormProvider";
+import { Input } from "../../../components/form/Input";
+import { MerchantBackend } from "../../../declaration";
+import { useTranslator } from "../../../i18n";
+
+type Entity = MerchantBackend.Instances.InstanceReconfigurationMessage;
+interface Props {
+  onUpdate: () => void;
+  onDelete: () => void;
+  selected: MerchantBackend.Instances.QueryInstancesResponse;
+}
+
+function convert(from: MerchantBackend.Instances.QueryInstancesResponse): 
Entity {
+  const { accounts, ...rest } = from
+  const payto_uris = accounts.filter(a => a.active).map(a => a.payto_uri)
+  const defaults = {
+    default_wire_fee_amortization: 1,
+    default_pay_delay: { d_us: 1000 * 60 * 60 }, //one hour
+    default_wire_transfer_delay: { d_us: 1000 * 60 * 60 * 2 }, //two hours
+  }
+  return { ...defaults, ...rest, payto_uris };
+}
+
+export function DetailPage({ selected }: Props): VNode {
+  const [value, valueHandler] = useState<Partial<Entity>>(convert(selected))
+
+  const i18n = useTranslator()
+  
+  return <div>
+    <section class="hero is-hero-bar">
+      <div class="hero-body">
+        <div class="level">
+          <div class="level-left">
+            <div class="level-item">
+              <h1 class="title">
+                Here goes the instance description
+              </h1>
+            </div>
+          </div>
+          <div class="level-right" style="display: none;">
+            <div class="level-item" />
+          </div>
+        </div>
+      </div>
+    </section>
+
+    <section class="section is-main-section">
+      <div class="columns">
+        <div class="column" />
+        <div class="column is-6">
+          <FormProvider<Entity> object={value} valueHandler={valueHandler} >
+
+            <Input<Entity> name="name" readonly label={i18n`Name`} />
+            <Input<Entity> name="payto_uris" readonly label={i18n`Account 
address`} />
+
+          </FormProvider>
+        </div>
+        <div class="column" />
+      </div>
+    </section>
+
+  </div>
+
+}
\ No newline at end of file
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/details/Details.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/details/Details.stories.tsx
new file mode 100644
index 000000000..fb7c9144c
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/details/Details.stories.tsx
@@ -0,0 +1,61 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { h, VNode, FunctionalComponent } from "preact";
+import { DetailPage as TestedComponent } from "./DetailPage";
+
+export default {
+  title: "Pages/Instance/Detail",
+  component: TestedComponent,
+  argTypes: {
+    onUpdate: { action: "onUpdate" },
+    onBack: { action: "onBack" },
+  },
+};
+
+function createExample<Props>(
+  Component: FunctionalComponent<Props>,
+  props: Partial<Props>
+) {
+  const r = (args: any) => <Component {...args} />;
+  r.args = props;
+  return r;
+}
+
+export const Example = createExample(TestedComponent, {
+  selected: {
+    accounts: [],
+    name: "name",
+    auth: { method: "external" },
+    address: {},
+    jurisdiction: {},
+    default_max_deposit_fee: "TESTKUDOS:2",
+    default_max_wire_fee: "TESTKUDOS:1",
+    default_pay_delay: {
+      d_us: 1000000,
+    },
+    default_wire_fee_amortization: 1,
+    default_wire_transfer_delay: {
+      d_us: 100000,
+    },
+    merchant_pub: "ASDWQEKASJDKSADJ",
+  },
+});
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/details/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/details/index.tsx
new file mode 100644
index 000000000..15675891e
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/paths/instance/details/index.tsx
@@ -0,0 +1,65 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+import { Fragment, h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { Loading } from "../../../components/exception/loading";
+import { DeleteModal } from "../../../components/modal";
+import { useInstanceContext } from "../../../context/instance";
+import { HttpError } from "../../../hooks/backend";
+import { useInstanceAPI, useInstanceDetails } from "../../../hooks/instance";
+import { DetailPage } from "./DetailPage";
+
+interface Props {
+  onUnauthorized: () => VNode;
+  onLoadError: (error: HttpError) => VNode;
+  onUpdate: () => void;
+  onNotFound: () => VNode;
+  onDelete: () => void;
+}
+
+export default function Detail({ onUpdate, onLoadError, onUnauthorized, 
onDelete, onNotFound }: Props): VNode {
+  const { id } = useInstanceContext()
+  const result = useInstanceDetails()
+  const [deleting, setDeleting] = useState<boolean>(false)
+
+  const { deleteInstance } = useInstanceAPI()
+
+  if (result.clientError && result.isUnauthorized) return onUnauthorized()
+  if (result.clientError && result.isNotfound) return onNotFound()
+  if (result.loading) return <Loading />
+  if (!result.ok) return onLoadError(result)
+
+  return <Fragment>
+    <DetailPage
+      selected={result.data}
+      onUpdate={onUpdate}
+      onDelete={() => setDeleting(true)}
+    />
+    {deleting && <DeleteModal
+      element={{ name: result.data.name, id }}
+      onCancel={() => setDeleting(false)}
+      onConfirm={async (): Promise<void> => {
+        try {
+          await deleteInstance()
+          onDelete()
+        } catch (error) {
+        }
+        setDeleting(false)
+      }}
+    />}
+
+  </Fragment>
+}
\ No newline at end of file
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/kyc/list/ListPage.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/kyc/list/ListPage.tsx
new file mode 100644
index 000000000..52363d3cd
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/paths/instance/kyc/list/ListPage.tsx
@@ -0,0 +1,178 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { h, VNode } from "preact";
+import { MerchantBackend } from "../../../../declaration";
+import { Translate, useTranslator } from "../../../../i18n";
+
+export interface Props {
+  status: MerchantBackend.Instances.AccountKycRedirects;
+}
+
+export function ListPage({ status }: Props): VNode {
+  const i18n = useTranslator();
+
+  return (
+    <section class="section is-main-section">
+      <div class="card has-table">
+        <header class="card-header">
+          <p class="card-header-title">
+            <span class="icon">
+              <i class="mdi mdi-clock" />
+            </span>
+            <Translate>Pending KYC verification</Translate>
+          </p>
+
+          <div class="card-header-icon" aria-label="more options" />
+        </header>
+        <div class="card-content">
+          <div class="b-table has-pagination">
+            <div class="table-wrapper has-mobile-cards">
+              {status.pending_kycs.length > 0 ? (
+                <PendingTable entries={status.pending_kycs} />
+              ) : (
+                <EmptyTable />
+              )}
+            </div>
+          </div>
+        </div>
+      </div>
+
+      {status.timeout_kycs.length > 0 ? (
+        <div class="card has-table">
+          <header class="card-header">
+            <p class="card-header-title">
+              <span class="icon">
+                <i class="mdi mdi-clock" />
+              </span>
+              <Translate>Timed out</Translate>
+            </p>
+
+            <div class="card-header-icon" aria-label="more options" />
+          </header>
+          <div class="card-content">
+            <div class="b-table has-pagination">
+              <div class="table-wrapper has-mobile-cards">
+                {status.timeout_kycs.length > 0 ? (
+                  <TimedOutTable entries={status.timeout_kycs} />
+                ) : (
+                  <EmptyTable />
+                )}
+              </div>
+            </div>
+          </div>
+        </div>
+      ) : undefined}
+    </section>
+  );
+}
+interface PendingTableProps {
+  entries: MerchantBackend.Instances.MerchantAccountKycRedirect[];
+}
+
+interface TimedOutTableProps {
+  entries: MerchantBackend.Instances.ExchangeKycTimeout[];
+}
+
+function PendingTable({ entries }: PendingTableProps): VNode {
+  return (
+    <div class="table-container">
+      <table class="table is-striped is-hoverable is-fullwidth">
+        <thead>
+          <tr>
+            <th>
+              <Translate>Exchange</Translate>
+            </th>
+            <th>
+              <Translate>Target account</Translate>
+            </th>
+            <th>
+              <Translate>KYC URL</Translate>
+            </th>
+          </tr>
+        </thead>
+        <tbody>
+          {entries.map((e, i) => {
+            return (
+              <tr key={i}>
+                <td>{e.exchange_url}</td>
+                <td>{e.payto_uri}</td>
+                <td>
+                  <a href={e.kyc_url} target="_black" rel="noreferrer">
+                    {e.kyc_url}
+                  </a>
+                </td>
+              </tr>
+            );
+          })}
+        </tbody>
+      </table>
+    </div>
+  );
+}
+
+function TimedOutTable({ entries }: TimedOutTableProps): VNode {
+  return (
+    <div class="table-container">
+      <table class="table is-striped is-hoverable is-fullwidth">
+        <thead>
+          <tr>
+            <th>
+              <Translate>Exchange</Translate>
+            </th>
+            <th>
+              <Translate>Code</Translate>
+            </th>
+            <th>
+              <Translate>Http Status</Translate>
+            </th>
+          </tr>
+        </thead>
+        <tbody>
+          {entries.map((e, i) => {
+            return (
+              <tr key={i}>
+                <td>{e.exchange_url}</td>
+                <td>{e.exchange_code}</td>
+                <td>{e.exchange_http_status}</td>
+              </tr>
+            );
+          })}
+        </tbody>
+      </table>
+    </div>
+  );
+}
+
+function EmptyTable(): VNode {
+  return (
+    <div class="content has-text-grey has-text-centered">
+      <p>
+        <span class="icon is-large">
+          <i class="mdi mdi-emoticon-happy mdi-48px" />
+        </span>
+      </p>
+      <p>
+        <Translate>No pending kyc verification!</Translate>
+      </p>
+    </div>
+  );
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/kyc/list/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/kyc/list/index.tsx
new file mode 100644
index 000000000..5dff01994
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/paths/instance/kyc/list/index.tsx
@@ -0,0 +1,51 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { h, VNode } from "preact";
+import { Loading } from "../../../../components/exception/loading";
+import { HttpError } from "../../../../hooks/backend";
+import { useInstanceKYCDetails } from "../../../../hooks/instance";
+import { ListPage } from "./ListPage";
+
+interface Props {
+  onUnauthorized: () => VNode;
+  onLoadError: (error: HttpError) => VNode;
+  onNotFound: () => VNode;
+}
+
+export default function ListKYC({
+  onUnauthorized,
+  onLoadError,
+  onNotFound,
+}: Props): VNode {
+  const result = useInstanceKYCDetails();
+  if (result.clientError && result.isUnauthorized) return onUnauthorized();
+  if (result.clientError && result.isNotfound) return onNotFound();
+  if (result.loading) return <Loading />;
+  if (!result.ok) return onLoadError(result);
+
+  const status = result.data.type === "ok" ? undefined : result.data.status;
+
+  if (!status) {
+    return <div>no kyc required</div>;
+  }
+  return <ListPage status={status} />;
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/Create.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/Create.stories.tsx
new file mode 100644
index 000000000..43df8484a
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/Create.stories.tsx
@@ -0,0 +1,70 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { h, VNode, FunctionalComponent } from "preact";
+import { CreatePage as TestedComponent } from "./CreatePage";
+
+export default {
+  title: "Pages/Order/Create",
+  component: TestedComponent,
+  argTypes: {
+    onCreate: { action: "onCreate" },
+    goBack: { action: "goBack" },
+  },
+};
+
+function createExample<Props>(
+  Component: FunctionalComponent<Props>,
+  props: Partial<Props>
+) {
+  const r = (args: any) => <Component {...args} />;
+  r.args = props;
+  return r;
+}
+
+export const Example = createExample(TestedComponent, {
+  instanceConfig: {
+    default_max_deposit_fee: "",
+    default_max_wire_fee: "",
+    default_pay_delay: {
+      d_us: 1000 * 60 * 60,
+    },
+    default_wire_fee_amortization: 1,
+  },
+  instanceInventory: [
+    {
+      id: "t-shirt-1",
+      description: "a m size t-shirt",
+      price: "TESTKUDOS:1",
+      total_stock: -1,
+    },
+    {
+      id: "t-shirt-2",
+      price: "TESTKUDOS:1",
+      description: "a xl size t-shirt",
+    } as any,
+    {
+      id: "t-shirt-3",
+      price: "TESTKUDOS:1",
+      description: "a s size t-shirt",
+    } as any,
+  ],
+});
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/CreatePage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/CreatePage.tsx
new file mode 100644
index 000000000..c08d8ee1d
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/CreatePage.tsx
@@ -0,0 +1,576 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { add, isAfter, isBefore, isFuture } from "date-fns";
+import { Amounts } from "@gnu-taler/taler-util";
+import { Fragment, h, VNode } from "preact";
+import { useEffect, useState } from "preact/hooks";
+import {
+  FormProvider,
+  FormErrors,
+} from "../../../../components/form/FormProvider";
+import { Input } from "../../../../components/form/Input";
+import { InputCurrency } from "../../../../components/form/InputCurrency";
+import { InputDate } from "../../../../components/form/InputDate";
+import { InputGroup } from "../../../../components/form/InputGroup";
+import { InputLocation } from "../../../../components/form/InputLocation";
+import { ProductList } from "../../../../components/product/ProductList";
+import { useConfigContext } from "../../../../context/config";
+import { Duration, MerchantBackend, WithId } from "../../../../declaration";
+import { Translate, useTranslator } from "../../../../i18n";
+import { OrderCreateSchema as schema } from "../../../../schemas/index";
+import { rate } from "../../../../utils/amount";
+import { InventoryProductForm } from 
"../../../../components/product/InventoryProductForm";
+import { NonInventoryProductFrom } from 
"../../../../components/product/NonInventoryProductForm";
+import { InputNumber } from "../../../../components/form/InputNumber";
+import { InputBoolean } from "../../../../components/form/InputBoolean";
+
+interface Props {
+  onCreate: (d: MerchantBackend.Orders.PostOrderRequest) => void;
+  onBack?: () => void;
+  instanceConfig: InstanceConfig;
+  instanceInventory: (MerchantBackend.Products.ProductDetail & WithId)[];
+}
+interface InstanceConfig {
+  default_max_wire_fee: string;
+  default_max_deposit_fee: string;
+  default_wire_fee_amortization: number;
+  default_pay_delay: Duration;
+}
+
+function with_defaults(config: InstanceConfig): Partial<Entity> {
+  const defaultPayDeadline =
+    !config.default_pay_delay || config.default_pay_delay.d_us === "forever"
+      ? undefined
+      : add(new Date(), { seconds: config.default_pay_delay.d_us / 1000 });
+
+  return {
+    inventoryProducts: {},
+    products: [],
+    pricing: {},
+    payments: {
+      max_wire_fee: config.default_max_wire_fee,
+      max_fee: config.default_max_deposit_fee,
+      wire_fee_amortization: config.default_wire_fee_amortization,
+      pay_deadline: defaultPayDeadline,
+      refund_deadline: defaultPayDeadline,
+      createToken: true,
+    },
+    shipping: {},
+    extra: "",
+  };
+}
+
+interface ProductAndQuantity {
+  product: MerchantBackend.Products.ProductDetail & WithId;
+  quantity: number;
+}
+export interface ProductMap {
+  [id: string]: ProductAndQuantity;
+}
+
+interface Pricing {
+  products_price: string;
+  order_price: string;
+  summary: string;
+}
+interface Shipping {
+  delivery_date?: Date;
+  delivery_location?: MerchantBackend.Location;
+  fullfilment_url?: string;
+}
+interface Payments {
+  refund_deadline?: Date;
+  pay_deadline?: Date;
+  wire_transfer_deadline?: Date;
+  auto_refund_deadline?: Date;
+  max_fee?: string;
+  max_wire_fee?: string;
+  wire_fee_amortization?: number;
+  createToken: boolean;
+  minimum_age?: number;
+}
+interface Entity {
+  inventoryProducts: ProductMap;
+  products: MerchantBackend.Product[];
+  pricing: Partial<Pricing>;
+  payments: Partial<Payments>;
+  shipping: Partial<Shipping>;
+  extra: string;
+}
+
+const stringIsValidJSON = (value: string) => {
+  try {
+    JSON.parse(value.trim());
+    return true;
+  } catch {
+    return false;
+  }
+};
+
+function undefinedIfEmpty<T>(obj: T): T | undefined {
+  return Object.keys(obj).some((k) => (obj as any)[k] !== undefined)
+    ? obj
+    : undefined;
+}
+
+export function CreatePage({
+  onCreate,
+  onBack,
+  instanceConfig,
+  instanceInventory,
+}: Props): VNode {
+  const [value, valueHandler] = useState(with_defaults(instanceConfig));
+  const config = useConfigContext();
+  const zero = Amounts.getZero(config.currency);
+
+  const inventoryList = Object.values(value.inventoryProducts || {});
+  const productList = Object.values(value.products || {});
+
+  const i18n = useTranslator();
+
+  const errors: FormErrors<Entity> = {
+    pricing: undefinedIfEmpty({
+      summary: !value.pricing?.summary ? i18n`required` : undefined,
+      order_price: !value.pricing?.order_price
+        ? i18n`required`
+        : Amounts.isZero(value.pricing.order_price)
+        ? i18n`must be greater than 0`
+        : undefined,
+    }),
+    extra:
+      value.extra && !stringIsValidJSON(value.extra)
+        ? i18n`not a valid json`
+        : undefined,
+    payments: undefinedIfEmpty({
+      refund_deadline: !value.payments?.refund_deadline
+        ? undefined
+        : !isFuture(value.payments.refund_deadline)
+        ? i18n`should be in the future`
+        : value.payments.pay_deadline &&
+          isBefore(value.payments.refund_deadline, value.payments.pay_deadline)
+        ? i18n`refund deadline cannot be before pay deadline`
+        : value.payments.wire_transfer_deadline &&
+          isBefore(
+            value.payments.wire_transfer_deadline,
+            value.payments.refund_deadline
+          )
+        ? i18n`wire transfer deadline cannot be before refund deadline`
+        : undefined,
+      pay_deadline: !value.payments?.pay_deadline
+        ? undefined
+        : !isFuture(value.payments.pay_deadline)
+        ? i18n`should be in the future`
+        : value.payments.wire_transfer_deadline &&
+          isBefore(
+            value.payments.wire_transfer_deadline,
+            value.payments.pay_deadline
+          )
+        ? i18n`wire transfer deadline cannot be before pay deadline`
+        : undefined,
+      auto_refund_deadline: !value.payments?.auto_refund_deadline
+        ? undefined
+        : !isFuture(value.payments.auto_refund_deadline)
+        ? i18n`should be in the future`
+        : !value.payments?.refund_deadline
+        ? i18n`should have a refund deadline`
+        : !isAfter(
+            value.payments.refund_deadline,
+            value.payments.auto_refund_deadline
+          )
+        ? i18n`auto refund cannot be after refund deadline`
+        : undefined,
+    }),
+    shipping: undefinedIfEmpty({
+      delivery_date: !value.shipping?.delivery_date
+        ? undefined
+        : !isFuture(value.shipping.delivery_date)
+        ? i18n`should be in the future`
+        : undefined,
+    }),
+  };
+  const hasErrors = Object.keys(errors).some(
+    (k) => (errors as any)[k] !== undefined
+  );
+
+  const submit = (): void => {
+    const order = schema.cast(value);
+    if (!value.payments) return;
+    if (!value.shipping) return;
+
+    const request: MerchantBackend.Orders.PostOrderRequest = {
+      order: {
+        amount: order.pricing.order_price,
+        summary: order.pricing.summary,
+        products: productList,
+        extra: value.extra,
+        pay_deadline: value.payments.pay_deadline
+          ? {
+              t_s: Math.floor(value.payments.pay_deadline.getTime() / 1000),
+            }
+          : undefined,
+        wire_transfer_deadline: value.payments.wire_transfer_deadline
+          ? {
+              t_s: Math.floor(
+                value.payments.wire_transfer_deadline.getTime() / 1000
+              ),
+            }
+          : undefined,
+        refund_deadline: value.payments.refund_deadline
+          ? {
+              t_s: Math.floor(value.payments.refund_deadline.getTime() / 1000),
+            }
+          : undefined,
+        auto_refund: value.payments.auto_refund_deadline
+          ? {
+              d_us: Math.floor(
+                value.payments.auto_refund_deadline.getTime() * 1000
+              ),
+            }
+          : undefined,
+        wire_fee_amortization: value.payments.wire_fee_amortization as number,
+        max_fee: value.payments.max_fee as string,
+        max_wire_fee: value.payments.max_wire_fee as string,
+
+        delivery_date: value.shipping.delivery_date
+          ? { t_s: value.shipping.delivery_date.getTime() / 1000 }
+          : undefined,
+        delivery_location: value.shipping.delivery_location,
+        fulfillment_url: value.shipping.fullfilment_url,
+        minimum_age: value.payments.minimum_age,
+      },
+      inventory_products: inventoryList.map((p) => ({
+        product_id: p.product.id,
+        quantity: p.quantity,
+      })),
+      create_token: value.payments.createToken,
+    };
+
+    onCreate(request);
+  };
+
+  const addProductToTheInventoryList = (
+    product: MerchantBackend.Products.ProductDetail & WithId,
+    quantity: number
+  ) => {
+    valueHandler((v) => {
+      const inventoryProducts = { ...v.inventoryProducts };
+      inventoryProducts[product.id] = { product, quantity };
+      return { ...v, inventoryProducts };
+    });
+  };
+
+  const removeProductFromTheInventoryList = (id: string) => {
+    valueHandler((v) => {
+      const inventoryProducts = { ...v.inventoryProducts };
+      delete inventoryProducts[id];
+      return { ...v, inventoryProducts };
+    });
+  };
+
+  const addNewProduct = async (product: MerchantBackend.Product) => {
+    return valueHandler((v) => {
+      const products = v.products ? [...v.products, product] : [];
+      return { ...v, products };
+    });
+  };
+
+  const removeFromNewProduct = (index: number) => {
+    valueHandler((v) => {
+      const products = v.products ? [...v.products] : [];
+      products.splice(index, 1);
+      return { ...v, products };
+    });
+  };
+
+  const [editingProduct, setEditingProduct] = useState<
+    MerchantBackend.Product | undefined
+  >(undefined);
+
+  const totalPriceInventory = inventoryList.reduce((prev, cur) => {
+    const p = Amounts.parseOrThrow(cur.product.price);
+    return Amounts.add(prev, Amounts.mult(p, cur.quantity).amount).amount;
+  }, zero);
+
+  const totalPriceProducts = productList.reduce((prev, cur) => {
+    if (!cur.price) return zero;
+    const p = Amounts.parseOrThrow(cur.price);
+    return Amounts.add(prev, Amounts.mult(p, cur.quantity).amount).amount;
+  }, zero);
+
+  const hasProducts = inventoryList.length > 0 || productList.length > 0;
+  const totalPrice = Amounts.add(totalPriceInventory, totalPriceProducts);
+
+  const totalAsString = Amounts.stringify(totalPrice.amount);
+  const allProducts = productList.concat(inventoryList.map(asProduct));
+
+  useEffect(() => {
+    valueHandler((v) => {
+      return {
+        ...v,
+        pricing: {
+          ...v.pricing,
+          products_price: hasProducts ? totalAsString : undefined,
+          order_price: hasProducts ? totalAsString : undefined,
+        },
+      };
+    });
+  }, [hasProducts, totalAsString]);
+
+  const discountOrRise = rate(
+    value.pricing?.order_price || `${config.currency}:0`,
+    totalAsString
+  );
+
+  const minAgeByProducts = allProducts.reduce(
+    (cur, prev) =>
+      !prev.minimum_age || cur > prev.minimum_age ? cur : prev.minimum_age,
+    0
+  );
+  return (
+    <div>
+      <section class="section is-main-section">
+        <div class="columns">
+          <div class="column" />
+          <div class="column is-four-fifths">
+            {/* // FIXME: translating plural singular */}
+            <InputGroup
+              name="inventory_products"
+              label={i18n`Manage products in order`}
+              alternative={
+                allProducts.length > 0 && (
+                  <p>
+                    {allProducts.length} products with a total price of{" "}
+                    {totalAsString}.
+                  </p>
+                )
+              }
+              tooltip={i18n`Manage list of products in the order.`}
+            >
+              <InventoryProductForm
+                currentProducts={value.inventoryProducts || {}}
+                onAddProduct={addProductToTheInventoryList}
+                inventory={instanceInventory}
+              />
+
+              <NonInventoryProductFrom
+                productToEdit={editingProduct}
+                onAddProduct={(p) => {
+                  setEditingProduct(undefined);
+                  return addNewProduct(p);
+                }}
+              />
+
+              {allProducts.length > 0 && (
+                <ProductList
+                  list={allProducts}
+                  actions={[
+                    {
+                      name: i18n`Remove`,
+                      tooltip: i18n`Remove this product from the order.`,
+                      handler: (e, index) => {
+                        if (e.product_id) {
+                          removeProductFromTheInventoryList(e.product_id);
+                        } else {
+                          removeFromNewProduct(index);
+                          setEditingProduct(e);
+                        }
+                      },
+                    },
+                  ]}
+                />
+              )}
+            </InputGroup>
+
+            <FormProvider<Entity>
+              errors={errors}
+              object={value}
+              valueHandler={valueHandler as any}
+            >
+              {hasProducts ? (
+                <Fragment>
+                  <InputCurrency
+                    name="pricing.products_price"
+                    label={i18n`Total price`}
+                    readonly
+                    tooltip={i18n`total product price added up`}
+                  />
+                  <InputCurrency
+                    name="pricing.order_price"
+                    label={i18n`Total price`}
+                    addonAfter={
+                      discountOrRise > 0 &&
+                      (discountOrRise < 1
+                        ? `discount of %${Math.round(
+                            (1 - discountOrRise) * 100
+                          )}`
+                        : `rise of %${Math.round((discountOrRise - 1) * 100)}`)
+                    }
+                    tooltip={i18n`Amount to be paid by the customer`}
+                  />
+                </Fragment>
+              ) : (
+                <InputCurrency
+                  name="pricing.order_price"
+                  label={i18n`Order price`}
+                  tooltip={i18n`final order price`}
+                />
+              )}
+
+              <Input
+                name="pricing.summary"
+                inputType="multiline"
+                label={i18n`Summary`}
+                tooltip={i18n`Title of the order to be shown to the customer`}
+              />
+
+              <InputGroup
+                name="shipping"
+                label={i18n`Shipping and Fulfillment`}
+                initialActive
+              >
+                <InputDate
+                  name="shipping.delivery_date"
+                  label={i18n`Delivery date`}
+                  tooltip={i18n`Deadline for physical delivery assured by the 
merchant.`}
+                />
+                {value.shipping?.delivery_date && (
+                  <InputGroup
+                    name="shipping.delivery_location"
+                    label={i18n`Location`}
+                    tooltip={i18n`address where the products will be 
delivered`}
+                  >
+                    <InputLocation name="shipping.delivery_location" />
+                  </InputGroup>
+                )}
+                <Input
+                  name="shipping.fullfilment_url"
+                  label={i18n`Fulfillment URL`}
+                  tooltip={i18n`URL to which the user will be redirected after 
successful payment.`}
+                />
+              </InputGroup>
+
+              <InputGroup
+                name="payments"
+                label={i18n`Taler payment options`}
+                tooltip={i18n`Override default Taler payment settings for this 
order`}
+              >
+                <InputDate
+                  name="payments.pay_deadline"
+                  label={i18n`Payment deadline`}
+                  tooltip={i18n`Deadline for the customer to pay for the offer 
before it expires. Inventory products will be reserved until this deadline.`}
+                />
+                <InputDate
+                  name="payments.refund_deadline"
+                  label={i18n`Refund deadline`}
+                  tooltip={i18n`Time until which the order can be refunded by 
the merchant.`}
+                />
+                <InputDate
+                  name="payments.wire_transfer_deadline"
+                  label={i18n`Wire transfer deadline`}
+                  tooltip={i18n`Deadline for the exchange to make the wire 
transfer.`}
+                />
+                <InputDate
+                  name="payments.auto_refund_deadline"
+                  label={i18n`Auto-refund deadline`}
+                  tooltip={i18n`Time until which the wallet will automatically 
check for refunds without user interaction.`}
+                />
+
+                <InputCurrency
+                  name="payments.max_fee"
+                  label={i18n`Maximum deposit fee`}
+                  tooltip={i18n`Maximum deposit fees the merchant is willing 
to cover for this order. Higher deposit fees must be covered in full by the 
consumer.`}
+                />
+                <InputCurrency
+                  name="payments.max_wire_fee"
+                  label={i18n`Maximum wire fee`}
+                  tooltip={i18n`Maximum aggregate wire fees the merchant is 
willing to cover for this order. Wire fees exceeding this amount are to be 
covered by the customers.`}
+                />
+                <InputNumber
+                  name="payments.wire_fee_amortization"
+                  label={i18n`Wire fee amortization`}
+                  tooltip={i18n`Factor by which wire fees exceeding the above 
threshold are divided to determine the share of excess wire fees to be paid 
explicitly by the consumer.`}
+                />
+                <InputBoolean
+                  name="payments.createToken"
+                  label={i18n`Create token`}
+                  tooltip={i18n`Uncheck this option if the merchant backend 
generated an order ID with enough entropy to prevent adversarial claims.`}
+                />
+                <InputNumber
+                  name="payments.minimum_age"
+                  label={i18n`Minimum age required`}
+                  tooltip={i18n`Any value greater than 0 will limit the coins 
able be used to pay this contract. If empty the age restriction will be defined 
by the products`}
+                  help={
+                    minAgeByProducts > 0
+                      ? i18n`Min age defined by the producs is 
${minAgeByProducts}`
+                      : undefined
+                  }
+                />
+              </InputGroup>
+
+              <InputGroup
+                name="extra"
+                label={i18n`Additional information`}
+                tooltip={i18n`Custom information to be included in the 
contract for this order.`}
+              >
+                <Input
+                  name="extra"
+                  inputType="multiline"
+                  label={`Value`}
+                  tooltip={i18n`You must enter a value in JavaScript Object 
Notation (JSON).`}
+                />
+              </InputGroup>
+            </FormProvider>
+
+            <div class="buttons is-right mt-5">
+              {onBack && (
+                <button class="button" onClick={onBack}>
+                  <Translate>Cancel</Translate>
+                </button>
+              )}
+              <button
+                class="button is-success"
+                onClick={submit}
+                disabled={hasErrors}
+              >
+                <Translate>Confirm</Translate>
+              </button>
+            </div>
+          </div>
+          <div class="column" />
+        </div>
+      </section>
+    </div>
+  );
+}
+
+function asProduct(p: ProductAndQuantity): MerchantBackend.Product {
+  return {
+    product_id: p.product.id,
+    image: p.product.image,
+    price: p.product.price,
+    unit: p.product.unit,
+    quantity: p.quantity,
+    description: p.product.description,
+    taxes: p.product.taxes,
+    minimum_age: p.product.minimum_age,
+  };
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/OrderCreatedSuccessfully.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/OrderCreatedSuccessfully.tsx
new file mode 100644
index 000000000..14c5d68c3
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/OrderCreatedSuccessfully.tsx
@@ -0,0 +1,89 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+import { h, VNode } from "preact";
+import { useEffect, useState } from "preact/hooks";
+import { CreatedSuccessfully } from 
"../../../../components/notifications/CreatedSuccessfully";
+import { useOrderAPI } from "../../../../hooks/order";
+import { Translate } from "../../../../i18n";
+import { Entity } from "./index";
+
+interface Props {
+  entity: Entity;
+  onConfirm: () => void;
+  onCreateAnother?: () => void;
+}
+
+export function OrderCreatedSuccessfully({ entity, onConfirm, onCreateAnother 
}: Props): VNode {
+  const { getPaymentURL } = useOrderAPI()
+  const [url, setURL] = useState<string | undefined>(undefined)
+
+  useEffect(() => {
+    getPaymentURL(entity.response.order_id).then(response => {
+      setURL(response.data)
+    })
+  }, [getPaymentURL, entity.response.order_id])
+
+  return <CreatedSuccessfully onConfirm={onConfirm} 
onCreateAnother={onCreateAnother}>
+    <div class="field is-horizontal">
+      <div class="field-label is-normal">
+        <label class="label"><Translate>Amount</Translate></label>
+      </div>
+      <div class="field-body is-flex-grow-3">
+        <div class="field">
+          <p class="control">
+            <input class="input" readonly value={entity.request.order.amount} 
/>
+          </p>
+        </div>
+      </div>
+    </div>
+    <div class="field is-horizontal">
+      <div class="field-label is-normal">
+        <label class="label"><Translate>Summary</Translate></label>
+      </div>
+      <div class="field-body is-flex-grow-3">
+        <div class="field">
+          <p class="control">
+            <input class="input" readonly value={entity.request.order.summary} 
/>
+          </p>
+        </div>
+      </div>
+    </div>
+    <div class="field is-horizontal">
+      <div class="field-label is-normal">
+        <label class="label"><Translate>Order ID</Translate></label>
+      </div>
+      <div class="field-body is-flex-grow-3">
+        <div class="field">
+          <p class="control">
+            <input class="input" readonly value={entity.response.order_id} />
+          </p>
+        </div>
+      </div>
+    </div>
+    <div class="field is-horizontal">
+      <div class="field-label is-normal">
+        <label class="label"><Translate>Payment URL</Translate></label>
+      </div>
+      <div class="field-body is-flex-grow-3">
+        <div class="field">
+          <p class="control">
+            <input class="input" readonly value={url} />
+          </p>
+        </div>
+      </div>
+    </div>
+  </CreatedSuccessfully>;
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/index.tsx
new file mode 100644
index 000000000..c447c4b04
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/index.tsx
@@ -0,0 +1,82 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { Fragment, h, VNode } from 'preact';
+import { useState } from 'preact/hooks';
+import { Loading } from '../../../../components/exception/loading';
+import { NotificationCard } from '../../../../components/menu';
+import { MerchantBackend } from '../../../../declaration';
+import { HttpError } from '../../../../hooks/backend';
+import { useInstanceDetails } from '../../../../hooks/instance';
+import { useOrderAPI } from '../../../../hooks/order';
+import { useInstanceProducts } from '../../../../hooks/product';
+import { Notification } from '../../../../utils/types';
+import { CreatePage } from './CreatePage';
+import { OrderCreatedSuccessfully } from './OrderCreatedSuccessfully';
+
+export type Entity = {
+  request: MerchantBackend.Orders.PostOrderRequest,
+  response: MerchantBackend.Orders.PostOrderResponse
+}
+interface Props {
+  onBack?: () => void;
+  onConfirm: () => void;
+  onUnauthorized: () => VNode;
+  onNotFound: () => VNode;
+  onLoadError: (error: HttpError) => VNode;
+}
+export default function OrderCreate({ onConfirm, onBack, onLoadError, 
onNotFound, onUnauthorized }: Props): VNode {
+  const { createOrder } = useOrderAPI()
+  const [notif, setNotif] = useState<Notification | undefined>(undefined)
+
+  const detailsResult = useInstanceDetails()
+  const inventoryResult = useInstanceProducts()
+
+  if (detailsResult.clientError && detailsResult.isUnauthorized) return 
onUnauthorized()
+  if (detailsResult.clientError && detailsResult.isNotfound) return 
onNotFound()
+  if (detailsResult.loading) return <Loading />
+  if (!detailsResult.ok) return onLoadError(detailsResult)
+
+  if (inventoryResult.clientError && inventoryResult.isUnauthorized) return 
onUnauthorized()
+  if (inventoryResult.clientError && inventoryResult.isNotfound) return 
onNotFound()
+  if (inventoryResult.loading) return <Loading />
+  if (!inventoryResult.ok) return onLoadError(inventoryResult)
+
+  return <Fragment>
+    
+    <NotificationCard notification={notif} />
+
+    <CreatePage
+      onBack={onBack}
+      onCreate={(request: MerchantBackend.Orders.PostOrderRequest) => {
+        createOrder(request).then(onConfirm).catch((error) => {
+          setNotif({
+            message: 'could not create order',
+            type: "ERROR",
+            description: error.message
+          })
+        })
+      }} 
+      instanceConfig={detailsResult.data}
+      instanceInventory={inventoryResult.data}
+      />
+  </Fragment>
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/details/Detail.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/details/Detail.stories.tsx
new file mode 100644
index 000000000..812b11a76
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/details/Detail.stories.tsx
@@ -0,0 +1,137 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { addDays } from "date-fns";
+import { h, VNode, FunctionalComponent } from "preact";
+import { MerchantBackend } from "../../../../declaration";
+import { DetailPage as TestedComponent } from "./DetailPage";
+
+export default {
+  title: "Pages/Order/Detail",
+  component: TestedComponent,
+  argTypes: {
+    onRefund: { action: "onRefund" },
+    onBack: { action: "onBack" },
+  },
+};
+
+function createExample<Props>(
+  Component: FunctionalComponent<Props>,
+  props: Partial<Props>
+) {
+  const r = (args: any) => <Component {...args} />;
+  r.args = props;
+  return r;
+}
+
+const defaultContractTerm = {
+  amount: "TESTKUDOS:10",
+  timestamp: {
+    t_s: new Date().getTime() / 1000,
+  },
+  auditors: [],
+  exchanges: [],
+  max_fee: "TESTKUDOS:1",
+  max_wire_fee: "TESTKUDOS:1",
+  merchant: {} as any,
+  merchant_base_url: "http://merchant.url/";,
+  order_id: "2021.165-03GDFC26Y1NNG",
+  products: [],
+  summary: "text summary",
+  wire_fee_amortization: 1,
+  wire_transfer_deadline: {
+    t_s: "never",
+  },
+  refund_deadline: { t_s: "never" },
+  merchant_pub: "ASDASDASDSd",
+  nonce: "QWEQWEQWE",
+  pay_deadline: {
+    t_s: "never",
+  },
+  wire_method: "x-taler-bank",
+  h_wire: "asd",
+} as MerchantBackend.ContractTerms;
+
+// contract_terms: defaultContracTerm,
+export const Claimed = createExample(TestedComponent, {
+  id: "2021.165-03GDFC26Y1NNG",
+  selected: {
+    order_status: "claimed",
+    contract_terms: defaultContractTerm,
+  },
+});
+
+export const PaidNotRefundable = createExample(TestedComponent, {
+  id: "2021.165-03GDFC26Y1NNG",
+  selected: {
+    order_status: "paid",
+    contract_terms: defaultContractTerm,
+    refunded: false,
+    deposit_total: "TESTKUDOS:10",
+    exchange_ec: 0,
+    order_status_url: "http://merchant.backend/status";,
+    exchange_hc: 0,
+    refund_amount: "TESTKUDOS:0",
+    refund_details: [],
+    refund_pending: false,
+    wire_details: [],
+    wire_reports: [],
+    wired: false,
+  },
+});
+
+export const PaidRefundable = createExample(TestedComponent, {
+  id: "2021.165-03GDFC26Y1NNG",
+  selected: {
+    order_status: "paid",
+    contract_terms: {
+      ...defaultContractTerm,
+      refund_deadline: {
+        t_s: addDays(new Date(), 2).getTime() / 1000,
+      },
+    },
+    refunded: false,
+    deposit_total: "TESTKUDOS:10",
+    exchange_ec: 0,
+    order_status_url: "http://merchant.backend/status";,
+    exchange_hc: 0,
+    refund_amount: "TESTKUDOS:0",
+    refund_details: [],
+    refund_pending: false,
+    wire_details: [],
+    wire_reports: [],
+    wired: false,
+  },
+});
+
+export const Unpaid = createExample(TestedComponent, {
+  id: "2021.165-03GDFC26Y1NNG",
+  selected: {
+    order_status: "unpaid",
+    order_status_url: "http://merchant.backend/status";,
+    creation_time: {
+      t_s: new Date().getTime() / 1000,
+    },
+    summary: "text summary",
+    taler_pay_uri: "pay uri",
+    total_amount: "TESTKUDOS:10",
+  },
+});
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/details/DetailPage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/details/DetailPage.tsx
new file mode 100644
index 000000000..4bb7051d6
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/details/DetailPage.tsx
@@ -0,0 +1,776 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { AmountJson, Amounts } from "@gnu-taler/taler-util";
+import { format } from "date-fns";
+import { Fragment, h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { FormProvider } from "../../../../components/form/FormProvider";
+import { Input } from "../../../../components/form/Input";
+import { InputCurrency } from "../../../../components/form/InputCurrency";
+import { InputDate } from "../../../../components/form/InputDate";
+import { InputDuration } from "../../../../components/form/InputDuration";
+import { InputGroup } from "../../../../components/form/InputGroup";
+import { InputLocation } from "../../../../components/form/InputLocation";
+import { TextField } from "../../../../components/form/TextField";
+import { ProductList } from "../../../../components/product/ProductList";
+import { useBackendContext } from "../../../../context/backend";
+import { MerchantBackend } from "../../../../declaration";
+import { Translate, useTranslator } from "../../../../i18n";
+import { mergeRefunds } from "../../../../utils/amount";
+import { RefundModal } from "../list/Table";
+import { Event, Timeline } from "./Timeline";
+
+type Entity = MerchantBackend.Orders.MerchantOrderStatusResponse;
+type CT = MerchantBackend.ContractTerms;
+
+interface Props {
+  onBack: () => void;
+  selected: Entity;
+  id: string;
+  onRefund: (id: string, value: MerchantBackend.Orders.RefundRequest) => void;
+}
+
+type Paid = MerchantBackend.Orders.CheckPaymentPaidResponse & {
+  refund_taken: string;
+};
+type Unpaid = MerchantBackend.Orders.CheckPaymentUnpaidResponse;
+type Claimed = MerchantBackend.Orders.CheckPaymentClaimedResponse;
+
+function ContractTerms({ value }: { value: CT }) {
+  const i18n = useTranslator();
+
+  return (
+    <InputGroup name="contract_terms" label={i18n`Contract Terms`}>
+      <FormProvider<CT> object={value} valueHandler={null}>
+        <Input<CT>
+          readonly
+          name="summary"
+          label={i18n`Summary`}
+          tooltip={i18n`human-readable description of the whole purchase`}
+        />
+        <InputCurrency<CT>
+          readonly
+          name="amount"
+          label={i18n`Amount`}
+          tooltip={i18n`total price for the transaction`}
+        />
+        {value.fulfillment_url && (
+          <Input<CT>
+            readonly
+            name="fulfillment_url"
+            label={i18n`Fulfillment URL`}
+            tooltip={i18n`URL for this purchase`}
+          />
+        )}
+        <Input<CT>
+          readonly
+          name="max_fee"
+          label={i18n`Max fee`}
+          tooltip={i18n`maximum total deposit fee accepted by the merchant for 
this contract`}
+        />
+        <Input<CT>
+          readonly
+          name="max_wire_fee"
+          label={i18n`Max wire fee`}
+          tooltip={i18n`maximum wire fee accepted by the merchant`}
+        />
+        <Input<CT>
+          readonly
+          name="wire_fee_amortization"
+          label={i18n`Wire fee amortization`}
+          tooltip={i18n`over how many customer transactions does the merchant 
expect to amortize wire fees on average`}
+        />
+        <InputDate<CT>
+          readonly
+          name="timestamp"
+          label={i18n`Created at`}
+          tooltip={i18n`time when this contract was generated`}
+        />
+        <InputDate<CT>
+          readonly
+          name="refund_deadline"
+          label={i18n`Refund deadline`}
+          tooltip={i18n`after this deadline has passed no refunds will be 
accepted`}
+        />
+        <InputDate<CT>
+          readonly
+          name="pay_deadline"
+          label={i18n`Payment deadline`}
+          tooltip={i18n`after this deadline, the merchant won't accept 
payments for the contract`}
+        />
+        <InputDate<CT>
+          readonly
+          name="wire_transfer_deadline"
+          label={i18n`Wire transfer deadline`}
+          tooltip={i18n`transfer deadline for the exchange`}
+        />
+        <InputDate<CT>
+          readonly
+          name="delivery_date"
+          label={i18n`Delivery date`}
+          tooltip={i18n`time indicating when the order should be delivered`}
+        />
+        {value.delivery_date && (
+          <InputGroup
+            name="delivery_location"
+            label={i18n`Location`}
+            tooltip={i18n`where the order will be delivered`}
+          >
+            <InputLocation name="payments.delivery_location" />
+          </InputGroup>
+        )}
+        <InputDuration<CT>
+          readonly
+          name="auto_refund"
+          label={i18n`Auto-refund delay`}
+          tooltip={i18n`how long the wallet should try to get an automatic 
refund for the purchase`}
+        />
+        <Input<CT>
+          readonly
+          name="extra"
+          label={i18n`Extra info`}
+          tooltip={i18n`extra data that is only interpreted by the merchant 
frontend`}
+        />
+      </FormProvider>
+    </InputGroup>
+  );
+}
+
+function ClaimedPage({
+  id,
+  order,
+}: {
+  id: string;
+  order: MerchantBackend.Orders.CheckPaymentClaimedResponse;
+}) {
+  const events: Event[] = [];
+  if (order.contract_terms.timestamp.t_s !== "never") {
+    events.push({
+      when: new Date(order.contract_terms.timestamp.t_s * 1000),
+      description: "order created",
+      type: "start",
+    });
+  }
+  if (order.contract_terms.pay_deadline.t_s !== "never") {
+    events.push({
+      when: new Date(order.contract_terms.pay_deadline.t_s * 1000),
+      description: "pay deadline",
+      type: "deadline",
+    });
+  }
+  if (order.contract_terms.refund_deadline.t_s !== "never") {
+    events.push({
+      when: new Date(order.contract_terms.refund_deadline.t_s * 1000),
+      description: "refund deadline",
+      type: "deadline",
+    });
+  }
+  if (order.contract_terms.wire_transfer_deadline.t_s !== "never") {
+    events.push({
+      when: new Date(order.contract_terms.wire_transfer_deadline.t_s * 1000),
+      description: "wire deadline",
+      type: "deadline",
+    });
+  }
+  if (
+    order.contract_terms.delivery_date &&
+    order.contract_terms.delivery_date.t_s !== "never"
+  ) {
+    events.push({
+      when: new Date(order.contract_terms.delivery_date?.t_s * 1000),
+      description: "delivery",
+      type: "delivery",
+    });
+  }
+
+  const [value, valueHandler] = useState<Partial<Claimed>>(order);
+  const i18n = useTranslator();
+
+  return (
+    <div>
+      <section class="section">
+        <div class="columns">
+          <div class="column" />
+          <div class="column is-10">
+            <section class="hero is-hero-bar">
+              <div class="hero-body">
+                <div class="level">
+                  <div class="level-left">
+                    <div class="level-item">
+                      <Translate>Order</Translate> #{id}
+                      <div class="tag is-info ml-4">
+                        <Translate>claimed</Translate>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+                <div class="level">
+                  <div class="level-left">
+                    <div class="level-item">
+                      <h1 class="title">{order.contract_terms.amount}</h1>
+                    </div>
+                  </div>
+                </div>
+
+                <div class="level">
+                  <div class="level-left" style={{ maxWidth: "100%" }}>
+                    <div class="level-item" style={{ maxWidth: "100%" }}>
+                      <div
+                        class="content"
+                        style={{
+                          whiteSpace: "nowrap",
+                          overflow: "hidden",
+                          textOverflow: "ellipsis",
+                        }}
+                      >
+                        <p>
+                          <b>
+                            <Translate>claimed at</Translate>:
+                          </b>{" "}
+                          {format(
+                            new Date(order.contract_terms.timestamp.t_s * 
1000),
+                            "yyyy-MM-dd HH:mm:ss"
+                          )}
+                        </p>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </section>
+
+            <section class="section">
+              <div class="columns">
+                <div class="column is-4">
+                  <div class="title">
+                    <Translate>Timeline</Translate>
+                  </div>
+                  <Timeline events={events} />
+                </div>
+                <div class="column is-8">
+                  <div class="title">
+                    <Translate>Payment details</Translate>
+                  </div>
+                  <FormProvider<Claimed>
+                    object={value}
+                    valueHandler={valueHandler}
+                  >
+                    <Input
+                      name="contract_terms.summary"
+                      readonly
+                      inputType="multiline"
+                      label={i18n`Summary`}
+                    />
+                    <InputCurrency
+                      name="contract_terms.amount"
+                      readonly
+                      label={i18n`Amount`}
+                    />
+                    <Input<Claimed>
+                      name="order_status"
+                      readonly
+                      label={i18n`Order status`}
+                    />
+                  </FormProvider>
+                </div>
+              </div>
+            </section>
+
+            {order.contract_terms.products.length ? (
+              <Fragment>
+                <div class="title">
+                  <Translate>Product list</Translate>
+                </div>
+                <ProductList list={order.contract_terms.products} />
+              </Fragment>
+            ) : undefined}
+
+            {value.contract_terms && (
+              <ContractTerms value={value.contract_terms} />
+            )}
+          </div>
+          <div class="column" />
+        </div>
+      </section>
+    </div>
+  );
+}
+function PaidPage({
+  id,
+  order,
+  onRefund,
+}: {
+  id: string;
+  order: MerchantBackend.Orders.CheckPaymentPaidResponse;
+  onRefund: (id: string) => void;
+}) {
+  const events: Event[] = [];
+  if (order.contract_terms.timestamp.t_s !== "never") {
+    events.push({
+      when: new Date(order.contract_terms.timestamp.t_s * 1000),
+      description: "order created",
+      type: "start",
+    });
+  }
+  if (order.contract_terms.pay_deadline.t_s !== "never") {
+    events.push({
+      when: new Date(order.contract_terms.pay_deadline.t_s * 1000),
+      description: "pay deadline",
+      type: "deadline",
+    });
+  }
+  if (order.contract_terms.refund_deadline.t_s !== "never") {
+    events.push({
+      when: new Date(order.contract_terms.refund_deadline.t_s * 1000),
+      description: "refund deadline",
+      type: "deadline",
+    });
+  }
+  if (order.contract_terms.wire_transfer_deadline.t_s !== "never") {
+    events.push({
+      when: new Date(order.contract_terms.wire_transfer_deadline.t_s * 1000),
+      description: "wire deadline",
+      type: "deadline",
+    });
+  }
+  if (
+    order.contract_terms.delivery_date &&
+    order.contract_terms.delivery_date.t_s !== "never"
+  ) {
+    if (order.contract_terms.delivery_date)
+      events.push({
+        when: new Date(order.contract_terms.delivery_date?.t_s * 1000),
+        description: "delivery",
+        type: "delivery",
+      });
+  }
+  order.refund_details.reduce(mergeRefunds, []).forEach((e) => {
+    if (e.timestamp.t_s !== "never") {
+      events.push({
+        when: new Date(e.timestamp.t_s * 1000),
+        description: `refund: ${e.amount}: ${e.reason}`,
+        type: e.pending ? "refund" : "refund-taken",
+      });
+    }
+  });
+  if (order.wire_details && order.wire_details.length) {
+    if (order.wire_details.length > 1) {
+      let last: MerchantBackend.Orders.TransactionWireTransfer | null = null;
+      let first: MerchantBackend.Orders.TransactionWireTransfer | null = null;
+      let total: AmountJson | null = null;
+
+      order.wire_details.forEach((w) => {
+        if (last === null || last.execution_time.t_s < w.execution_time.t_s) {
+          last = w;
+        }
+        if (first === null || first.execution_time.t_s > w.execution_time.t_s) 
{
+          first = w;
+        }
+        total =
+          total === null
+            ? Amounts.parseOrThrow(w.amount)
+            : Amounts.add(total, Amounts.parseOrThrow(w.amount)).amount;
+      });
+      const last_time = last!.execution_time.t_s;
+      if (last_time !== "never") {
+        events.push({
+          when: new Date(last_time * 1000),
+          description: `wired ${Amounts.stringify(total!)}`,
+          type: "wired-range",
+        });
+      }
+      const first_time = first!.execution_time.t_s;
+      if (first_time !== "never") {
+        events.push({
+          when: new Date(first_time * 1000),
+          description: `wire transfer started...`,
+          type: "wired-range",
+        });
+      }
+    } else {
+      order.wire_details.forEach((e) => {
+        if (e.execution_time.t_s !== "never") {
+          events.push({
+            when: new Date(e.execution_time.t_s * 1000),
+            description: `wired ${e.amount}`,
+            type: "wired",
+          });
+        }
+      });
+    }
+  }
+
+  const [value, valueHandler] = useState<Partial<Paid>>(order);
+  const { url } = useBackendContext();
+  const refundHost = url.replace(/.*:\/\//, ""); // remove protocol part
+  const proto = url.startsWith("http://";) ? "taler+http" : "taler";
+  const refundurl = 
`${proto}://refund/${refundHost}/${order.contract_terms.order_id}/`;
+  const refundable =
+    new Date().getTime() < order.contract_terms.refund_deadline.t_s * 1000;
+  const i18n = useTranslator();
+
+  const amount = Amounts.parseOrThrow(order.contract_terms.amount);
+  const refund_taken = order.refund_details.reduce((prev, cur) => {
+    if (cur.pending) return prev;
+    return Amounts.add(prev, Amounts.parseOrThrow(cur.amount)).amount;
+  }, Amounts.getZero(amount.currency));
+  value.refund_taken = Amounts.stringify(refund_taken);
+
+  return (
+    <div>
+      <section class="section">
+        <div class="columns">
+          <div class="column" />
+          <div class="column is-10">
+            <section class="hero is-hero-bar">
+              <div class="hero-body">
+                <div class="level">
+                  <div class="level-left">
+                    <div class="level-item">
+                      <Translate>Order</Translate> #{id}
+                      <div class="tag is-success ml-4">
+                        <Translate>paid</Translate>
+                      </div>
+                      {order.wired ? (
+                        <div class="tag is-success ml-4">
+                          <Translate>wired</Translate>
+                        </div>
+                      ) : null}
+                      {order.refunded ? (
+                        <div class="tag is-danger ml-4">
+                          <Translate>refunded</Translate>
+                        </div>
+                      ) : null}
+                    </div>
+                  </div>
+                </div>
+                <div class="level">
+                  <div class="level-left">
+                    <div class="level-item">
+                      <h1 class="title">{order.contract_terms.amount}</h1>
+                    </div>
+                  </div>
+                  <div class="level-right">
+                    <div class="level-item">
+                      <h1 class="title">
+                        <div class="buttons">
+                          <span
+                            class="has-tooltip-left"
+                            data-tooltip={
+                              refundable
+                                ? i18n`refund order`
+                                : i18n`not refundable`
+                            }
+                          >
+                            <button
+                              class="button is-danger"
+                              disabled={!refundable}
+                              onClick={() => onRefund(id)}
+                            >
+                              <Translate>refund</Translate>
+                            </button>
+                          </span>
+                        </div>
+                      </h1>
+                    </div>
+                  </div>
+                </div>
+
+                <div class="level">
+                  <div class="level-left" style={{ maxWidth: "100%" }}>
+                    <div class="level-item" style={{ maxWidth: "100%" }}>
+                      <div
+                        class="content"
+                        style={{
+                          whiteSpace: "nowrap",
+                          overflow: "hidden",
+                          textOverflow: "ellipsis",
+                          // maxWidth: '100%',
+                        }}
+                      >
+                        <p>
+                          <a
+                            href={order.contract_terms.fulfillment_url}
+                            rel="nofollow"
+                            target="new"
+                          >
+                            {order.contract_terms.fulfillment_url}
+                          </a>
+                        </p>
+                        <p>
+                          {format(
+                            new Date(order.contract_terms.timestamp.t_s * 
1000),
+                            "yyyy/MM/dd HH:mm:ss"
+                          )}
+                        </p>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </section>
+
+            <section class="section">
+              <div class="columns">
+                <div class="column is-4">
+                  <div class="title">
+                    <Translate>Timeline</Translate>
+                  </div>
+                  <Timeline events={events} />
+                </div>
+                <div class="column is-8">
+                  <div class="title">
+                    <Translate>Payment details</Translate>
+                  </div>
+                  <FormProvider<Paid>
+                    object={value}
+                    valueHandler={valueHandler}
+                  >
+                    {/* <InputCurrency<Paid> name="deposit_total" readonly 
label={i18n`Deposit total`} /> */}
+                    {order.refunded && (
+                      <InputCurrency<Paid>
+                        name="refund_amount"
+                        readonly
+                        label={i18n`Refunded amount`}
+                      />
+                    )}
+                    {order.refunded && (
+                      <InputCurrency<Paid>
+                        name="refund_taken"
+                        readonly
+                        label={i18n`Refund taken`}
+                      />
+                    )}
+                    <Input<Paid>
+                      name="order_status"
+                      readonly
+                      label={i18n`Order status`}
+                    />
+                    <TextField<Paid>
+                      name="order_status_url"
+                      label={i18n`Status URL`}
+                    >
+                      <a
+                        target="_blank"
+                        rel="noreferrer"
+                        href={order.order_status_url}
+                      >
+                        {order.order_status_url}
+                      </a>
+                    </TextField>
+                    {order.refunded && (
+                      <TextField<Paid>
+                        name="order_status_url"
+                        label={i18n`Refund URI`}
+                      >
+                        <a target="_blank" rel="noreferrer" href={refundurl}>
+                          {refundurl}
+                        </a>
+                      </TextField>
+                    )}
+                  </FormProvider>
+                </div>
+              </div>
+            </section>
+
+            {order.contract_terms.products.length ? (
+              <Fragment>
+                <div class="title">
+                  <Translate>Product list</Translate>
+                </div>
+                <ProductList list={order.contract_terms.products} />
+              </Fragment>
+            ) : undefined}
+
+            {value.contract_terms && (
+              <ContractTerms value={value.contract_terms} />
+            )}
+          </div>
+          <div class="column" />
+        </div>
+      </section>
+    </div>
+  );
+}
+
+function UnpaidPage({
+  id,
+  order,
+}: {
+  id: string;
+  order: MerchantBackend.Orders.CheckPaymentUnpaidResponse;
+}) {
+  const [value, valueHandler] = useState<Partial<Unpaid>>(order);
+  const i18n = useTranslator();
+  return (
+    <div>
+      <section class="hero is-hero-bar">
+        <div class="hero-body">
+          <div class="level">
+            <div class="level-left">
+              <div class="level-item">
+                <h1 class="title">
+                  <Translate>Order</Translate> #{id}
+                </h1>
+              </div>
+              <div class="tag is-dark">
+                <Translate>unpaid</Translate>
+              </div>
+            </div>
+          </div>
+
+          <div class="level">
+            <div class="level-left" style={{ maxWidth: "100%" }}>
+              <div class="level-item" style={{ maxWidth: "100%" }}>
+                <div
+                  class="content"
+                  style={{
+                    whiteSpace: "nowrap",
+                    overflow: "hidden",
+                    textOverflow: "ellipsis",
+                  }}
+                >
+                  <p>
+                    <b>
+                      <Translate>pay at</Translate>:
+                    </b>{" "}
+                    <a
+                      href={order.order_status_url}
+                      rel="nofollow"
+                      target="new"
+                    >
+                      {order.order_status_url}
+                    </a>
+                  </p>
+                  <p>
+                    <b>
+                      <Translate>created at</Translate>:
+                    </b>{" "}
+                    {order.creation_time.t_s === "never"
+                      ? "never"
+                      : format(
+                          new Date(order.creation_time.t_s * 1000),
+                          "yyyy-MM-dd HH:mm:ss"
+                        )}
+                  </p>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </section>
+
+      <section class="section is-main-section">
+        <div class="columns">
+          <div class="column" />
+          <div class="column is-four-fifths">
+            <FormProvider<Unpaid> object={value} valueHandler={valueHandler}>
+              <Input<Unpaid>
+                readonly
+                name="summary"
+                label={i18n`Summary`}
+                tooltip={i18n`human-readable description of the whole 
purchase`}
+              />
+              <InputCurrency<Unpaid>
+                readonly
+                name="total_amount"
+                label={i18n`Amount`}
+                tooltip={i18n`total price for the transaction`}
+              />
+              <Input<Unpaid>
+                name="order_status"
+                readonly
+                label={i18n`Order status`}
+              />
+              <Input<Unpaid>
+                name="order_status_url"
+                readonly
+                label={i18n`Order status URL`}
+              />
+              <TextField<Unpaid> name="taler_pay_uri" label={i18n`Payment 
URI`}>
+                <a target="_blank" rel="noreferrer" href={value.taler_pay_uri}>
+                  {value.taler_pay_uri}
+                </a>
+              </TextField>
+            </FormProvider>
+          </div>
+          <div class="column" />
+        </div>
+      </section>
+    </div>
+  );
+}
+
+export function DetailPage({ id, selected, onRefund, onBack }: Props): VNode {
+  const [showRefund, setShowRefund] = useState<string | undefined>(undefined);
+
+  const DetailByStatus = function () {
+    switch (selected.order_status) {
+      case "claimed":
+        return <ClaimedPage id={id} order={selected} />;
+      case "paid":
+        return <PaidPage id={id} order={selected} onRefund={setShowRefund} />;
+      case "unpaid":
+        return <UnpaidPage id={id} order={selected} />;
+      default:
+        return (
+          <div>
+            <Translate>
+              Unknown order status. This is an error, please contact the
+              administrator.
+            </Translate>
+          </div>
+        );
+    }
+  };
+
+  return (
+    <Fragment>
+      {DetailByStatus()}
+      {showRefund && (
+        <RefundModal
+          order={selected}
+          onCancel={() => setShowRefund(undefined)}
+          onConfirm={(value) => {
+            onRefund(showRefund, value);
+            setShowRefund(undefined);
+          }}
+        />
+      )}
+      <div class="columns">
+        <div class="column" />
+        <div class="column is-four-fifths">
+          <div class="buttons is-right mt-5">
+            <button class="button" onClick={onBack}>
+              <Translate>Back</Translate>
+            </button>
+          </div>
+        </div>
+        <div class="column" />
+      </div>
+    </Fragment>
+  );
+}
+
+async function copyToClipboard(text: string) {
+  return navigator.clipboard.writeText(text);
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/details/Timeline.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/details/Timeline.tsx
new file mode 100644
index 000000000..bea65607a
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/details/Timeline.tsx
@@ -0,0 +1,128 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+import { format } from "date-fns";
+import { h } from "preact";
+import { useEffect, useState } from "preact/hooks";
+
+interface Props {
+  events: Event[];
+}
+
+export function Timeline({ events: e }: Props) {
+  const events = [...e];
+  events.push({
+    when: new Date(),
+    description: "now",
+    type: "now",
+  });
+
+  events.sort((a, b) => a.when.getTime() - b.when.getTime());
+
+  const [state, setState] = useState(events);
+  useEffect(() => {
+    const handle = setTimeout(() => {
+      const eventsWithoutNow = state.filter((e) => e.type !== "now");
+      eventsWithoutNow.push({
+        when: new Date(),
+        description: "now",
+        type: "now",
+      });
+      setState(eventsWithoutNow);
+    }, 1000);
+    return () => {
+      clearTimeout(handle);
+    };
+  });
+  return (
+    <div class="timeline">
+      {events.map((e, i) => {
+        return (
+          <div key={i} class="timeline-item">
+            {(() => {
+              switch (e.type) {
+                case "deadline":
+                  return (
+                    <div class="timeline-marker is-icon ">
+                      <i class="mdi mdi-flag" />
+                    </div>
+                  );
+                case "delivery":
+                  return (
+                    <div class="timeline-marker is-icon ">
+                      <i class="mdi mdi-delivery" />
+                    </div>
+                  );
+                case "start":
+                  return (
+                    <div class="timeline-marker is-icon is-success">
+                      <i class="mdi mdi-flag " />
+                    </div>
+                  );
+                case "wired":
+                  return (
+                    <div class="timeline-marker is-icon is-success">
+                      <i class="mdi mdi-cash" />
+                    </div>
+                  );
+                case "wired-range":
+                  return (
+                    <div class="timeline-marker is-icon is-success">
+                      <i class="mdi mdi-cash" />
+                    </div>
+                  );
+                case "refund":
+                  return (
+                    <div class="timeline-marker is-icon is-danger">
+                      <i class="mdi mdi-cash" />
+                    </div>
+                  );
+                case "refund-taken":
+                  return (
+                    <div class="timeline-marker is-icon is-success">
+                      <i class="mdi mdi-cash" />
+                    </div>
+                  );
+                case "now":
+                  return (
+                    <div class="timeline-marker is-icon is-info">
+                      <i class="mdi mdi-clock" />
+                    </div>
+                  );
+              }
+            })()}
+            <div class="timeline-content">
+              <p class="heading">{format(e.when, "yyyy/MM/dd HH:mm:ss")}</p>
+              <p>{e.description}</p>
+            </div>
+          </div>
+        );
+      })}
+    </div>
+  );
+}
+export interface Event {
+  when: Date;
+  description: string;
+  type:
+    | "start"
+    | "refund"
+    | "refund-taken"
+    | "wired"
+    | "wired-range"
+    | "deadline"
+    | "delivery"
+    | "now";
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/details/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/details/index.tsx
new file mode 100644
index 000000000..cd4e163eb
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/details/index.tsx
@@ -0,0 +1,67 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+import { Fragment, h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { Loading } from "../../../../components/exception/loading";
+import { NotificationCard } from "../../../../components/menu";
+import { HttpError } from "../../../../hooks/backend";
+import { useOrderDetails, useOrderAPI } from "../../../../hooks/order";
+import { useTranslator } from "../../../../i18n";
+import { Notification } from "../../../../utils/types";
+import { DetailPage } from "./DetailPage";
+
+export interface Props {
+  oid: string;
+
+  onBack: () => void;
+  onUnauthorized: () => VNode;
+  onNotFound: () => VNode;
+  onLoadError: (error: HttpError) => VNode;
+}
+
+export default function Update({ oid, onBack, onLoadError, onNotFound, 
onUnauthorized }: Props): VNode {
+  const { refundOrder } = useOrderAPI();
+  const result = useOrderDetails(oid)
+  const [notif, setNotif] = useState<Notification | undefined>(undefined)
+
+  const i18n = useTranslator()
+
+  if (result.clientError && result.isUnauthorized) return onUnauthorized()
+  if (result.clientError && result.isNotfound) return onNotFound()
+  if (result.loading) return <Loading />
+  if (!result.ok) return onLoadError(result)
+
+  return <Fragment>
+
+    <NotificationCard notification={notif} />
+
+    <DetailPage
+      onBack={onBack}
+      id={oid}
+      onRefund={(id, value) => refundOrder(id, value)
+        .then(() => setNotif({
+          message: i18n`refund created successfully`,
+          type: "SUCCESS"
+        })).catch((error) => setNotif({
+          message: i18n`could not create the refund`,
+          type: "ERROR",
+          description: error.message
+        }))
+      }
+      selected={result.data}
+    />
+  </Fragment>
+}
\ No newline at end of file
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/list/List.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/list/List.stories.tsx
new file mode 100644
index 000000000..1dbb3f20d
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/list/List.stories.tsx
@@ -0,0 +1,107 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { h, VNode, FunctionalComponent } from "preact";
+import { ListPage as TestedComponent } from "./ListPage";
+
+export default {
+  title: "Pages/Order/List",
+  component: TestedComponent,
+  argTypes: {
+    onShowAll: { action: "onShowAll" },
+    onShowPaid: { action: "onShowPaid" },
+    onShowRefunded: { action: "onShowRefunded" },
+    onShowNotWired: { action: "onShowNotWired" },
+    onCopyURL: { action: "onCopyURL" },
+    onSelectDate: { action: "onSelectDate" },
+    onLoadMoreBefore: { action: "onLoadMoreBefore" },
+    onLoadMoreAfter: { action: "onLoadMoreAfter" },
+    onSelectOrder: { action: "onSelectOrder" },
+    onRefundOrder: { action: "onRefundOrder" },
+    onSearchOrderById: { action: "onSearchOrderById" },
+    onCreate: { action: "onCreate" },
+  },
+};
+
+function createExample<Props>(
+  Component: FunctionalComponent<Props>,
+  props: Partial<Props>
+) {
+  const r = (args: any) => <Component {...args} />;
+  r.args = props;
+  return r;
+}
+
+export const Example = createExample(TestedComponent, {
+  orders: [
+    {
+      id: "123",
+      amount: "TESTKUDOS:10",
+      paid: false,
+      refundable: true,
+      row_id: 1,
+      summary: "summary",
+      timestamp: {
+        t_s: new Date().getTime() / 1000,
+      },
+      order_id: "123",
+    },
+    {
+      id: "234",
+      amount: "TESTKUDOS:12",
+      paid: true,
+      refundable: true,
+      row_id: 2,
+      summary:
+        "summary with long text, very very long text that someone want to add 
as a description of the order",
+      timestamp: {
+        t_s: new Date().getTime() / 1000,
+      },
+      order_id: "234",
+    },
+    {
+      id: "456",
+      amount: "TESTKUDOS:1",
+      paid: false,
+      refundable: false,
+      row_id: 3,
+      summary:
+        "summary with long text, very very long text that someone want to add 
as a description of the order",
+      timestamp: {
+        t_s: new Date().getTime() / 1000,
+      },
+      order_id: "456",
+    },
+    {
+      id: "234",
+      amount: "TESTKUDOS:12",
+      paid: false,
+      refundable: false,
+      row_id: 4,
+      summary:
+        "summary with long text, very very long text that someone want to add 
as a description of the order",
+      timestamp: {
+        t_s: new Date().getTime() / 1000,
+      },
+      order_id: "234",
+    },
+  ],
+});
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/list/ListPage.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/list/ListPage.tsx
new file mode 100644
index 000000000..032801bde
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/list/ListPage.tsx
@@ -0,0 +1,146 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { format } from 'date-fns';
+import { h, VNode } from 'preact';
+import { useState } from 'preact/hooks';
+import { DatePicker } from '../../../../components/picker/DatePicker';
+import { MerchantBackend, WithId } from '../../../../declaration';
+import { Translate, useTranslator } from '../../../../i18n';
+import { CardTable } from './Table';
+
+export interface ListPageProps {
+  errorOrderId: string | undefined,
+
+  onShowAll: () => void,
+  onShowPaid: () => void,
+  onShowRefunded: () => void,
+  onShowNotWired: () => void,
+  onCopyURL: (id: string) => void;
+  isAllActive: string,
+  isPaidActive: string,
+  isRefundedActive: string,
+  isNotWiredActive: string,
+
+  jumpToDate?: Date,
+  onSelectDate: (date?: Date) => void,
+
+  orders: (MerchantBackend.Orders.OrderHistoryEntry & WithId)[];
+  onLoadMoreBefore?: () => void;
+  hasMoreBefore?: boolean;
+  hasMoreAfter?: boolean;
+  onLoadMoreAfter?: () => void;
+
+  onSelectOrder: (o: MerchantBackend.Orders.OrderHistoryEntry & WithId) => 
void;
+  onRefundOrder: (o: MerchantBackend.Orders.OrderHistoryEntry & WithId) => 
void;
+  onSearchOrderById: (id: string) => void;
+  onCreate: () => void;
+}
+
+export function ListPage({ orders, errorOrderId, isAllActive, onSelectOrder, 
onRefundOrder, onSearchOrderById, jumpToDate, onCopyURL, onShowAll, onShowPaid, 
onShowRefunded, onShowNotWired, onSelectDate, isPaidActive, isRefundedActive, 
isNotWiredActive, onCreate }: ListPageProps): VNode {
+  const i18n = useTranslator();
+  const dateTooltip = i18n`select date to show nearby orders`;
+  const [pickDate, setPickDate] = useState(false);
+  const [orderId, setOrderId] = useState<string>('');
+
+  return <section class="section is-main-section">
+
+    <div class="level">
+      <div class="level-left">
+        <div class="level-item">
+          <div class="field has-addons">
+            <div class="control">
+              <input class={errorOrderId ? "input is-danger" : "input"} 
type="text" value={orderId} onChange={e => setOrderId(e.currentTarget.value)} 
placeholder={i18n`order id`} />
+              {errorOrderId && <p class="help is-danger">{errorOrderId}</p>}
+            </div>
+            <span class="has-tooltip-bottom" data-tooltip={i18n`jump to order 
with the given order ID`}>
+              <button class="button" onClick={(e) => 
onSearchOrderById(orderId)}>
+                <span class="icon"><i class="mdi mdi-arrow-right" /></span>
+              </button>
+            </span>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="columns">
+      <div class="column is-two-thirds">
+        <div class="tabs" style={{overflow:'inherit'}}>
+          <ul>
+            <li class={isAllActive}>
+              <div class="has-tooltip-right" data-tooltip={i18n`remove all 
filters`}>
+                <a onClick={onShowAll}><Translate>All</Translate></a>
+              </div>
+            </li>
+            <li class={isPaidActive}>
+              <div class="has-tooltip-right" data-tooltip={i18n`only show paid 
orders`}>
+                <a onClick={onShowPaid}><Translate>Paid</Translate></a>
+              </div>
+            </li>
+            <li class={isRefundedActive}>
+              <div class="has-tooltip-right" data-tooltip={i18n`only show 
orders with refunds`}>
+                <a onClick={onShowRefunded}><Translate>Refunded</Translate></a>
+              </div>
+            </li>
+            <li class={isNotWiredActive}>
+              <div class="has-tooltip-left" data-tooltip={i18n`only show 
orders where customers paid, but wire payments from payment provider are still 
pending`}>
+                <a onClick={onShowNotWired}><Translate>Not 
wired</Translate></a>
+              </div>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class="column ">
+        <div class="buttons is-right">
+          <div class="field has-addons">
+            {jumpToDate && <div class="control">
+              <a class="button" onClick={() => onSelectDate(undefined)}>
+                <span class="icon" data-tooltip={i18n`clear date filter`}><i 
class="mdi mdi-close" /></span>
+              </a>
+            </div>}
+            <div class="control">
+              <span class="has-tooltip-top" data-tooltip={dateTooltip}>
+                <input class="input" type="text" readonly value={!jumpToDate ? 
'' : format(jumpToDate, 'yyyy/MM/dd')} placeholder={i18n`date (YYYY/MM/DD)`} 
onClick={() => { setPickDate(true); }} />
+              </span>
+            </div>
+            <div class="control">
+              <span class="has-tooltip-left" data-tooltip={dateTooltip}>
+                <a class="button" onClick={() => { setPickDate(true); }}>
+                  <span class="icon"><i class="mdi mdi-calendar" /></span>
+                </a>
+              </span>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <DatePicker
+      opened={pickDate}
+      closeFunction={() => setPickDate(false)}
+      dateReceiver={onSelectDate} />
+
+    <CardTable orders={orders}
+      onCreate={onCreate}
+      onCopyURL={onCopyURL}
+      onSelect={onSelectOrder}
+      onRefund={onRefundOrder} />
+  </section>;
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/list/Table.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/list/Table.tsx
new file mode 100644
index 000000000..60d5fae59
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/paths/instance/orders/list/Table.tsx
@@ -0,0 +1,412 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { Amounts } from "@gnu-taler/taler-util";
+import { format } from "date-fns";
+import { h, VNode } from "preact";
+import { StateUpdater, useState } from "preact/hooks";
+import {
+  FormErrors,
+  FormProvider,
+} from "../../../../components/form/FormProvider";
+import { Input } from "../../../../components/form/Input";
+import { InputCurrency } from "../../../../components/form/InputCurrency";
+import { InputGroup } from "../../../../components/form/InputGroup";
+import { InputSelector } from "../../../../components/form/InputSelector";
+import { ConfirmModal } from "../../../../components/modal";
+import { useConfigContext } from "../../../../context/config";
+import { MerchantBackend, WithId } from "../../../../declaration";
+import { Translate, useTranslator } from "../../../../i18n";
+import { mergeRefunds } from "../../../../utils/amount";
+
+type Entity = MerchantBackend.Orders.OrderHistoryEntry & WithId;
+interface Props {
+  orders: Entity[];
+  onRefund: (value: Entity) => void;
+  onCopyURL: (id: string) => void;
+  onCreate: () => void;
+  onSelect: (order: Entity) => void;
+  onLoadMoreBefore?: () => void;
+  hasMoreBefore?: boolean;
+  hasMoreAfter?: boolean;
+  onLoadMoreAfter?: () => void;
+}
+
+export function CardTable({
+  orders,
+  onCreate,
+  onRefund,
+  onCopyURL,
+  onSelect,
+  onLoadMoreAfter,
+  onLoadMoreBefore,
+  hasMoreAfter,
+  hasMoreBefore,
+}: Props): VNode {
+  const [rowSelection, rowSelectionHandler] = useState<string[]>([]);
+
+  const i18n = useTranslator();
+
+  return (
+    <div class="card has-table">
+      <header class="card-header">
+        <p class="card-header-title">
+          <span class="icon">
+            <i class="mdi mdi-cash-register" />
+          </span>
+          <Translate>Orders</Translate>
+        </p>
+
+        <div class="card-header-icon" aria-label="more options" />
+
+        <div class="card-header-icon" aria-label="more options">
+          <span class="has-tooltip-left" data-tooltip={i18n`create order`}>
+            <button class="button is-info" type="button" onClick={onCreate}>
+              <span class="icon is-small">
+                <i class="mdi mdi-plus mdi-36px" />
+              </span>
+            </button>
+          </span>
+        </div>
+      </header>
+      <div class="card-content">
+        <div class="b-table has-pagination">
+          <div class="table-wrapper has-mobile-cards">
+            {orders.length > 0 ? (
+              <Table
+                instances={orders}
+                onSelect={onSelect}
+                onRefund={onRefund}
+                onCopyURL={(o) => onCopyURL(o.id)}
+                rowSelection={rowSelection}
+                rowSelectionHandler={rowSelectionHandler}
+                onLoadMoreAfter={onLoadMoreAfter}
+                onLoadMoreBefore={onLoadMoreBefore}
+                hasMoreAfter={hasMoreAfter}
+                hasMoreBefore={hasMoreBefore}
+              />
+            ) : (
+              <EmptyTable />
+            )}
+          </div>
+        </div>
+      </div>
+    </div>
+  );
+}
+interface TableProps {
+  rowSelection: string[];
+  instances: Entity[];
+  onRefund: (id: Entity) => void;
+  onCopyURL: (id: Entity) => void;
+  onSelect: (id: Entity) => void;
+  rowSelectionHandler: StateUpdater<string[]>;
+  onLoadMoreBefore?: () => void;
+  hasMoreBefore?: boolean;
+  hasMoreAfter?: boolean;
+  onLoadMoreAfter?: () => void;
+}
+
+function Table({
+  instances,
+  onSelect,
+  onRefund,
+  onCopyURL,
+  onLoadMoreAfter,
+  onLoadMoreBefore,
+  hasMoreAfter,
+  hasMoreBefore,
+}: TableProps): VNode {
+  return (
+    <div class="table-container">
+      {onLoadMoreBefore && (
+        <button
+          class="button is-fullwidth"
+          disabled={!hasMoreBefore}
+          onClick={onLoadMoreBefore}
+        >
+          <Translate>load newer orders</Translate>
+        </button>
+      )}
+      <table class="table is-striped is-hoverable is-fullwidth">
+        <thead>
+          <tr>
+            <th style={{ minWidth: 100 }}>
+              <Translate>Date</Translate>
+            </th>
+            <th style={{ minWidth: 100 }}>
+              <Translate>Amount</Translate>
+            </th>
+            <th style={{ minWidth: 400 }}>
+              <Translate>Summary</Translate>
+            </th>
+            <th style={{ minWidth: 50 }} />
+          </tr>
+        </thead>
+        <tbody>
+          {instances.map((i) => {
+            return (
+              <tr key={i.id}>
+                <td
+                  onClick={(): void => onSelect(i)}
+                  style={{ cursor: "pointer" }}
+                >
+                  {i.timestamp.t_s === "never"
+                    ? "never"
+                    : format(
+                        new Date(i.timestamp.t_s * 1000),
+                        "yyyy/MM/dd HH:mm:ss"
+                      )}
+                </td>
+                <td
+                  onClick={(): void => onSelect(i)}
+                  style={{ cursor: "pointer" }}
+                >
+                  {i.amount}
+                </td>
+                <td
+                  onClick={(): void => onSelect(i)}
+                  style={{ cursor: "pointer" }}
+                >
+                  {i.summary}
+                </td>
+                <td class="is-actions-cell right-sticky">
+                  <div class="buttons is-right">
+                    {i.refundable && (
+                      <button
+                        class="button is-small is-danger jb-modal"
+                        type="button"
+                        onClick={(): void => onRefund(i)}
+                      >
+                        <Translate>Refund</Translate>
+                      </button>
+                    )}
+                    {!i.paid && (
+                      <button
+                        class="button is-small is-info jb-modal"
+                        type="button"
+                        onClick={(): void => onCopyURL(i)}
+                      >
+                        <Translate>copy url</Translate>
+                      </button>
+                    )}
+                  </div>
+                </td>
+              </tr>
+            );
+          })}
+        </tbody>
+      </table>
+      {onLoadMoreAfter && (
+        <button
+          class="button is-fullwidth"
+          disabled={!hasMoreAfter}
+          onClick={onLoadMoreAfter}
+        >
+          <Translate>load older orders</Translate>
+        </button>
+      )}
+    </div>
+  );
+}
+
+function EmptyTable(): VNode {
+  return (
+    <div class="content has-text-grey has-text-centered">
+      <p>
+        <span class="icon is-large">
+          <i class="mdi mdi-emoticon-sad mdi-48px" />
+        </span>
+      </p>
+      <p>
+        <Translate>No orders have been found matching your query!</Translate>
+      </p>
+    </div>
+  );
+}
+
+interface RefundModalProps {
+  onCancel: () => void;
+  onConfirm: (value: MerchantBackend.Orders.RefundRequest) => void;
+  order: MerchantBackend.Orders.MerchantOrderStatusResponse;
+}
+
+export function RefundModal({
+  order,
+  onCancel,
+  onConfirm,
+}: RefundModalProps): VNode {
+  type State = { mainReason?: string; description?: string; refund?: string };
+  const [form, setValue] = useState<State>({});
+  const i18n = useTranslator();
+  // const [errors, setErrors] = useState<FormErrors<State>>({});
+
+  const refunds = (
+    order.order_status === "paid" ? order.refund_details : []
+  ).reduce(mergeRefunds, []);
+
+  const config = useConfigContext();
+  const totalRefunded = refunds
+    .map((r) => r.amount)
+    .reduce(
+      (p, c) => Amounts.add(p, Amounts.parseOrThrow(c)).amount,
+      Amounts.getZero(config.currency)
+    );
+  const orderPrice =
+    order.order_status === "paid"
+      ? Amounts.parseOrThrow(order.contract_terms.amount)
+      : undefined;
+  const totalRefundable = !orderPrice
+    ? Amounts.getZero(totalRefunded.currency)
+    : refunds.length
+    ? Amounts.sub(orderPrice, totalRefunded).amount
+    : orderPrice;
+
+  const isRefundable = Amounts.isNonZero(totalRefundable);
+  const duplicatedText = i18n`duplicated`;
+
+  const errors: FormErrors<State> = {
+    mainReason: !form.mainReason ? i18n`required` : undefined,
+    description:
+      !form.description && form.mainReason !== duplicatedText
+        ? i18n`required`
+        : undefined,
+    refund: !form.refund
+      ? i18n`required`
+      : !Amounts.parse(form.refund)
+      ? i18n`invalid format`
+      : Amounts.cmp(totalRefundable, Amounts.parse(form.refund)!) === -1
+      ? i18n`this value exceed the refundable amount`
+      : undefined,
+  };
+  const hasErrors = Object.keys(errors).some(
+    (k) => (errors as any)[k] !== undefined
+  );
+
+  const validateAndConfirm = () => {
+    try {
+      if (!form.refund) return;
+      onConfirm({
+        refund: Amounts.stringify(
+          Amounts.add(Amounts.parse(form.refund)!, totalRefunded).amount
+        ),
+        reason:
+          form.description === undefined
+            ? form.mainReason || ""
+            : `${form.mainReason}: ${form.description}`,
+      });
+    } catch (err) {
+      console.log(err);
+    }
+  };
+
+  //FIXME: parameters in the translation
+  return (
+    <ConfirmModal
+      description="refund"
+      danger
+      active
+      disabled={!isRefundable || hasErrors}
+      onCancel={onCancel}
+      onConfirm={validateAndConfirm}
+    >
+      {refunds.length > 0 && (
+        <div class="columns">
+          <div class="column is-12">
+            <InputGroup
+              name="asd"
+              label={`${Amounts.stringify(totalRefunded)} was already 
refunded`}
+            >
+              <table class="table is-fullwidth">
+                <thead>
+                  <tr>
+                    <th>
+                      <Translate>date</Translate>
+                    </th>
+                    <th>
+                      <Translate>amount</Translate>
+                    </th>
+                    <th>
+                      <Translate>reason</Translate>
+                    </th>
+                  </tr>
+                </thead>
+                <tbody>
+                  {refunds.map((r) => {
+                    return (
+                      <tr key={r.timestamp.t_s}>
+                        <td>
+                          {r.timestamp.t_s === "never"
+                            ? "never"
+                            : format(
+                                new Date(r.timestamp.t_s * 1000),
+                                "yyyy-MM-dd HH:mm:ss"
+                              )}
+                        </td>
+                        <td>{r.amount}</td>
+                        <td>{r.reason}</td>
+                      </tr>
+                    );
+                  })}
+                </tbody>
+              </table>
+            </InputGroup>
+          </div>
+        </div>
+      )}
+
+      {isRefundable && (
+        <FormProvider<State>
+          errors={errors}
+          object={form}
+          valueHandler={(d) => setValue(d as any)}
+        >
+          <InputCurrency<State>
+            name="refund"
+            label={i18n`Refund`}
+            tooltip={i18n`amount to be refunded`}
+          >
+            <Translate>Max refundable:</Translate>{" "}
+            {Amounts.stringify(totalRefundable)}
+          </InputCurrency>
+          <InputSelector
+            name="mainReason"
+            label={i18n`Reason`}
+            values={[
+              i18n`Choose one...`,
+              duplicatedText,
+              i18n`requested by the customer`,
+              i18n`other`,
+            ]}
+            tooltip={i18n`why this order is being refunded`}
+          />
+          {form.mainReason && form.mainReason !== duplicatedText ? (
+            <Input<State>
+              label={i18n`Description`}
+              name="description"
+              tooltip={i18n`more information to give context`}
+            />
+          ) : undefined}
+        </FormProvider>
+      )}
+    </ConfirmModal>
+  );
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/orders/list/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/orders/list/index.tsx
new file mode 100644
index 000000000..47e143fb7
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/paths/instance/orders/list/index.tsx
@@ -0,0 +1,171 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode, Fragment } from 'preact';
+import { useState } from 'preact/hooks';
+import { Loading } from '../../../../components/exception/loading';
+import { NotificationCard } from '../../../../components/menu';
+import { MerchantBackend, WithId } from '../../../../declaration';
+import { HttpError } from '../../../../hooks/backend';
+import { InstanceOrderFilter, useInstanceOrders, useOrderAPI, useOrderDetails 
} from '../../../../hooks/order';
+import { useTranslator } from '../../../../i18n';
+import { Notification } from '../../../../utils/types';
+import { RefundModal } from './Table';
+import { ListPage } from './ListPage';
+
+interface Props {
+  onUnauthorized: () => VNode;
+  onLoadError: (error: HttpError) => VNode;
+  onNotFound: () => VNode;
+  onSelect: (id: string) => void;
+  onCreate: () => void;
+}
+
+export default function ({ onUnauthorized, onLoadError, onCreate, onSelect, 
onNotFound }: Props): VNode {
+  const [filter, setFilter] = useState<InstanceOrderFilter>({})
+  const [orderToBeRefunded, setOrderToBeRefunded] = 
useState<MerchantBackend.Orders.OrderHistoryEntry | undefined>(undefined)
+
+  const setNewDate = (date?: Date) => setFilter(prev => ({ ...prev, date }))
+
+  const result = useInstanceOrders(filter, setNewDate)
+  const { refundOrder, getPaymentURL } = useOrderAPI()
+
+  const [notif, setNotif] = useState<Notification | undefined>(undefined)
+
+  if (result.clientError && result.isUnauthorized) return onUnauthorized()
+  if (result.clientError && result.isNotfound) return onNotFound()
+  if (result.loading) return <Loading />
+  if (!result.ok) return onLoadError(result)
+
+  const isPaidActive = filter.paid === 'yes' ? "is-active" : ''
+  const isRefundedActive = filter.refunded === 'yes' ? "is-active" : ''
+  const isNotWiredActive = filter.wired === 'no' ? "is-active" : ''
+  const isAllActive = filter.paid === undefined && filter.refunded === 
undefined && filter.wired === undefined ? 'is-active' : ''
+
+  const i18n = useTranslator()
+  const [errorOrderId, setErrorOrderId] = useState<string | 
undefined>(undefined)
+
+  async function testIfOrderExistAndSelect(orderId: string) {
+    if (!orderId) {
+      setErrorOrderId(i18n`Enter an order id`)
+      return;
+    }
+    try {
+      await getPaymentURL(orderId)
+      onSelect(orderId)
+      setErrorOrderId(undefined)
+    } catch {
+      setErrorOrderId(i18n`order not found`)
+    }
+  }
+
+  return <Fragment>
+    <NotificationCard notification={notif} />
+
+    <ListPage
+      orders={result.data.orders.map(o => ({ ...o, id: o.order_id }))}
+      onLoadMoreBefore={result.loadMorePrev} 
hasMoreBefore={!result.isReachingStart}
+      onLoadMoreAfter={result.loadMore} hasMoreAfter={!result.isReachingEnd}
+
+      onSelectOrder={(order) => onSelect(order.id)}
+      onRefundOrder={(value) => setOrderToBeRefunded(value)}
+
+      errorOrderId={errorOrderId}
+      isAllActive={isAllActive}
+      isNotWiredActive={isNotWiredActive}
+      isPaidActive={isPaidActive}
+      isRefundedActive={isRefundedActive}
+      jumpToDate={filter.date}
+      onCopyURL={(id) => getPaymentURL(id).then((resp) => 
copyToClipboard(resp.data))}
+
+      onCreate={onCreate}
+      onSearchOrderById={testIfOrderExistAndSelect}
+      onSelectDate={setNewDate}
+      onShowAll={() => setFilter({})}
+      onShowPaid={() => setFilter({ paid: 'yes' })}
+      onShowRefunded={() => setFilter({ refunded: 'yes' })}
+      onShowNotWired={() => setFilter({ wired: 'no' })}
+
+    />
+
+    {orderToBeRefunded && <RefundModalForTable
+      id={orderToBeRefunded.order_id}
+      onCancel={() => setOrderToBeRefunded(undefined)}
+      onConfirm={(value) => refundOrder(orderToBeRefunded.order_id, value)
+        .then(() => setNotif({
+          message: i18n`refund created successfully`,
+          type: "SUCCESS"
+        }))
+        .catch((error) => setNotif({
+          message: i18n`could not create the refund`,
+          type: "ERROR",
+          description: error.message
+        }))
+        .then(() => setOrderToBeRefunded(undefined))}
+      onLoadError={(error) => {
+        setNotif({
+          message: i18n`could not create the refund`,
+          type: "ERROR",
+          description: error.message
+        });
+        setOrderToBeRefunded(undefined);
+        return <div />;
+      }}
+      onUnauthorized={onUnauthorized}
+      onNotFound={() => {
+        setNotif({
+          message: i18n`could not get the order to refund`,
+          type: "ERROR",
+          // description: error.message
+        });
+        setOrderToBeRefunded(undefined);
+        return <div />;
+      }} />}
+  </Fragment>
+}
+
+interface RefundProps {
+  id: string;
+  onUnauthorized: () => VNode;
+  onLoadError: (error: HttpError) => VNode;
+  onNotFound: () => VNode;
+  onCancel: () => void;
+  onConfirm: (m: MerchantBackend.Orders.RefundRequest) => void;
+}
+
+function RefundModalForTable({ id, onUnauthorized, onLoadError, onNotFound, 
onConfirm, onCancel }: RefundProps) {
+  const result = useOrderDetails(id);
+
+  if (result.clientError && result.isUnauthorized) return onUnauthorized()
+  if (result.clientError && result.isNotfound) return onNotFound()
+  if (result.loading) return <Loading />
+  if (!result.ok) return onLoadError(result)
+
+  return <RefundModal
+    order={result.data}
+    onCancel={onCancel}
+    onConfirm={onConfirm}
+  />
+}
+
+async function copyToClipboard(text: string) {
+  return navigator.clipboard.writeText(text)
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/products/create/Create.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/products/create/Create.stories.tsx
new file mode 100644
index 000000000..1d9ea53f6
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/products/create/Create.stories.tsx
@@ -0,0 +1,42 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode, FunctionalComponent } from 'preact';
+import { CreatePage as TestedComponent } from './CreatePage';
+
+
+export default {
+  title: 'Pages/Product/Create',
+  component: TestedComponent,
+  argTypes: {
+    onCreate: { action: 'onCreate' },
+    onBack: { action: 'onBack' },
+  },
+};
+
+function createExample<Props>(Component: FunctionalComponent<Props>, props: 
Partial<Props>) {
+  const r = (args: any) => <Component {...args} />
+  r.args = props
+  return r
+}
+
+export const Example = createExample(TestedComponent, {
+});
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/products/create/CreatePage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/products/create/CreatePage.tsx
new file mode 100644
index 000000000..ed669f67f
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/products/create/CreatePage.tsx
@@ -0,0 +1,65 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode } from "preact";
+import { AsyncButton } from "../../../../components/exception/AsyncButton";
+import { ProductForm } from "../../../../components/product/ProductForm";
+import { MerchantBackend } from "../../../../declaration";
+import { useListener } from "../../../../hooks/listener";
+import { Translate, useTranslator } from "../../../../i18n";
+
+type Entity = MerchantBackend.Products.ProductAddDetail & { product_id: string}
+
+interface Props {
+  onCreate: (d: Entity) => Promise<void>;
+  onBack?: () => void;
+}
+
+
+export function CreatePage({ onCreate, onBack }: Props): VNode {
+
+  const [submitForm, addFormSubmitter] = useListener<Entity | 
undefined>((result) => {
+    if (result) return onCreate(result)
+    return Promise.reject()
+  })
+
+  const i18n = useTranslator()
+
+  return <div>
+    <section class="section is-main-section">
+      <div class="columns">
+        <div class="column" />
+        <div class="column is-four-fifths">
+          <ProductForm onSubscribe={addFormSubmitter} />
+
+          <div class="buttons is-right mt-5">
+            {onBack && <button class="button" onClick={onBack} 
><Translate>Cancel</Translate></button>}
+            <AsyncButton onClick={submitForm} data-tooltip={
+              !submitForm ? i18n`Need to complete marked fields` : 'confirm 
operation'
+            } 
disabled={!submitForm}><Translate>Confirm</Translate></AsyncButton>
+          </div>
+
+        </div>
+        <div class="column" />
+      </div>
+    </section>
+  </div>
+}
\ No newline at end of file
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/products/create/CreatedSuccessfully.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/products/create/CreatedSuccessfully.tsx
new file mode 100644
index 000000000..b56750405
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/products/create/CreatedSuccessfully.tsx
@@ -0,0 +1,67 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+import { h, VNode } from "preact";
+import { CreatedSuccessfully as Template } from 
"../../../../components/notifications/CreatedSuccessfully";
+import { Entity } from "./index";
+import emptyImage from "../../assets/empty.png";
+
+interface Props {
+  entity: Entity;
+  onConfirm: () => void;
+  onCreateAnother?: () => void;
+}
+
+export function CreatedSuccessfully({ entity, onConfirm, onCreateAnother }: 
Props): VNode {
+
+  return <Template onConfirm={onConfirm} onCreateAnother={onCreateAnother}>
+    <div class="field is-horizontal">
+      <div class="field-label is-normal">
+        <label class="label">Image</label>
+      </div>
+      <div class="field-body is-flex-grow-3">
+        <div class="field">
+          <p class="control">
+            <img src={entity.image} style={{ width: 200, height: 200 }} />
+          </p>
+        </div>
+      </div>
+    </div>
+    <div class="field is-horizontal">
+      <div class="field-label is-normal">
+        <label class="label">Description</label>
+      </div>
+      <div class="field-body is-flex-grow-3">
+        <div class="field">
+          <p class="control">
+            <textarea class="input" readonly value={entity.description} />
+          </p>
+        </div>
+      </div>
+    </div>
+    <div class="field is-horizontal">
+      <div class="field-label is-normal">
+        <label class="label">Price</label>
+      </div>
+      <div class="field-body is-flex-grow-3">
+        <div class="field">
+          <p class="control">
+            <input class="input" readonly value={entity.price} />
+          </p>
+        </div>
+      </div>
+    </div>
+  </Template>;
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/products/create/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/products/create/index.tsx
new file mode 100644
index 000000000..46454582a
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/products/create/index.tsx
@@ -0,0 +1,55 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { Fragment, h, VNode } from 'preact';
+import { useState } from 'preact/hooks';
+import { NotificationCard } from '../../../../components/menu';
+import { MerchantBackend } from '../../../../declaration';
+import { useProductAPI } from '../../../../hooks/product';
+import { useTranslator } from '../../../../i18n';
+import { Notification } from '../../../../utils/types';
+import { CreatePage } from './CreatePage';
+
+export type Entity = MerchantBackend.Products.ProductAddDetail
+interface Props {
+  onBack?: () => void;
+  onConfirm: () => void;
+}
+export default function CreateProduct({ onConfirm, onBack }: Props): VNode {
+  const { createProduct } = useProductAPI()
+  const [notif, setNotif] = useState<Notification | undefined>(undefined)
+  const i18n = useTranslator()
+  
+  return <Fragment>
+    <NotificationCard notification={notif} />
+    <CreatePage
+      onBack={onBack}
+      onCreate={(request: MerchantBackend.Products.ProductAddDetail) => {
+        return createProduct(request).then(() => onConfirm()).catch((error) => 
{
+          setNotif({
+            message: i18n`could not create product`,
+            type: "ERROR",
+            description: error.message
+          })
+        })
+      }} />
+  </Fragment>
+}
\ No newline at end of file
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/products/list/List.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/products/list/List.stories.tsx
new file mode 100644
index 000000000..beae83b15
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/products/list/List.stories.tsx
@@ -0,0 +1,58 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode, FunctionalComponent } from 'preact';
+import { CardTable as TestedComponent } from './Table';
+
+
+export default {
+  title: 'Pages/Product/List',
+  component: TestedComponent,
+  argTypes: {
+    onCreate: { action: 'onCreate' },
+    onSelect: { action: 'onSelect' },
+    onDelete: { action: 'onDelete' },
+    onUpdate: { action: 'onUpdate' },
+  },
+};
+
+function createExample<Props>(Component: FunctionalComponent<Props>, props: 
Partial<Props>) {
+  const r = (args: any) => <Component {...args} />
+  r.args = props
+  return r
+}
+
+
+export const Example = createExample(TestedComponent, {
+  instances: [{
+    id: 'orderid',
+    description: 'description1',
+    description_i18n: {} as any,
+    image: '',
+    price: 'TESTKUDOS:10',
+    taxes: [],
+    total_lost: 10,
+    total_sold: 5,
+    total_stock: 15,
+    unit: 'bar',
+    address: {}
+  }]
+});
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/products/list/Table.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/products/list/Table.tsx
new file mode 100644
index 000000000..9c85d976e
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/paths/instance/products/list/Table.tsx
@@ -0,0 +1,479 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { format } from "date-fns";
+import { ComponentChildren, Fragment, h, VNode } from "preact";
+import { StateUpdater, useState } from "preact/hooks";
+import {
+  FormProvider,
+  FormErrors,
+} from "../../../../components/form/FormProvider";
+import { InputCurrency } from "../../../../components/form/InputCurrency";
+import { InputNumber } from "../../../../components/form/InputNumber";
+import { MerchantBackend, WithId } from "../../../../declaration";
+import emptyImage from "../../../../assets/empty.png";
+import { Translate, useTranslator } from "../../../../i18n";
+import { Amounts } from "@gnu-taler/taler-util";
+
+type Entity = MerchantBackend.Products.ProductDetail & WithId;
+
+interface Props {
+  instances: Entity[];
+  onDelete: (id: Entity) => void;
+  onSelect: (product: Entity) => void;
+  onUpdate: (
+    id: string,
+    data: MerchantBackend.Products.ProductPatchDetail
+  ) => Promise<void>;
+  onCreate: () => void;
+  selected?: boolean;
+}
+
+export function CardTable({
+  instances,
+  onCreate,
+  onSelect,
+  onUpdate,
+  onDelete,
+}: Props): VNode {
+  const [rowSelection, rowSelectionHandler] = useState<string | undefined>(
+    undefined
+  );
+  const i18n = useTranslator();
+  return (
+    <div class="card has-table">
+      <header class="card-header">
+        <p class="card-header-title">
+          <span class="icon">
+            <i class="mdi mdi-shopping" />
+          </span>
+          <Translate>Products</Translate>
+        </p>
+        <div class="card-header-icon" aria-label="more options">
+          <span
+            class="has-tooltip-left"
+            data-tooltip={i18n`add product to inventory`}
+          >
+            <button class="button is-info" type="button" onClick={onCreate}>
+              <span class="icon is-small">
+                <i class="mdi mdi-plus mdi-36px" />
+              </span>
+            </button>
+          </span>
+        </div>
+      </header>
+      <div class="card-content">
+        <div class="b-table has-pagination">
+          <div class="table-wrapper has-mobile-cards">
+            {instances.length > 0 ? (
+              <Table
+                instances={instances}
+                onSelect={onSelect}
+                onDelete={onDelete}
+                onUpdate={onUpdate}
+                rowSelection={rowSelection}
+                rowSelectionHandler={rowSelectionHandler}
+              />
+            ) : (
+              <EmptyTable />
+            )}
+          </div>
+        </div>
+      </div>
+    </div>
+  );
+}
+interface TableProps {
+  rowSelection: string | undefined;
+  instances: Entity[];
+  onSelect: (id: Entity) => void;
+  onUpdate: (
+    id: string,
+    data: MerchantBackend.Products.ProductPatchDetail
+  ) => Promise<void>;
+  onDelete: (id: Entity) => void;
+  rowSelectionHandler: StateUpdater<string | undefined>;
+}
+
+function Table({
+  rowSelection,
+  rowSelectionHandler,
+  instances,
+  onSelect,
+  onUpdate,
+  onDelete,
+}: TableProps): VNode {
+  const i18n = useTranslator();
+  return (
+    <div class="table-container">
+      <table class="table is-fullwidth is-striped is-hoverable is-fullwidth">
+        <thead>
+          <tr>
+            <th>
+              <Translate>Image</Translate>
+            </th>
+            <th>
+              <Translate>Description</Translate>
+            </th>
+            <th>
+              <Translate>Sell</Translate>
+            </th>
+            <th>
+              <Translate>Taxes</Translate>
+            </th>
+            <th>
+              <Translate>Profit</Translate>
+            </th>
+            <th>
+              <Translate>Stock</Translate>
+            </th>
+            <th>
+              <Translate>Sold</Translate>
+            </th>
+            <th />
+          </tr>
+        </thead>
+        <tbody>
+          {instances.map((i) => {
+            const restStockInfo = !i.next_restock
+              ? ""
+              : i.next_restock.t_s === "never"
+              ? "never"
+              : `restock at ${format(
+                  new Date(i.next_restock.t_s * 1000),
+                  "yyyy/MM/dd"
+                )}`;
+            let stockInfo: ComponentChildren = "";
+            if (i.total_stock < 0) {
+              stockInfo = "infinite";
+            } else {
+              const totalStock = i.total_stock - i.total_lost - i.total_sold;
+              stockInfo = (
+                <label title={restStockInfo}>
+                  {totalStock} {i.unit}
+                </label>
+              );
+            }
+
+            const isFree = Amounts.isZero(Amounts.parseOrThrow(i.price));
+
+            return (
+              <Fragment key={i.id}>
+                <tr key="info">
+                  <td
+                    onClick={() =>
+                      rowSelection !== i.id && rowSelectionHandler(i.id)
+                    }
+                    style={{ cursor: "pointer" }}
+                  >
+                    <img
+                      src={i.image ? i.image : emptyImage}
+                      style={{
+                        border: "solid black 1px",
+                        width: 100,
+                        height: 100,
+                      }}
+                    />
+                  </td>
+                  <td
+                    onClick={() =>
+                      rowSelection !== i.id && rowSelectionHandler(i.id)
+                    }
+                    style={{ cursor: "pointer" }}
+                  >
+                    {i.description}
+                  </td>
+                  <td
+                    onClick={() =>
+                      rowSelection !== i.id && rowSelectionHandler(i.id)
+                    }
+                    style={{ cursor: "pointer" }}
+                  >
+                    {isFree ? i18n`free` : `${i.price} / ${i.unit}`}
+                  </td>
+                  <td
+                    onClick={() =>
+                      rowSelection !== i.id && rowSelectionHandler(i.id)
+                    }
+                    style={{ cursor: "pointer" }}
+                  >
+                    {sum(i.taxes)}
+                  </td>
+                  <td
+                    onClick={() =>
+                      rowSelection !== i.id && rowSelectionHandler(i.id)
+                    }
+                    style={{ cursor: "pointer" }}
+                  >
+                    {difference(i.price, sum(i.taxes))}
+                  </td>
+                  <td
+                    onClick={() =>
+                      rowSelection !== i.id && rowSelectionHandler(i.id)
+                    }
+                    style={{ cursor: "pointer" }}
+                  >
+                    {stockInfo}
+                  </td>
+                  <td
+                    onClick={() =>
+                      rowSelection !== i.id && rowSelectionHandler(i.id)
+                    }
+                    style={{ cursor: "pointer" }}
+                  >
+                    {i.total_sold} {i.unit}
+                  </td>
+                  <td class="is-actions-cell right-sticky">
+                    <div class="buttons is-right">
+                      <span
+                        class="has-tooltip-bottom"
+                        data-tooltip={i18n`go to product update page`}
+                      >
+                        <button
+                          class="button is-small is-success "
+                          type="button"
+                          onClick={(): void => onSelect(i)}
+                        >
+                          <Translate>Update</Translate>
+                        </button>
+                      </span>
+                      <span
+                        class="has-tooltip-left"
+                        data-tooltip={i18n`remove this product from the 
database`}
+                      >
+                        <button
+                          class="button is-small is-danger"
+                          type="button"
+                          onClick={(): void => onDelete(i)}
+                        >
+                          <Translate>Delete</Translate>
+                        </button>
+                      </span>
+                    </div>
+                  </td>
+                </tr>
+                {rowSelection === i.id && (
+                  <tr key="form">
+                    <td colSpan={10}>
+                      <FastProductUpdateForm
+                        product={i}
+                        onUpdate={(prod) =>
+                          onUpdate(i.id, prod).then((r) =>
+                            rowSelectionHandler(undefined)
+                          )
+                        }
+                        onCancel={() => rowSelectionHandler(undefined)}
+                      />
+                    </td>
+                  </tr>
+                )}
+              </Fragment>
+            );
+          })}
+        </tbody>
+      </table>
+    </div>
+  );
+}
+
+interface FastProductUpdateFormProps {
+  product: Entity;
+  onUpdate: (
+    data: MerchantBackend.Products.ProductPatchDetail
+  ) => Promise<void>;
+  onCancel: () => void;
+}
+interface FastProductUpdate {
+  incoming: number;
+  lost: number;
+  price: string;
+}
+interface UpdatePrice {
+  price: string;
+}
+
+function FastProductWithInfiniteStockUpdateForm({
+  product,
+  onUpdate,
+  onCancel,
+}: FastProductUpdateFormProps) {
+  const [value, valueHandler] = useState<UpdatePrice>({ price: product.price 
});
+  const i18n = useTranslator();
+
+  return (
+    <Fragment>
+      <FormProvider<FastProductUpdate>
+        name="added"
+        object={value}
+        valueHandler={valueHandler as any}
+      >
+        <InputCurrency<FastProductUpdate>
+          name="price"
+          label={i18n`Price`}
+          tooltip={i18n`update the product with new price`}
+        />
+      </FormProvider>
+
+      <div class="buttons is-right mt-5">
+        <button class="button" onClick={onCancel}>
+          <Translate>Cancel</Translate>
+        </button>
+        <span
+          class="has-tooltip-left"
+          data-tooltip={i18n`update product with new price`}
+        >
+          <button
+            class="button is-info"
+            onClick={() =>
+              onUpdate({
+                ...product,
+                price: value.price,
+              })
+            }
+          >
+            <Translate>Confirm</Translate>
+          </button>
+        </span>
+      </div>
+    </Fragment>
+  );
+}
+
+function FastProductWithManagedStockUpdateForm({
+  product,
+  onUpdate,
+  onCancel,
+}: FastProductUpdateFormProps) {
+  const [value, valueHandler] = useState<FastProductUpdate>({
+    incoming: 0,
+    lost: 0,
+    price: product.price,
+  });
+
+  const currentStock =
+    product.total_stock - product.total_sold - product.total_lost;
+
+  const errors: FormErrors<FastProductUpdate> = {
+    lost:
+      currentStock + value.incoming < value.lost
+        ? `lost cannot be greater that current + incoming (max ${
+            currentStock + value.incoming
+          })`
+        : undefined,
+  };
+
+  const hasErrors = Object.keys(errors).some(
+    (k) => (errors as any)[k] !== undefined
+  );
+  const i18n = useTranslator();
+
+  return (
+    <Fragment>
+      <FormProvider<FastProductUpdate>
+        name="added"
+        errors={errors}
+        object={value}
+        valueHandler={valueHandler as any}
+      >
+        <InputNumber<FastProductUpdate>
+          name="incoming"
+          label={i18n`Incoming`}
+          tooltip={i18n`add more elements to the inventory`}
+        />
+        <InputNumber<FastProductUpdate>
+          name="lost"
+          label={i18n`Lost`}
+          tooltip={i18n`report elements lost in the inventory`}
+        />
+        <InputCurrency<FastProductUpdate>
+          name="price"
+          label={i18n`Price`}
+          tooltip={i18n`new price for the product`}
+        />
+      </FormProvider>
+
+      <div class="buttons is-right mt-5">
+        <button class="button" onClick={onCancel}>
+          <Translate>Cancel</Translate>
+        </button>
+        <span
+          class="has-tooltip-left"
+          data-tooltip={
+            hasErrors
+              ? i18n`the are value with errors`
+              : i18n`update product with new stock and price`
+          }
+        >
+          <button
+            class="button is-info"
+            disabled={hasErrors}
+            onClick={() =>
+              onUpdate({
+                ...product,
+                total_stock: product.total_stock + value.incoming,
+                total_lost: product.total_lost + value.lost,
+                price: value.price,
+              })
+            }
+          >
+            <Translate>Confirm</Translate>
+          </button>
+        </span>
+      </div>
+    </Fragment>
+  );
+}
+
+function FastProductUpdateForm(props: FastProductUpdateFormProps) {
+  return props.product.total_stock === -1 ? (
+    <FastProductWithInfiniteStockUpdateForm {...props} />
+  ) : (
+    <FastProductWithManagedStockUpdateForm {...props} />
+  );
+}
+
+function EmptyTable(): VNode {
+  return (
+    <div class="content has-text-grey has-text-centered">
+      <p>
+        <span class="icon is-large">
+          <i class="mdi mdi-emoticon-sad mdi-48px" />
+        </span>
+      </p>
+      <p>
+        <Translate>
+          There is no products yet, add more pressing the + sign
+        </Translate>
+      </p>
+    </div>
+  );
+}
+
+function difference(price: string, tax: number) {
+  if (!tax) return price;
+  const ps = price.split(":");
+  const p = parseInt(ps[1], 10);
+  ps[1] = `${p - tax}`;
+  return ps.join(":");
+}
+function sum(taxes: MerchantBackend.Tax[]) {
+  return taxes.reduce((p, c) => p + parseInt(c.tax.split(":")[1], 10), 0);
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/products/list/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/products/list/index.tsx
new file mode 100644
index 000000000..63e440df5
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/paths/instance/products/list/index.tsx
@@ -0,0 +1,80 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode } from 'preact';
+import { useState } from 'preact/hooks';
+import { Loading } from '../../../../components/exception/loading';
+import { NotificationCard } from '../../../../components/menu';
+import { MerchantBackend, WithId } from '../../../../declaration';
+import { HttpError } from '../../../../hooks/backend';
+import { useInstanceProducts, useProductAPI } from "../../../../hooks/product";
+import { useTranslator } from '../../../../i18n';
+import { Notification } from '../../../../utils/types';
+import { CardTable } from './Table';
+
+interface Props {
+  onUnauthorized: () => VNode;
+  onNotFound: () => VNode;
+  onCreate: () => void;
+  onSelect: (id: string) => void;
+  onLoadError: (e: HttpError) => VNode;
+}
+export default function ProductList({ onUnauthorized, onLoadError, onCreate, 
onSelect, onNotFound }: Props): VNode {
+  const result = useInstanceProducts()
+  const { deleteProduct, updateProduct } = useProductAPI()
+  const [notif, setNotif] = useState<Notification | undefined>(undefined)
+
+  const i18n = useTranslator()
+
+  if (result.clientError && result.isUnauthorized) return onUnauthorized()
+  if (result.clientError && result.isNotfound) return onNotFound()
+  if (result.loading) return <Loading />
+  if (!result.ok) return onLoadError(result)
+
+  return <section class="section is-main-section">
+    <NotificationCard notification={notif} />
+
+    <CardTable instances={result.data}
+      onCreate={onCreate}
+      onUpdate={(id, prod) => updateProduct(id, prod)
+        .then(() => setNotif({
+          message: i18n`product updated successfully`,
+          type: "SUCCESS"
+        })).catch((error) => setNotif({
+          message: i18n`could not update the product`,
+          type: "ERROR",
+          description: error.message
+        }))
+      }
+      onSelect={(product) => onSelect(product.id)}
+      onDelete={(prod: (MerchantBackend.Products.ProductDetail & WithId)) => 
deleteProduct(prod.id)
+        .then(() => setNotif({
+          message: i18n`product delete successfully`,
+          type: "SUCCESS"
+        })).catch((error) => setNotif({
+          message: i18n`could not delete the product`,
+          type: "ERROR",
+          description: error.message
+        }))
+      }
+    />
+  </section>
+}
\ No newline at end of file
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/products/update/Update.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/products/update/Update.stories.tsx
new file mode 100644
index 000000000..3a57f7fac
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/products/update/Update.stories.tsx
@@ -0,0 +1,71 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode, FunctionalComponent } from 'preact';
+import { UpdatePage as TestedComponent } from './UpdatePage';
+
+
+export default {
+  title: 'Pages/Product/Update',
+  component: TestedComponent,
+  argTypes: {
+    onUpdate: { action: 'onUpdate' },
+    onBack: { action: 'onBack' },
+  },
+};
+
+function createExample<Props>(Component: FunctionalComponent<Props>, props: 
Partial<Props>) {
+  const r = (args: any) => <Component {...args} />
+  r.args = props
+  return r
+}
+
+export const WithManagedStock = createExample(TestedComponent, {
+  product: {
+    product_id: '20102-ASDAS-QWE',
+    description: 'description1',
+    description_i18n: {} as any,
+    image: '',
+    price: 'TESTKUDOS:10',
+    taxes: [],
+    total_lost: 10,
+    total_sold: 5,
+    total_stock: 15,
+    unit: 'bar',
+    address: {}
+  }
+});
+
+export const WithInfiniteStock = createExample(TestedComponent, {
+  product: {
+    product_id: '20102-ASDAS-QWE',
+    description: 'description1',
+    description_i18n: {} as any,
+    image: '',
+    price: 'TESTKUDOS:10',
+    taxes: [],
+    total_lost: 10,
+    total_sold: 5,
+    total_stock: -1,
+    unit: 'bar',
+    address: {}
+  }
+});
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/products/update/UpdatePage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/products/update/UpdatePage.tsx
new file mode 100644
index 000000000..d7eb3d162
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/products/update/UpdatePage.tsx
@@ -0,0 +1,77 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode } from "preact";
+import { AsyncButton } from "../../../../components/exception/AsyncButton";
+import { ProductForm } from "../../../../components/product/ProductForm";
+import { MerchantBackend, WithId } from "../../../../declaration";
+import { useListener } from "../../../../hooks/listener";
+import { Translate, useTranslator } from "../../../../i18n";
+
+type Entity = MerchantBackend.Products.ProductDetail & { product_id: string }
+
+interface Props {
+  onUpdate: (d: Entity) => Promise<void>;
+  onBack?: () => void;
+  product: Entity;
+}
+
+export function UpdatePage({ product, onUpdate, onBack }: Props): VNode {
+  const [submitForm, addFormSubmitter] = useListener<Entity | 
undefined>((result) => {
+    if (result) return onUpdate(result)
+    return Promise.resolve()
+  })
+
+  const i18n = useTranslator()
+
+  return <div>
+    <section class="section">
+      <section class="hero is-hero-bar">
+        <div class="hero-body">
+
+          <div class="level">
+            <div class="level-left">
+              <div class="level-item">
+                <span class="is-size-4"><Translate>Product 
id:</Translate><b>{product.product_id}</b></span>
+              </div>
+            </div>
+          </div>
+        </div>
+      </section>
+      <hr />
+
+      <div class="columns">
+        <div class="column" />
+        <div class="column is-four-fifths">
+          <ProductForm initial={product} onSubscribe={addFormSubmitter} 
alreadyExist />
+
+          <div class="buttons is-right mt-5">
+            {onBack && <button class="button" onClick={onBack} 
><Translate>Cancel</Translate></button>}
+            <AsyncButton onClick={submitForm} data-tooltip={
+              !submitForm ? i18n`Need to complete marked fields` : 'confirm 
operation'
+            } 
disabled={!submitForm}><Translate>Confirm</Translate></AsyncButton>
+          </div>
+        </div>
+        <div class="column" />
+      </div>
+    </section>
+  </div>
+}
\ No newline at end of file
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/products/update/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/products/update/index.tsx
new file mode 100644
index 000000000..a6a61c815
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/products/update/index.tsx
@@ -0,0 +1,71 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { Fragment, h, VNode } from 'preact';
+import { useState } from 'preact/hooks';
+import { Loading } from '../../../../components/exception/loading';
+import { NotificationCard } from '../../../../components/menu';
+import { MerchantBackend } from '../../../../declaration';
+import { HttpError } from '../../../../hooks/backend';
+import { useProductAPI, useProductDetails } from '../../../../hooks/product';
+import { useTranslator } from '../../../../i18n';
+import { Notification } from '../../../../utils/types';
+import { UpdatePage } from './UpdatePage';
+
+export type Entity = MerchantBackend.Products.ProductAddDetail
+interface Props {
+  onBack?: () => void;
+  onConfirm: () => void;
+  onUnauthorized: () => VNode;
+  onNotFound: () => VNode;
+  onLoadError: (e: HttpError) => VNode;
+  pid: string;
+}
+export default function UpdateProduct({ pid, onConfirm, onBack, 
onUnauthorized, onNotFound, onLoadError }: Props): VNode {
+  const { updateProduct } = useProductAPI()
+  const result = useProductDetails(pid)
+  const [notif, setNotif] = useState<Notification | undefined>(undefined)
+
+  const i18n = useTranslator()
+
+  if (result.clientError && result.isUnauthorized) return onUnauthorized()
+  if (result.clientError && result.isNotfound) return onNotFound()
+  if (result.loading) return <Loading />
+  if (!result.ok) return onLoadError(result)
+
+  return <Fragment>
+    <NotificationCard notification={notif} />
+    <UpdatePage
+      product={{ ...result.data, product_id: pid }}
+      onBack={onBack}
+      onUpdate={(data) => {
+        return updateProduct(pid, data)
+          .then(onConfirm)
+          .catch((error) => {
+            setNotif({
+              message: i18n`could not create product`,
+              type: "ERROR",
+              description: error.message
+            })
+          })
+      }} />
+  </Fragment>
+}
\ No newline at end of file
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/Create.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/Create.stories.tsx
new file mode 100644
index 000000000..e138770a8
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/Create.stories.tsx
@@ -0,0 +1,42 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode, FunctionalComponent } from 'preact';
+import { CreatePage as TestedComponent } from './CreatePage';
+
+
+export default {
+  title: 'Pages/Reserve/Create',
+  component: TestedComponent,
+  argTypes: {
+    onCreate: { action: 'onCreate' },
+    onBack: { action: 'onBack' },
+  },
+};
+
+function createExample<Props>(Component: FunctionalComponent<Props>, props: 
Partial<Props>) {
+  const r = (args: any) => <Component {...args} />
+  r.args = props
+  return r
+}
+
+export const Example = createExample(TestedComponent, {
+});
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatePage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatePage.tsx
new file mode 100644
index 000000000..2e85cf9c8
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatePage.tsx
@@ -0,0 +1,168 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { Fragment, h, VNode } from "preact";
+import { StateUpdater, useEffect, useState } from "preact/hooks";
+import { FormErrors, FormProvider } from 
"../../../../components/form/FormProvider";
+import { Input } from "../../../../components/form/Input";
+import { InputCurrency } from "../../../../components/form/InputCurrency";
+import { ExchangeBackend, MerchantBackend } from "../../../../declaration";
+import { Translate, useTranslator } from "../../../../i18n";
+import { AsyncButton } from "../../../../components/exception/AsyncButton";
+import { canonicalizeBaseUrl, ExchangeKeysJson } from "@gnu-taler/taler-util"
+import { PAYTO_WIRE_METHOD_LOOKUP, URL_REGEX } from 
"../../../../utils/constants";
+import { request } from "../../../../hooks/backend";
+import { InputSelector } from "../../../../components/form/InputSelector";
+
+type Entity = MerchantBackend.Tips.ReserveCreateRequest
+
+interface Props {
+  onCreate: (d: Entity) => Promise<void>;
+  onBack?: () => void;
+}
+
+
+enum Steps {
+  EXCHANGE,
+  WIRE_METHOD,
+}
+
+interface ViewProps {
+  step: Steps,
+  setCurrentStep: (s: Steps) => void;
+  reserve: Partial<Entity>;
+  onBack?: () => void;
+  submitForm: () => Promise<void>;
+  setReserve: StateUpdater<Partial<Entity>>;
+}
+function ViewStep({ step, setCurrentStep, reserve, onBack, submitForm, 
setReserve }: ViewProps): VNode {
+  const i18n = useTranslator()
+  const [wireMethods, setWireMethods] = useState<Array<string>>([])
+  const [exchangeQueryError, setExchangeQueryError] = useState<string | 
undefined>(undefined)
+
+  useEffect(() => {
+    setExchangeQueryError(undefined)
+  }, [reserve.exchange_url])
+
+  switch (step) {
+    case Steps.EXCHANGE: {
+      const errors: FormErrors<Entity> = {
+        initial_balance: !reserve.initial_balance ? 'cannot be empty' : 
!(parseInt(reserve.initial_balance.split(':')[1], 10) > 0) ? i18n`it should be 
greater than 0` : undefined,
+        exchange_url: !reserve.exchange_url ? i18n`cannot be empty` : 
!URL_REGEX.test(reserve.exchange_url) ? i18n`must be a valid URL` : 
!exchangeQueryError ? undefined : exchangeQueryError,
+      }
+
+      const hasErrors = Object.keys(errors).some(k => (errors as any)[k] !== 
undefined)
+
+      return <Fragment>
+        <FormProvider<Entity> object={reserve} errors={errors} 
valueHandler={setReserve}>
+          <InputCurrency<Entity> name="initial_balance" label={i18n`Initial 
balance`} tooltip={i18n`balance prior to deposit`} />
+          <Input<Entity> name="exchange_url" label={i18n`Exchange URL`} 
tooltip={i18n`URL of exchange`} />
+        </FormProvider>
+
+        <div class="buttons is-right mt-5">
+          {onBack && <button class="button" onClick={onBack} 
><Translate>Cancel</Translate></button>}
+          <AsyncButton class="has-tooltip-left" onClick={() => {
+            return 
request<ExchangeBackend.WireResponse>(`${reserve.exchange_url}wire`).then(r => {
+              const wireMethods = r.data.accounts.map(a => {
+                const match = PAYTO_WIRE_METHOD_LOOKUP.exec(a.payto_uri)
+                return match && match[1] || ''
+              })
+              setWireMethods(wireMethods)
+              setCurrentStep(Steps.WIRE_METHOD)
+              return
+            }).catch((r: any) => {
+              setExchangeQueryError(r.message)
+            })
+          }} data-tooltip={
+            hasErrors ? i18n`Need to complete marked fields` : 'confirm 
operation'
+          } disabled={hasErrors} ><Translate>Next</Translate></AsyncButton>
+        </div>
+      </Fragment>
+    }
+
+    case Steps.WIRE_METHOD: {
+      const errors: FormErrors<Entity> = {
+        wire_method: !reserve.wire_method ? i18n`cannot be empty` : undefined,
+      }
+
+      const hasErrors = Object.keys(errors).some(k => (errors as any)[k] !== 
undefined)
+      return <Fragment>
+        <FormProvider<Entity> object={reserve} errors={errors} 
valueHandler={setReserve}>
+          <InputCurrency<Entity> name="initial_balance" label={i18n`Initial 
balance`} tooltip={i18n`balance prior to deposit`} readonly />
+          <Input<Entity> name="exchange_url" label={i18n`Exchange URL`} 
tooltip={i18n`URL of exchange`} readonly />
+          <InputSelector<Entity> name="wire_method" label={i18n`Wire method`} 
tooltip={i18n`method to use for wire transfer`} values={wireMethods} 
placeholder={i18n`Select one wire method`} />
+        </FormProvider>
+        <div class="buttons is-right mt-5">
+          {onBack && <button class="button" onClick={() => 
setCurrentStep(Steps.EXCHANGE)} ><Translate>Back</Translate></button>}
+          <AsyncButton onClick={submitForm} data-tooltip={
+              hasErrors ? i18n`Need to complete marked fields` : 'confirm 
operation'
+            } disabled={hasErrors} 
><Translate>Confirm</Translate></AsyncButton>
+        </div>
+      </Fragment>
+
+    }
+  }
+}
+
+export function CreatePage({ onCreate, onBack }: Props): VNode {
+  const [reserve, setReserve] = useState<Partial<Entity>>({})
+
+
+  const submitForm = () => {
+    return onCreate(reserve as Entity)
+  }
+
+  const [currentStep, setCurrentStep] = useState(Steps.EXCHANGE)
+
+
+  return <div>
+    <section class="section is-main-section">
+      <div class="columns">
+        <div class="column" />
+        <div class="column is-four-fifths">
+
+          <div class="tabs is-toggle is-fullwidth is-small">
+            <ul>
+              <li class={currentStep === Steps.EXCHANGE ? "is-active" : ""}>
+                <a style={{ cursor: 'initial' }}>
+                  <span>Step 1: Specify exchange</span>
+                </a>
+              </li>
+              <li class={currentStep === Steps.WIRE_METHOD ? "is-active" : ""}>
+                <a style={{ cursor: 'initial' }}>
+                  <span>Step 2: Select wire method</span>
+                </a>
+              </li>
+            </ul>
+          </div>
+
+          <ViewStep step={currentStep} reserve={reserve}
+            setCurrentStep={setCurrentStep}
+            setReserve={setReserve}
+            submitForm={submitForm}
+            onBack={onBack}
+          />
+        </div>
+        <div class="column" />
+      </div>
+    </section>
+  </div>
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatedSuccessfully.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatedSuccessfully.stories.tsx
new file mode 100644
index 000000000..f013040ff
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatedSuccessfully.stories.tsx
@@ -0,0 +1,53 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode, FunctionalComponent } from 'preact';
+import { CreatedSuccessfully as TestedComponent } from './CreatedSuccessfully';
+
+
+export default {
+  title: 'Pages/Reserve/CreatedSuccessfully',
+  component: TestedComponent,
+  argTypes: {
+    onCreate: { action: 'onCreate' },
+    onBack: { action: 'onBack' },
+  },
+};
+
+function createExample<Props>(Component: FunctionalComponent<Props>, props: 
Partial<Props>) {
+  const r = (args: any) => <Component {...args} />
+  r.args = props
+  return r
+}
+
+export const Example = createExample(TestedComponent, {
+  entity: {
+    request: {
+      exchange_url: 'http://exchange.taler/',
+      initial_balance: 'TESTKUDOS:1',
+      wire_method: 'x-taler-bank',
+    },
+    response: {
+      payto_uri: 'payto://x-taler-bank/bank.taler:8080/exchange_account',
+      reserve_pub: 'WEQWDASDQWEASDADASDQWEQWEASDAS'
+    }
+  }
+});
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatedSuccessfully.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatedSuccessfully.tsx
new file mode 100644
index 000000000..255486d22
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatedSuccessfully.tsx
@@ -0,0 +1,79 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+import { h, VNode } from "preact";
+import { CreatedSuccessfully as Template } from 
"../../../../components/notifications/CreatedSuccessfully";
+import { MerchantBackend } from "../../../../declaration";
+import { Translate } from "../../../../i18n";
+import { QR } from "../../../../components/exception/QR";
+
+type Entity = { request: MerchantBackend.Tips.ReserveCreateRequest, response: 
MerchantBackend.Tips.ReserveCreateConfirmation };
+
+interface Props {
+  entity: Entity;
+  onConfirm: () => void;
+  onCreateAnother?: () => void;
+}
+
+export function CreatedSuccessfully({ entity, onConfirm, onCreateAnother }: 
Props): VNode {
+  const link = 
`${entity.response.payto_uri}?message=${entity.response.reserve_pub}&amount=${entity.request.initial_balance}`
+
+  return <Template onConfirm={onConfirm} onCreateAnother={onCreateAnother}>
+    <div class="field is-horizontal">
+      <div class="field-label is-normal">
+        <label class="label">Amount</label>
+      </div>
+      <div class="field-body is-flex-grow-3">
+        <div class="field">
+          <p class="control">
+            <input readonly class="input" 
value={entity.request.initial_balance} />
+          </p>
+        </div>
+      </div>
+    </div>
+    <div class="field is-horizontal">
+      <div class="field-label is-normal">
+        <label class="label">Exchange bank account</label>
+      </div>
+      <div class="field-body is-flex-grow-3">
+        <div class="field">
+          <p class="control">
+            <input readonly class="input" value={entity.response.payto_uri} />
+          </p>
+        </div>
+      </div>
+    </div>
+    <div class="field is-horizontal">
+      <div class="field-label is-normal">
+        <label class="label">Wire transfer subject</label>
+      </div>
+      <div class="field-body is-flex-grow-3">
+        <div class="field">
+          <p class="control">
+            <input class="input" readonly value={entity.response.reserve_pub} 
/>
+          </p>
+        </div>
+      </div>
+    </div>
+    <p class="is-size-5"><Translate>To complete the setup of the reserve, you 
must now initiate a wire transfer using the given wire transfer subject and 
crediting the specified amount to the indicated account of the 
exchange.</Translate></p>
+    <p class="is-size-5"><Translate>If your system supports RFC 8905, you can 
do this by opening this URI:</Translate></p>
+    <pre>
+      <a target="_blank" rel="noreferrer" href={link}>{link}</a>
+    </pre>
+    <QR text={link} />
+  </Template>;
+}
+
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/index.tsx
new file mode 100644
index 000000000..5c2fdaf4b
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/index.tsx
@@ -0,0 +1,71 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { Fragment, h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { NotificationCard } from "../../../../components/menu";
+import { MerchantBackend } from "../../../../declaration";
+import { useReservesAPI } from "../../../../hooks/reserves";
+import { useTranslator } from "../../../../i18n";
+import { Notification } from "../../../../utils/types";
+import { CreatedSuccessfully } from "./CreatedSuccessfully";
+import { CreatePage } from "./CreatePage";
+interface Props {
+  onBack: () => void;
+  onConfirm: () => void;
+}
+export default function CreateReserve({ onBack, onConfirm }: Props): VNode {
+  const { createReserve } = useReservesAPI();
+  const [notif, setNotif] = useState<Notification | undefined>(undefined);
+  const i18n = useTranslator();
+
+  const [createdOk, setCreatedOk] = useState<
+    | {
+        request: MerchantBackend.Tips.ReserveCreateRequest;
+        response: MerchantBackend.Tips.ReserveCreateConfirmation;
+      }
+    | undefined
+  >(undefined);
+
+  if (createdOk) {
+    return <CreatedSuccessfully entity={createdOk} onConfirm={onConfirm} />;
+  }
+
+  return (
+    <Fragment>
+      <NotificationCard notification={notif} />
+      <CreatePage
+        onBack={onBack}
+        onCreate={(request: MerchantBackend.Tips.ReserveCreateRequest) => {
+          return createReserve(request)
+            .then((r) => setCreatedOk({ request, response: r.data }))
+            .catch((error) => {
+              setNotif({
+                message: i18n`could not create reserve`,
+                type: "ERROR",
+                description: error.message,
+              });
+            });
+        }}
+      />
+    </Fragment>
+  );
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/DetailPage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/DetailPage.tsx
new file mode 100644
index 000000000..cbc70179b
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/DetailPage.tsx
@@ -0,0 +1,278 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { Amounts } from "@gnu-taler/taler-util";
+import { format } from "date-fns";
+import { Fragment, h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { QR } from "../../../../components/exception/QR";
+import { FormProvider } from "../../../../components/form/FormProvider";
+import { Input } from "../../../../components/form/Input";
+import { InputCurrency } from "../../../../components/form/InputCurrency";
+import { InputDate } from "../../../../components/form/InputDate";
+import { TextField } from "../../../../components/form/TextField";
+import { ContinueModal, SimpleModal } from "../../../../components/modal";
+import { MerchantBackend } from "../../../../declaration";
+import { useTipDetails } from "../../../../hooks/reserves";
+import { Translate, useTranslator } from "../../../../i18n";
+import { TipInfo } from "./TipInfo";
+
+type Entity = MerchantBackend.Tips.ReserveDetail;
+type CT = MerchantBackend.ContractTerms;
+
+interface Props {
+  onBack: () => void;
+  selected: Entity;
+  id: string;
+}
+
+export function DetailPage({ id, selected, onBack }: Props): VNode {
+  const i18n = useTranslator();
+  const didExchangeAckTransfer = Amounts.isNonZero(
+    Amounts.parseOrThrow(selected.exchange_initial_amount)
+  );
+  const link = 
`${selected.payto_uri}?message=${id}&amount=${selected.merchant_initial_amount}`;
+
+  return (
+    <div class="columns">
+      <div class="column" />
+      <div class="column is-four-fifths">
+        <div class="section main-section">
+          <FormProvider object={{ ...selected, id }} valueHandler={null}>
+            <InputDate<Entity>
+              name="creation_time"
+              label={i18n`Created at`}
+              readonly
+            />
+            <InputDate<Entity>
+              name="expiration_time"
+              label={i18n`Valid until`}
+              readonly
+            />
+            <InputCurrency<Entity>
+              name="merchant_initial_amount"
+              label={i18n`Created balance`}
+              readonly
+            />
+            <TextField<Entity>
+              name="exchange_url"
+              label={i18n`Exchange URL`}
+              readonly
+            >
+              <a target="_blank" rel="noreferrer" href={selected.exchange_url}>
+                {selected.exchange_url}
+              </a>
+            </TextField>
+
+            {didExchangeAckTransfer && (
+              <Fragment>
+                <InputCurrency<Entity>
+                  name="exchange_initial_amount"
+                  label={i18n`Exchange balance`}
+                  readonly
+                />
+                <InputCurrency<Entity>
+                  name="pickup_amount"
+                  label={i18n`Picked up`}
+                  readonly
+                />
+                <InputCurrency<Entity>
+                  name="committed_amount"
+                  label={i18n`Committed`}
+                  readonly
+                />
+              </Fragment>
+            )}
+            <Input<Entity>
+              name="payto_uri"
+              label={i18n`Account address`}
+              readonly
+            />
+            <Input name="id" label={i18n`Subject`} readonly />
+          </FormProvider>
+
+          {didExchangeAckTransfer ? (
+            <Fragment>
+              <div class="card has-table">
+                <header class="card-header">
+                  <p class="card-header-title">
+                    <span class="icon">
+                      <i class="mdi mdi-cash-register" />
+                    </span>
+                    <Translate>Tips</Translate>
+                  </p>
+                </header>
+                <div class="card-content">
+                  <div class="b-table has-pagination">
+                    <div class="table-wrapper has-mobile-cards">
+                      {selected.tips && selected.tips.length > 0 ? (
+                        <Table tips={selected.tips} />
+                      ) : (
+                        <EmptyTable />
+                      )}
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </Fragment>
+          ) : (
+            <Fragment>
+              <p class="is-size-5">
+                <Translate>
+                  To complete the setup of the reserve, you must now initiate a
+                  wire transfer using the given wire transfer subject and
+                  crediting the specified amount to the indicated account of 
the
+                  exchange.
+                </Translate>
+              </p>
+              <p class="is-size-5">
+                <Translate>
+                  If your system supports RFC 8905, you can do this by opening
+                  this URI:
+                </Translate>
+              </p>
+              <pre>
+                <a target="_blank" rel="noreferrer" href={link}>
+                  {link}
+                </a>
+              </pre>
+              <QR text={link} />
+            </Fragment>
+          )}
+
+          <div class="buttons is-right mt-5">
+            <button class="button" onClick={onBack}>
+              <Translate>Back</Translate>
+            </button>
+          </div>
+        </div>
+      </div>
+      <div class="column" />
+    </div>
+  );
+}
+
+function EmptyTable(): VNode {
+  return (
+    <div class="content has-text-grey has-text-centered">
+      <p>
+        <span class="icon is-large">
+          <i class="mdi mdi-emoticon-sad mdi-48px" />
+        </span>
+      </p>
+      <p>
+        <Translate>No tips has been authorized from this reserve</Translate>
+      </p>
+    </div>
+  );
+}
+
+interface TableProps {
+  tips: MerchantBackend.Tips.TipStatusEntry[];
+}
+
+function Table({ tips }: TableProps): VNode {
+  return (
+    <div class="table-container">
+      <table class="table is-fullwidth is-striped is-hoverable is-fullwidth">
+        <thead>
+          <tr>
+            <th>
+              <Translate>Authorized</Translate>
+            </th>
+            <th>
+              <Translate>Picked up</Translate>
+            </th>
+            <th>
+              <Translate>Reason</Translate>
+            </th>
+            <th>
+              <Translate>Expiration</Translate>
+            </th>
+          </tr>
+        </thead>
+        <tbody>
+          {tips.map((t, i) => {
+            return <TipRow id={t.tip_id} key={i} entry={t} />;
+          })}
+        </tbody>
+      </table>
+    </div>
+  );
+}
+
+function TipRow({
+  id,
+  entry,
+}: {
+  id: string;
+  entry: MerchantBackend.Tips.TipStatusEntry;
+}) {
+  const [selected, setSelected] = useState(false);
+  const result = useTipDetails(id);
+  if (result.loading) {
+    return (
+      <tr>
+        <td>...</td>
+        <td>...</td>
+        <td>...</td>
+        <td>...</td>
+      </tr>
+    );
+  }
+  if (!result.ok) {
+    return (
+      <tr>
+        <td>...</td> {/* authorized */}
+        <td>{entry.total_amount}</td>
+        <td>{entry.reason}</td>
+        <td>...</td> {/* expired */}
+      </tr>
+    );
+  }
+  const info = result.data;
+  function onSelect() {
+    setSelected(true);
+  }
+  return (
+    <Fragment>
+      {selected && (
+        <SimpleModal
+          description="tip"
+          active
+          onCancel={() => setSelected(false)}
+        >
+          <TipInfo id={id} amount={info.total_authorized} entity={info} />
+        </SimpleModal>
+      )}
+      <tr>
+        <td onClick={onSelect}>{info.total_authorized}</td>
+        <td onClick={onSelect}>{info.total_picked_up}</td>
+        <td onClick={onSelect}>{info.reason}</td>
+        <td onClick={onSelect}>
+          {info.expiration.t_s === "never"
+            ? "never"
+            : format(info.expiration.t_s * 1000, "yyyy/MM/dd HH:mm:ss")}
+        </td>
+      </tr>
+    </Fragment>
+  );
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/Details.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/Details.stories.tsx
new file mode 100644
index 000000000..98c1fa72e
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/Details.stories.tsx
@@ -0,0 +1,105 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { h, VNode, FunctionalComponent } from "preact";
+import { DetailPage as TestedComponent } from "./DetailPage";
+
+export default {
+  title: "Pages/Reserve/Detail",
+  component: TestedComponent,
+  argTypes: {
+    onUpdate: { action: "onUpdate" },
+    onBack: { action: "onBack" },
+  },
+};
+
+function createExample<Props>(
+  Component: FunctionalComponent<Props>,
+  props: Partial<Props>
+) {
+  const r = (args: any) => <Component {...args} />;
+  r.args = props;
+  return r;
+}
+
+export const Funded = createExample(TestedComponent, {
+  id: "THISISTHERESERVEID",
+  selected: {
+    active: true,
+    committed_amount: "TESTKUDOS:10",
+    creation_time: {
+      t_s: new Date().getTime() / 1000,
+    },
+    exchange_initial_amount: "TESTKUDOS:10",
+    expiration_time: {
+      t_s: new Date().getTime() / 1000,
+    },
+    merchant_initial_amount: "TESTKUDOS:10",
+    pickup_amount: "TESTKUDOS:10",
+    payto_uri: "payto://x-taler-bank/bank.taler:8080/account",
+    exchange_url: "http://exchange.taler/";,
+  },
+});
+
+export const NotYetFunded = createExample(TestedComponent, {
+  id: "THISISTHERESERVEID",
+  selected: {
+    active: true,
+    committed_amount: "TESTKUDOS:10",
+    creation_time: {
+      t_s: new Date().getTime() / 1000,
+    },
+    exchange_initial_amount: "TESTKUDOS:0",
+    expiration_time: {
+      t_s: new Date().getTime() / 1000,
+    },
+    merchant_initial_amount: "TESTKUDOS:10",
+    pickup_amount: "TESTKUDOS:10",
+    payto_uri: "payto://x-taler-bank/bank.taler:8080/account",
+    exchange_url: "http://exchange.taler/";,
+  },
+});
+
+export const FundedWithEmptyTips = createExample(TestedComponent, {
+  id: "THISISTHERESERVEID",
+  selected: {
+    active: true,
+    committed_amount: "TESTKUDOS:10",
+    creation_time: {
+      t_s: new Date().getTime() / 1000,
+    },
+    exchange_initial_amount: "TESTKUDOS:10",
+    expiration_time: {
+      t_s: new Date().getTime() / 1000,
+    },
+    merchant_initial_amount: "TESTKUDOS:10",
+    pickup_amount: "TESTKUDOS:10",
+    payto_uri: "payto://x-taler-bank/bank.taler:8080/account",
+    exchange_url: "http://exchange.taler/";,
+    tips: [
+      {
+        reason: "asdasd",
+        tip_id: "123",
+        total_amount: "TESTKUDOS:1",
+      },
+    ],
+  },
+});
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/TipInfo.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/TipInfo.tsx
new file mode 100644
index 000000000..3f384966b
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/TipInfo.tsx
@@ -0,0 +1,87 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+import { format } from "date-fns";
+import { Fragment, h, VNode } from "preact";
+import { useBackendContext } from "../../../../context/backend";
+import { MerchantBackend } from "../../../../declaration";
+
+type Entity = MerchantBackend.Tips.TipDetails;
+
+interface Props {
+  id: string;
+  entity: Entity;
+  amount: string;
+}
+
+export function TipInfo({ id, amount, entity }: Props): VNode {
+  const { url } = useBackendContext();
+  const tipHost = url.replace(/.*:\/\//, ""); // remove protocol part
+  const proto = url.startsWith("http://";) ? "taler+http" : "taler";
+  const tipURL = `${proto}://tip/${tipHost}/${id}`;
+  return (
+    <Fragment>
+      <div class="field is-horizontal">
+        <div class="field-label is-normal">
+          <label class="label">Amount</label>
+        </div>
+        <div class="field-body is-flex-grow-3">
+          <div class="field">
+            <p class="control">
+              <input readonly class="input" value={amount} />
+            </p>
+          </div>
+        </div>
+      </div>
+      <div class="field is-horizontal">
+        <div class="field-label is-normal">
+          <label class="label">URL</label>
+        </div>
+        <div class="field-body is-flex-grow-3">
+          <div class="field" style={{ overflowWrap: "anywhere" }}>
+            <p class="control">
+              <a target="_blank" rel="noreferrer" href={tipURL}>
+                {tipURL}
+              </a>
+            </p>
+          </div>
+        </div>
+      </div>
+      <div class="field is-horizontal">
+        <div class="field-label is-normal">
+          <label class="label">Valid until</label>
+        </div>
+        <div class="field-body is-flex-grow-3">
+          <div class="field">
+            <p class="control">
+              <input
+                class="input"
+                readonly
+                value={
+                  !entity.expiration || entity.expiration.t_s === "never"
+                    ? "never"
+                    : format(
+                        entity.expiration.t_s * 1000,
+                        "yyyy/MM/dd HH:mm:ss"
+                      )
+                }
+              />
+            </p>
+          </div>
+        </div>
+      </div>
+    </Fragment>
+  );
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/index.tsx
new file mode 100644
index 000000000..c2483f053
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/index.tsx
@@ -0,0 +1,56 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { Fragment, h, VNode } from "preact";
+import { Loading } from "../../../../components/exception/loading";
+import { HttpError } from "../../../../hooks/backend";
+import { useReserveDetails } from "../../../../hooks/reserves";
+import { DetailPage } from "./DetailPage";
+
+interface Props {
+  rid: string;
+
+  onUnauthorized: () => VNode;
+  onLoadError: (error: HttpError) => VNode;
+  onNotFound: () => VNode;
+  onDelete: () => void;
+  onBack: () => void;
+}
+export default function DetailReserve({
+  rid,
+  onUnauthorized,
+  onLoadError,
+  onNotFound,
+  onBack,
+  onDelete,
+}: Props): VNode {
+  const result = useReserveDetails(rid);
+
+  if (result.clientError && result.isUnauthorized) return onUnauthorized();
+  if (result.clientError && result.isNotfound) return onNotFound();
+  if (result.loading) return <Loading />;
+  if (!result.ok) return onLoadError(result);
+  return (
+    <Fragment>
+      <DetailPage selected={result.data} onBack={onBack} id={rid} />
+    </Fragment>
+  );
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/AutorizeTipModal.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/AutorizeTipModal.tsx
new file mode 100644
index 000000000..ec468b2e9
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/AutorizeTipModal.tsx
@@ -0,0 +1,85 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { FormErrors, FormProvider } from 
"../../../../components/form/FormProvider";
+import { Input } from "../../../../components/form/Input";
+import { InputCurrency } from "../../../../components/form/InputCurrency";
+import { ConfirmModal, ContinueModal } from "../../../../components/modal";
+import { MerchantBackend } from "../../../../declaration";
+import { useTranslator } from "../../../../i18n";
+import { AuthorizeTipSchema } from "../../../../schemas";
+import { CreatedSuccessfully } from "./CreatedSuccessfully";
+import * as yup from 'yup';
+
+interface AuthorizeTipModalProps {
+  onCancel: () => void;
+  onConfirm: (value: MerchantBackend.Tips.TipCreateRequest) => void;
+  tipAuthorized?: {
+    response: MerchantBackend.Tips.TipCreateConfirmation;
+    request: MerchantBackend.Tips.TipCreateRequest;
+  };
+}
+
+export function AuthorizeTipModal({ onCancel, onConfirm, tipAuthorized }: 
AuthorizeTipModalProps): VNode {
+  // const result = useOrderDetails(id)
+  type State = MerchantBackend.Tips.TipCreateRequest
+  const [form, setValue] = useState<Partial<State>>({})
+  const i18n = useTranslator();
+
+  // const [errors, setErrors] = useState<FormErrors<State>>({})
+  let errors: FormErrors<State> = {}
+  try {
+    AuthorizeTipSchema.validateSync(form, { abortEarly: false })
+  } catch (err) {
+    if (err instanceof yup.ValidationError) {
+      const yupErrors = err.inner as any[]
+      errors = yupErrors.reduce((prev, cur) => !cur.path ? prev : ({ ...prev, 
[cur.path]: cur.message }), {})
+    }
+  }
+  const hasErrors = Object.keys(errors).some(k => (errors as any)[k] !== 
undefined)
+
+  const validateAndConfirm = () => {
+    onConfirm(form as State)
+  }
+  if (tipAuthorized) {
+    return <ContinueModal description="tip" active onConfirm={onCancel}>
+      <CreatedSuccessfully
+        entity={tipAuthorized.response}
+        request={tipAuthorized.request}
+        onConfirm={onCancel}
+      />
+    </ContinueModal>
+  }
+
+  return <ConfirmModal description="tip" active onCancel={onCancel} 
disabled={hasErrors} onConfirm={validateAndConfirm}>
+
+    <FormProvider<State> errors={errors} object={form} valueHandler={setValue} 
>
+      <InputCurrency<State> name="amount" label={i18n`Amount`} 
tooltip={i18n`amount of tip`} />
+      <Input<State> name="justification" label={i18n`Justification`} 
inputType="multiline" tooltip={i18n`reason for the tip`} />
+      <Input<State> name="next_url" label={i18n`URL after tip`} 
tooltip={i18n`URL to visit after tip payment`} />
+    </FormProvider>
+
+  </ConfirmModal>
+}
+
+
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/CreatedSuccessfully.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/CreatedSuccessfully.tsx
new file mode 100644
index 000000000..1e5f0758f
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/CreatedSuccessfully.tsx
@@ -0,0 +1,100 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+import { format } from "date-fns";
+import { Fragment, h, VNode } from "preact";
+import { CreatedSuccessfully as Template } from 
"../../../../components/notifications/CreatedSuccessfully";
+import { MerchantBackend } from "../../../../declaration";
+
+type Entity = MerchantBackend.Tips.TipCreateConfirmation;
+
+interface Props {
+  entity: Entity;
+  request: MerchantBackend.Tips.TipCreateRequest;
+  onConfirm: () => void;
+  onCreateAnother?: () => void;
+}
+
+export function CreatedSuccessfully({
+  request,
+  entity,
+  onConfirm,
+  onCreateAnother,
+}: Props): VNode {
+  return (
+    <Fragment>
+      <div class="field is-horizontal">
+        <div class="field-label is-normal">
+          <label class="label">Amount</label>
+        </div>
+        <div class="field-body is-flex-grow-3">
+          <div class="field">
+            <p class="control">
+              <input readonly class="input" value={request.amount} />
+            </p>
+          </div>
+        </div>
+      </div>
+      <div class="field is-horizontal">
+        <div class="field-label is-normal">
+          <label class="label">Justification</label>
+        </div>
+        <div class="field-body is-flex-grow-3">
+          <div class="field">
+            <p class="control">
+              <input readonly class="input" value={request.justification} />
+            </p>
+          </div>
+        </div>
+      </div>
+      <div class="field is-horizontal">
+        <div class="field-label is-normal">
+          <label class="label">URL</label>
+        </div>
+        <div class="field-body is-flex-grow-3">
+          <div class="field">
+            <p class="control">
+              <input readonly class="input" value={entity.tip_status_url} />
+            </p>
+          </div>
+        </div>
+      </div>
+      <div class="field is-horizontal">
+        <div class="field-label is-normal">
+          <label class="label">Valid until</label>
+        </div>
+        <div class="field-body is-flex-grow-3">
+          <div class="field">
+            <p class="control">
+              <input
+                class="input"
+                readonly
+                value={
+                  !entity.tip_expiration ||
+                  entity.tip_expiration.t_s === "never"
+                    ? "never"
+                    : format(
+                        entity.tip_expiration.t_s * 1000,
+                        "yyyy/MM/dd HH:mm:ss"
+                      )
+                }
+              />
+            </p>
+          </div>
+        </div>
+      </div>
+    </Fragment>
+  );
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/List.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/List.stories.tsx
new file mode 100644
index 000000000..1cb9e748c
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/List.stories.tsx
@@ -0,0 +1,102 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { h, VNode, FunctionalComponent } from "preact";
+import { CardTable as TestedComponent } from "./Table";
+
+export default {
+  title: "Pages/Reserve/List",
+  component: TestedComponent,
+  argTypes: {
+    onCreate: { action: "onCreate" },
+    onDelete: { action: "onDelete" },
+    onNewTip: { action: "onNewTip" },
+    onSelect: { action: "onSelect" },
+  },
+};
+
+function createExample<Props>(
+  Component: FunctionalComponent<Props>,
+  props: Partial<Props>
+) {
+  const r = (args: any) => <Component {...args} />;
+  r.args = props;
+  return r;
+}
+
+export const AllFunded = createExample(TestedComponent, {
+  instances: [
+    {
+      id: "reseverId",
+      active: true,
+      committed_amount: "TESTKUDOS:10",
+      creation_time: {
+        t_s: new Date().getTime() / 1000,
+      },
+      exchange_initial_amount: "TESTKUDOS:10",
+      expiration_time: {
+        t_s: new Date().getTime() / 1000,
+      },
+      merchant_initial_amount: "TESTKUDOS:10",
+      pickup_amount: "TESTKUDOS:10",
+      reserve_pub: "WEQWDASDQWEASDADASDQWEQWEASDAS",
+    },
+    {
+      id: "reseverId2",
+      active: true,
+      committed_amount: "TESTKUDOS:13",
+      creation_time: {
+        t_s: new Date().getTime() / 1000,
+      },
+      exchange_initial_amount: "TESTKUDOS:10",
+      expiration_time: {
+        t_s: new Date().getTime() / 1000,
+      },
+      merchant_initial_amount: "TESTKUDOS:10",
+      pickup_amount: "TESTKUDOS:10",
+      reserve_pub: "WEQWDASDQWEASDADASDQWEQWEASDAS",
+    },
+  ],
+});
+
+export const Empty = createExample(TestedComponent, {
+  instances: [],
+});
+
+export const OneNotYetFunded = createExample(TestedComponent, {
+  instances: [
+    {
+      id: "reseverId",
+      active: true,
+      committed_amount: "TESTKUDOS:0",
+      creation_time: {
+        t_s: new Date().getTime() / 1000,
+      },
+      exchange_initial_amount: "TESTKUDOS:0",
+      expiration_time: {
+        t_s: new Date().getTime() / 1000,
+      },
+      merchant_initial_amount: "TESTKUDOS:10",
+      pickup_amount: "TESTKUDOS:10",
+      reserve_pub: "WEQWDASDQWEASDADASDQWEQWEASDAS",
+    },
+  ],
+});
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/Table.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/Table.tsx
new file mode 100644
index 000000000..b3bb7b020
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/Table.tsx
@@ -0,0 +1,313 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { format } from "date-fns";
+import { Fragment, h, VNode } from "preact";
+import { MerchantBackend, WithId } from "../../../../declaration";
+import { Translate, useTranslator } from "../../../../i18n";
+
+type Entity = MerchantBackend.Tips.ReserveStatusEntry & WithId;
+
+interface Props {
+  instances: Entity[];
+  onNewTip: (id: Entity) => void;
+  onSelect: (id: Entity) => void;
+  onDelete: (id: Entity) => void;
+  onCreate: () => void;
+}
+
+export function CardTable({
+  instances,
+  onCreate,
+  onSelect,
+  onNewTip,
+  onDelete,
+}: Props): VNode {
+  const [withoutFunds, withFunds] = instances.reduce((prev, current) => {
+    const amount = current.exchange_initial_amount;
+    if (amount.endsWith(":0")) {
+      prev[0] = prev[0].concat(current);
+    } else {
+      prev[1] = prev[1].concat(current);
+    }
+    return prev;
+  }, new Array<Array<Entity>>([], []));
+
+  const i18n = useTranslator();
+
+  return (
+    <Fragment>
+      {withoutFunds.length > 0 && (
+        <div class="card has-table">
+          <header class="card-header">
+            <p class="card-header-title">
+              <span class="icon">
+                <i class="mdi mdi-cash" />
+              </span>
+              <Translate>Reserves not yet funded</Translate>
+            </p>
+          </header>
+          <div class="card-content">
+            <div class="b-table has-pagination">
+              <div class="table-wrapper has-mobile-cards">
+                <TableWithoutFund
+                  instances={withoutFunds}
+                  onNewTip={onNewTip}
+                  onSelect={onSelect}
+                  onDelete={onDelete}
+                />
+              </div>
+            </div>
+          </div>
+        </div>
+      )}
+
+      <div class="card has-table">
+        <header class="card-header">
+          <p class="card-header-title">
+            <span class="icon">
+              <i class="mdi mdi-cash" />
+            </span>
+            <Translate>Reserves ready</Translate>
+          </p>
+          <div class="card-header-icon" aria-label="more options" />
+          <div class="card-header-icon" aria-label="more options">
+            <span class="has-tooltip-left" data-tooltip={i18n`add new 
reserve`}>
+              <button class="button is-info" type="button" onClick={onCreate}>
+                <span class="icon is-small">
+                  <i class="mdi mdi-plus mdi-36px" />
+                </span>
+              </button>
+            </span>
+          </div>
+        </header>
+        <div class="card-content">
+          <div class="b-table has-pagination">
+            <div class="table-wrapper has-mobile-cards">
+              {withFunds.length > 0 ? (
+                <Table
+                  instances={withFunds}
+                  onNewTip={onNewTip}
+                  onSelect={onSelect}
+                  onDelete={onDelete}
+                />
+              ) : (
+                <EmptyTable />
+              )}
+            </div>
+          </div>
+        </div>
+      </div>
+    </Fragment>
+  );
+}
+interface TableProps {
+  instances: Entity[];
+  onNewTip: (id: Entity) => void;
+  onDelete: (id: Entity) => void;
+  onSelect: (id: Entity) => void;
+}
+
+function Table({ instances, onNewTip, onSelect, onDelete }: TableProps): VNode 
{
+  const i18n = useTranslator();
+  return (
+    <div class="table-container">
+      <table class="table is-fullwidth is-striped is-hoverable is-fullwidth">
+        <thead>
+          <tr>
+            <th>
+              <Translate>Created at</Translate>
+            </th>
+            <th>
+              <Translate>Expires at</Translate>
+            </th>
+            <th>
+              <Translate>Initial</Translate>
+            </th>
+            <th>
+              <Translate>Picked up</Translate>
+            </th>
+            <th>
+              <Translate>Committed</Translate>
+            </th>
+            <th />
+          </tr>
+        </thead>
+        <tbody>
+          {instances.map((i) => {
+            return (
+              <tr key={i.id}>
+                <td
+                  onClick={(): void => onSelect(i)}
+                  style={{ cursor: "pointer" }}
+                >
+                  {i.creation_time.t_s === "never"
+                    ? "never"
+                    : format(i.creation_time.t_s * 1000, "yyyy/MM/dd 
HH:mm:ss")}
+                </td>
+                <td
+                  onClick={(): void => onSelect(i)}
+                  style={{ cursor: "pointer" }}
+                >
+                  {i.expiration_time.t_s === "never"
+                    ? "never"
+                    : format(
+                        i.expiration_time.t_s * 1000,
+                        "yyyy/MM/dd HH:mm:ss"
+                      )}
+                </td>
+                <td
+                  onClick={(): void => onSelect(i)}
+                  style={{ cursor: "pointer" }}
+                >
+                  {i.exchange_initial_amount}
+                </td>
+                <td
+                  onClick={(): void => onSelect(i)}
+                  style={{ cursor: "pointer" }}
+                >
+                  {i.pickup_amount}
+                </td>
+                <td
+                  onClick={(): void => onSelect(i)}
+                  style={{ cursor: "pointer" }}
+                >
+                  {i.committed_amount}
+                </td>
+                <td class="is-actions-cell right-sticky">
+                  <div class="buttons is-right">
+                    <button
+                      class="button is-small is-danger has-tooltip-left"
+                      data-tooltip={i18n`delete selected reserve from the 
database`}
+                      type="button"
+                      onClick={(): void => onDelete(i)}
+                    >
+                      Delete
+                    </button>
+                    <button
+                      class="button is-small is-info has-tooltip-left"
+                      data-tooltip={i18n`authorize new tip from selected 
reserve`}
+                      type="button"
+                      onClick={(): void => onNewTip(i)}
+                    >
+                      New Tip
+                    </button>
+                  </div>
+                </td>
+              </tr>
+            );
+          })}
+        </tbody>
+      </table>
+    </div>
+  );
+}
+
+function EmptyTable(): VNode {
+  return (
+    <div class="content has-text-grey has-text-centered">
+      <p>
+        <span class="icon is-large">
+          <i class="mdi mdi-emoticon-sad mdi-48px" />
+        </span>
+      </p>
+      <p>
+        <Translate>
+          There is no ready reserves yet, add more pressing the + sign or fund
+          them
+        </Translate>
+      </p>
+    </div>
+  );
+}
+
+function TableWithoutFund({
+  instances,
+  onSelect,
+  onDelete,
+}: TableProps): VNode {
+  const i18n = useTranslator();
+  return (
+    <div class="table-container">
+      <table class="table is-fullwidth is-striped is-hoverable is-fullwidth">
+        <thead>
+          <tr>
+            <th>
+              <Translate>Created at</Translate>
+            </th>
+            <th>
+              <Translate>Expires at</Translate>
+            </th>
+            <th>
+              <Translate>Expected Balance</Translate>
+            </th>
+            <th />
+          </tr>
+        </thead>
+        <tbody>
+          {instances.map((i) => {
+            return (
+              <tr key={i.id}>
+                <td
+                  onClick={(): void => onSelect(i)}
+                  style={{ cursor: "pointer" }}
+                >
+                  {i.creation_time.t_s === "never"
+                    ? "never"
+                    : format(i.creation_time.t_s * 1000, "yyyy/MM/dd 
HH:mm:ss")}
+                </td>
+                <td
+                  onClick={(): void => onSelect(i)}
+                  style={{ cursor: "pointer" }}
+                >
+                  {i.expiration_time.t_s === "never"
+                    ? "never"
+                    : format(
+                        i.expiration_time.t_s * 1000,
+                        "yyyy/MM/dd HH:mm:ss"
+                      )}
+                </td>
+                <td
+                  onClick={(): void => onSelect(i)}
+                  style={{ cursor: "pointer" }}
+                >
+                  {i.merchant_initial_amount}
+                </td>
+                <td class="is-actions-cell right-sticky">
+                  <div class="buttons is-right">
+                    <button
+                      class="button is-small is-danger jb-modal 
has-tooltip-left"
+                      type="button"
+                      data-tooltip={i18n`delete selected reserve from the 
database`}
+                      onClick={(): void => onDelete(i)}
+                    >
+                      Delete
+                    </button>
+                  </div>
+                </td>
+              </tr>
+            );
+          })}
+        </tbody>
+      </table>
+    </div>
+  );
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/index.tsx
new file mode 100644
index 000000000..f071b5635
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/index.tsx
@@ -0,0 +1,117 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { Loading } from "../../../../components/exception/loading";
+import { NotificationCard } from "../../../../components/menu";
+import { MerchantBackend } from "../../../../declaration";
+import { HttpError } from "../../../../hooks/backend";
+import {
+  useInstanceReserves,
+  useReservesAPI,
+} from "../../../../hooks/reserves";
+import { useTranslator } from "../../../../i18n";
+import { Notification } from "../../../../utils/types";
+import { CardTable } from "./Table";
+import { AuthorizeTipModal } from "./AutorizeTipModal";
+
+interface Props {
+  onUnauthorized: () => VNode;
+  onLoadError: (e: HttpError) => VNode;
+  onSelect: (id: string) => void;
+  onNotFound: () => VNode;
+  onCreate: () => void;
+}
+
+interface TipConfirmation {
+  response: MerchantBackend.Tips.TipCreateConfirmation;
+  request: MerchantBackend.Tips.TipCreateRequest;
+}
+
+export default function ListTips({
+  onUnauthorized,
+  onLoadError,
+  onNotFound,
+  onSelect,
+  onCreate,
+}: Props): VNode {
+  const result = useInstanceReserves();
+  const { deleteReserve, authorizeTipReserve } = useReservesAPI();
+  const [notif, setNotif] = useState<Notification | undefined>(undefined);
+  const i18n = useTranslator();
+  const [reserveForTip, setReserveForTip] = useState<string | undefined>(
+    undefined
+  );
+  const [tipAuthorized, setTipAuthorized] = useState<
+    TipConfirmation | undefined
+  >(undefined);
+
+  if (result.clientError && result.isUnauthorized) return onUnauthorized();
+  if (result.clientError && result.isNotfound) return onNotFound();
+  if (result.loading) return <Loading />;
+  if (!result.ok) return onLoadError(result);
+
+  return (
+    <section class="section is-main-section">
+      <NotificationCard notification={notif} />
+
+      {reserveForTip && (
+        <AuthorizeTipModal
+          onCancel={() => {
+            setReserveForTip(undefined);
+            setTipAuthorized(undefined);
+          }}
+          tipAuthorized={tipAuthorized}
+          onConfirm={async (request) => {
+            try {
+              const response = await authorizeTipReserve(
+                reserveForTip,
+                request
+              );
+              setTipAuthorized({
+                request,
+                response: response.data,
+              });
+            } catch (error) {
+              setNotif({
+                message: i18n`could not create the tip`,
+                type: "ERROR",
+                description: error instanceof Error ? error.message : 
undefined,
+              });
+              setReserveForTip(undefined);
+            }
+          }}
+        />
+      )}
+
+      <CardTable
+        instances={result.data.reserves
+          .filter((r) => r.active)
+          .map((o) => ({ ...o, id: o.reserve_pub }))}
+        onCreate={onCreate}
+        onDelete={(reserve) => deleteReserve(reserve.reserve_pub)}
+        onSelect={(reserve) => onSelect(reserve.id)}
+        onNewTip={(reserve) => setReserveForTip(reserve.id)}
+      />
+    </section>
+  );
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/transfers/create/Create.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/create/Create.stories.tsx
new file mode 100644
index 000000000..535cb1e37
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/create/Create.stories.tsx
@@ -0,0 +1,43 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode, FunctionalComponent } from 'preact';
+import { CreatePage as TestedComponent } from './CreatePage';
+
+
+export default {
+  title: 'Pages/Transfer/Create',
+  component: TestedComponent,
+  argTypes: {
+    onUpdate: { action: 'onUpdate' },
+    onBack: { action: 'onBack' },
+  },
+};
+
+function createExample<Props>(Component: FunctionalComponent<Props>, props: 
Partial<Props>) {
+  const r = (args: any) => <Component {...args} />
+  r.args = props
+  return r
+}
+
+export const Example = createExample(TestedComponent, {
+  accounts: ['payto://x-taler-bank/account1','payto://x-taler-bank/account2']
+});
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/transfers/create/CreatePage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/create/CreatePage.tsx
new file mode 100644
index 000000000..d0f5c5e95
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/create/CreatePage.tsx
@@ -0,0 +1,104 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { AsyncButton } from "../../../../components/exception/AsyncButton";
+import { FormErrors, FormProvider } from 
"../../../../components/form/FormProvider";
+import { Input } from "../../../../components/form/Input";
+import { InputCurrency } from "../../../../components/form/InputCurrency";
+import { InputSelector } from "../../../../components/form/InputSelector";
+import { useConfigContext } from "../../../../context/config";
+import { MerchantBackend } from "../../../../declaration";
+import { Translate, useTranslator } from "../../../../i18n";
+import { CROCKFORD_BASE32_REGEX, URL_REGEX } from 
"../../../../utils/constants";
+
+type Entity = MerchantBackend.Transfers.TransferInformation
+
+interface Props {
+  onCreate: (d: Entity) => Promise<void>;
+  onBack?: () => void;
+  accounts: string[],
+}
+
+export function CreatePage({ accounts, onCreate, onBack }: Props): VNode {
+  const i18n = useTranslator()
+  const { currency } = useConfigContext()
+
+  const [state, setState] = useState<Partial<Entity>>({
+    wtid: '',
+    // payto_uri: ,
+    // exchange_url: 'http://exchange.taler:8081/',
+    credit_amount: ``,
+  });
+
+  const errors: FormErrors<Entity> = {
+    wtid: !state.wtid ? i18n`cannot be empty` :
+      (!CROCKFORD_BASE32_REGEX.test(state.wtid) ? i18n`check the id, does not 
look valid` :
+        (state.wtid.length !== 52 ? i18n`should have 52 characters, current 
${state.wtid.length}` :
+          undefined)),
+    payto_uri: !state.payto_uri ? i18n`cannot be empty` : undefined,
+    credit_amount: !state.credit_amount ? i18n`cannot be empty` : undefined,
+    exchange_url: !state.exchange_url ? i18n`cannot be empty` :
+      (!URL_REGEX.test(state.exchange_url) ? i18n`URL doesn't have the right 
format` : undefined),
+  }
+
+  const hasErrors = Object.keys(errors).some(k => (errors as any)[k] !== 
undefined)
+
+  const submitForm = () => {
+    if (hasErrors) return Promise.reject()
+    return onCreate(state as any)
+  }
+
+  return <div>
+    <section class="section is-main-section">
+      <div class="columns">
+        <div class="column" />
+        <div class="column is-four-fifths">
+
+          <FormProvider object={state} valueHandler={setState} errors={errors}>
+            <InputSelector name="payto_uri" label={i18n`Credited bank account`}
+              values={accounts}
+              placeholder={i18n`Select one account`}
+              tooltip={i18n`Bank account of the merchant where the payment was 
received`}
+            />
+            <Input<Entity> name="wtid" label={i18n`Wire transfer ID`} help="" 
tooltip={i18n`unique identifier of the wire transfer used by the exchange, must 
be 52 characters long`} />
+            <Input<Entity> name="exchange_url"
+              label={i18n`Exchange URL`}
+              tooltip={i18n`Base URL of the exchange that made the transfer, 
should have been in the wire transfer subject`}
+              help="http://exchange.taler:8081/"; />
+            <InputCurrency<Entity> name="credit_amount" label={i18n`Amount 
credited`} tooltip={i18n`Actual amount that was wired to the merchant's bank 
account`} />
+
+          </FormProvider>
+
+          <div class="buttons is-right mt-5">
+            {onBack && <button class="button" onClick={onBack} 
><Translate>Cancel</Translate></button>}
+            <AsyncButton disabled={hasErrors} data-tooltip={
+              hasErrors ? i18n`Need to complete marked fields` : 'confirm 
operation'
+            } onClick={submitForm} 
><Translate>Confirm</Translate></AsyncButton>
+          </div>
+
+        </div>
+        <div class="column" />
+      </div>
+    </section>
+  </div>
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/transfers/create/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/create/index.tsx
new file mode 100644
index 000000000..d95929a0e
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/create/index.tsx
@@ -0,0 +1,60 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { Fragment, h, VNode } from 'preact';
+import { useState } from 'preact/hooks';
+import { NotificationCard } from '../../../../components/menu';
+import { MerchantBackend } from '../../../../declaration';
+import { useInstanceDetails } from '../../../../hooks/instance';
+import { useTransferAPI } from '../../../../hooks/transfer';
+import { useTranslator } from '../../../../i18n';
+import { Notification } from '../../../../utils/types';
+import { CreatePage } from './CreatePage';
+
+export type Entity = MerchantBackend.Transfers.TransferInformation
+interface Props {
+  onBack?: () => void;
+  onConfirm: () => void;
+}
+
+export default function CreateTransfer({onConfirm, onBack}:Props): VNode {
+  const { informTransfer } = useTransferAPI()
+  const [notif, setNotif] = useState<Notification | undefined>(undefined)
+  const i18n = useTranslator()
+  const instance = useInstanceDetails()
+  const accounts = !instance.ok ? [] : instance.data.accounts.map(a => 
a.payto_uri)
+
+  return <>
+    <NotificationCard notification={notif} />
+    <CreatePage
+      onBack={onBack}
+      accounts={accounts}
+      onCreate={(request: MerchantBackend.Transfers.TransferInformation) => {
+        return informTransfer(request).then(() => onConfirm()).catch((error) 
=> {
+          setNotif({
+            message: i18n`could not inform transfer`,
+            type: "ERROR",
+            description: error.message
+          })
+        })
+      }} />
+  </>
+}
\ No newline at end of file
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/List.stories.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/List.stories.tsx
new file mode 100644
index 000000000..24a791187
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/List.stories.tsx
@@ -0,0 +1,93 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { h, VNode, FunctionalComponent } from "preact";
+import { ListPage as TestedComponent } from "./ListPage";
+
+export default {
+  title: "Pages/Transfer/List",
+  component: TestedComponent,
+  argTypes: {
+    onCreate: { action: "onCreate" },
+    onDelete: { action: "onDelete" },
+    onLoadMoreBefore: { action: "onLoadMoreBefore" },
+    onLoadMoreAfter: { action: "onLoadMoreAfter" },
+    onShowAll: { action: "onShowAll" },
+    onShowVerified: { action: "onShowVerified" },
+    onShowUnverified: { action: "onShowUnverified" },
+    onChangePayTo: { action: "onChangePayTo" },
+  },
+};
+
+function createExample<Props>(
+  Component: FunctionalComponent<Props>,
+  props: Partial<Props>
+) {
+  const r = (args: any) => <Component {...args} />;
+  r.args = props;
+  return r;
+}
+
+export const Example = createExample(TestedComponent, {
+  transfers: [
+    {
+      exchange_url: "http://exchange.url/";,
+      credit_amount: "TESTKUDOS:10",
+      payto_uri: "payto//x-taler-bank/bank:8080/account",
+      transfer_serial_id: 123123123,
+      wtid: "!@KJELQKWEJ!L@K#!J@",
+      confirmed: true,
+      execution_time: {
+        t_s: new Date().getTime() / 1000,
+      },
+      verified: false,
+    },
+    {
+      exchange_url: "http://exchange.url/";,
+      credit_amount: "TESTKUDOS:10",
+      payto_uri: "payto//x-taler-bank/bank:8080/account",
+      transfer_serial_id: 123123123,
+      wtid: "!@KJELQKWEJ!L@K#!J@",
+      confirmed: true,
+      execution_time: {
+        t_s: new Date().getTime() / 1000,
+      },
+      verified: false,
+    },
+    {
+      exchange_url: "http://exchange.url/";,
+      credit_amount: "TESTKUDOS:10",
+      payto_uri: "payto//x-taler-bank/bank:8080/account",
+      transfer_serial_id: 123123123,
+      wtid: "!@KJELQKWEJ!L@K#!J@",
+      confirmed: true,
+      execution_time: {
+        t_s: new Date().getTime() / 1000,
+      },
+      verified: false,
+    },
+  ],
+  accounts: ["payto://x-taler-bank/bank/some_account"],
+});
+export const Empty = createExample(TestedComponent, {
+  transfers: [],
+  accounts: [],
+});
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/ListPage.tsx
 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/ListPage.tsx
new file mode 100644
index 000000000..544a720b8
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/ListPage.tsx
@@ -0,0 +1,89 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode } from 'preact';
+import { FormProvider } from '../../../../components/form/FormProvider';
+import { InputSelector } from '../../../../components/form/InputSelector';
+import { MerchantBackend } from '../../../../declaration';
+import { Translate, useTranslator } from '../../../../i18n';
+import { CardTable } from './Table';
+
+export interface Props {
+  transfers: MerchantBackend.Transfers.TransferDetails[];
+  onLoadMoreBefore?: () => void;
+  onLoadMoreAfter?: () => void;
+  onShowAll: () => void;
+  onShowVerified: () => void;
+  onShowUnverified: () => void;
+  isVerifiedTransfers?: boolean;
+  isNonVerifiedTransfers?: boolean;
+  isAllTransfers?: boolean;
+  accounts: string[];
+  onChangePayTo: (p?: string) => void;
+  payTo?: string;
+  onCreate: () => void;
+  onDelete: () => void;
+}
+
+export function ListPage({ payTo, onChangePayTo, transfers, onCreate, 
onDelete, accounts, onLoadMoreBefore, onLoadMoreAfter, isAllTransfers, 
isNonVerifiedTransfers, isVerifiedTransfers, onShowAll, onShowUnverified, 
onShowVerified }: Props): VNode {
+  const form = { payto_uri: payTo }
+
+  const i18n = useTranslator();
+  return <section class="section is-main-section">
+    <div class="columns">
+      <div class="column" />
+      <div class="column is-10">
+        <FormProvider object={form} valueHandler={(updater) => 
onChangePayTo(updater(form).payto_uri)}>
+          <InputSelector name="payto_uri" label={i18n`Address`}
+            values={accounts}
+            placeholder={i18n`Select one account`}
+            tooltip={i18n`filter by account address`} />
+        </FormProvider>
+      </div>
+      <div class="column" />
+    </div>
+    <div class="tabs">
+      <ul>
+        <li class={isAllTransfers ? 'is-active' : ''}>
+          <div class="has-tooltip-right" data-tooltip={i18n`remove all 
filters`}>
+            <a onClick={onShowAll}><Translate>All</Translate></a>
+          </div>
+        </li>
+        <li class={isVerifiedTransfers ? 'is-active' : ''}>
+          <div class="has-tooltip-right" data-tooltip={i18n`only show wire 
transfers confirmed by the merchant`}>
+            <a onClick={onShowVerified}><Translate>Verified</Translate></a>
+          </div>
+        </li>
+        <li class={isNonVerifiedTransfers ? 'is-active' : ''}>
+          <div class="has-tooltip-right" data-tooltip={i18n`only show wire 
transfers claimed by the exchange`}>
+            <a onClick={onShowUnverified}><Translate>Unverified</Translate></a>
+          </div>
+        </li>
+      </ul>
+    </div>
+    <CardTable transfers={transfers.map(o => ({ ...o, id: 
String(o.transfer_serial_id) }))}
+      accounts={accounts}
+      onCreate={onCreate}
+      onDelete={onDelete}
+      onLoadMoreBefore={onLoadMoreBefore} hasMoreBefore={!onLoadMoreBefore}
+      onLoadMoreAfter={onLoadMoreAfter} hasMoreAfter={!onLoadMoreAfter} />
+  </section>;
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/Table.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/Table.tsx
new file mode 100644
index 000000000..4cb04694d
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/Table.tsx
@@ -0,0 +1,225 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { format } from "date-fns";
+import { h, VNode } from "preact";
+import { StateUpdater, useState } from "preact/hooks";
+import { MerchantBackend, WithId } from "../../../../declaration";
+import { Translate, useTranslator } from "../../../../i18n";
+
+type Entity = MerchantBackend.Transfers.TransferDetails & WithId;
+
+interface Props {
+  transfers: Entity[];
+  onDelete: (id: Entity) => void;
+  onCreate: () => void;
+  accounts: string[];
+  onLoadMoreBefore?: () => void;
+  hasMoreBefore?: boolean;
+  hasMoreAfter?: boolean;
+  onLoadMoreAfter?: () => void;
+}
+
+export function CardTable({
+  transfers,
+  onCreate,
+  onDelete,
+  onLoadMoreAfter,
+  onLoadMoreBefore,
+  hasMoreAfter,
+  hasMoreBefore,
+}: Props): VNode {
+  const [rowSelection, rowSelectionHandler] = useState<string[]>([]);
+
+  const i18n = useTranslator();
+
+  return (
+    <div class="card has-table">
+      <header class="card-header">
+        <p class="card-header-title">
+          <span class="icon">
+            <i class="mdi mdi-bank" />
+          </span>
+          <Translate>Transfers</Translate>
+        </p>
+        <div class="card-header-icon" aria-label="more options">
+          <span class="has-tooltip-left" data-tooltip={i18n`add new transfer`}>
+            <button class="button is-info" type="button" onClick={onCreate}>
+              <span class="icon is-small">
+                <i class="mdi mdi-plus mdi-36px" />
+              </span>
+            </button>
+          </span>
+        </div>
+      </header>
+      <div class="card-content">
+        <div class="b-table has-pagination">
+          <div class="table-wrapper has-mobile-cards">
+            {transfers.length > 0 ? (
+              <Table
+                instances={transfers}
+                onDelete={onDelete}
+                rowSelection={rowSelection}
+                rowSelectionHandler={rowSelectionHandler}
+                onLoadMoreAfter={onLoadMoreAfter}
+                onLoadMoreBefore={onLoadMoreBefore}
+                hasMoreAfter={hasMoreAfter}
+                hasMoreBefore={hasMoreBefore}
+              />
+            ) : (
+              <EmptyTable />
+            )}
+          </div>
+        </div>
+      </div>
+    </div>
+  );
+}
+interface TableProps {
+  rowSelection: string[];
+  instances: Entity[];
+  onDelete: (id: Entity) => void;
+  rowSelectionHandler: StateUpdater<string[]>;
+  onLoadMoreBefore?: () => void;
+  hasMoreBefore?: boolean;
+  hasMoreAfter?: boolean;
+  onLoadMoreAfter?: () => void;
+}
+
+function toggleSelected<T>(id: T): (prev: T[]) => T[] {
+  return (prev: T[]): T[] =>
+    prev.indexOf(id) == -1 ? [...prev, id] : prev.filter((e) => e != id);
+}
+
+function Table({
+  instances,
+  onLoadMoreAfter,
+  onDelete,
+  onLoadMoreBefore,
+  hasMoreAfter,
+  hasMoreBefore,
+}: TableProps): VNode {
+  const i18n = useTranslator();
+  return (
+    <div class="table-container">
+      {onLoadMoreBefore && (
+        <button
+          class="button is-fullwidth"
+          data-tooltip={i18n`load more transfers before the first one`}
+          disabled={!hasMoreBefore}
+          onClick={onLoadMoreBefore}
+        >
+          <Translate>load newer transfers</Translate>
+        </button>
+      )}
+      <table class="table is-fullwidth is-striped is-hoverable is-fullwidth">
+        <thead>
+          <tr>
+            <th>
+              <Translate>ID</Translate>
+            </th>
+            <th>
+              <Translate>Credit</Translate>
+            </th>
+            <th>
+              <Translate>Address</Translate>
+            </th>
+            <th>
+              <Translate>Exchange URL</Translate>
+            </th>
+            <th>
+              <Translate>Confirmed</Translate>
+            </th>
+            <th>
+              <Translate>Verified</Translate>
+            </th>
+            <th>
+              <Translate>Executed at</Translate>
+            </th>
+            <th />
+          </tr>
+        </thead>
+        <tbody>
+          {instances.map((i) => {
+            return (
+              <tr key={i.id}>
+                <td>{i.id}</td>
+                <td>{i.credit_amount}</td>
+                <td>{i.payto_uri}</td>
+                <td>{i.exchange_url}</td>
+                <td>{i.confirmed ? i18n`yes` : i18n`no`}</td>
+                <td>{i.verified ? i18n`yes` : i18n`no`}</td>
+                <td>
+                  {i.execution_time
+                    ? i.execution_time.t_s == "never"
+                      ? i18n`never`
+                      : format(
+                          i.execution_time.t_s * 1000,
+                          "yyyy/MM/dd HH:mm:ss"
+                        )
+                    : i18n`unknown`}
+                </td>
+                <td>
+                  {i.verified === undefined ? (
+                    <button
+                      class="button is-danger is-small has-tooltip-left"
+                      data-tooltip={i18n`delete selected transfer from the 
database`}
+                      onClick={() => onDelete(i)}
+                    >
+                      Delete
+                    </button>
+                  ) : undefined}
+                </td>
+              </tr>
+            );
+          })}
+        </tbody>
+      </table>
+      {onLoadMoreAfter && (
+        <button
+          class="button is-fullwidth"
+          data-tooltip={i18n`load more transfer after the last one`}
+          disabled={!hasMoreAfter}
+          onClick={onLoadMoreAfter}
+        >
+          <Translate>load older transfers</Translate>
+        </button>
+      )}
+    </div>
+  );
+}
+
+function EmptyTable(): VNode {
+  return (
+    <div class="content has-text-grey has-text-centered">
+      <p>
+        <span class="icon is-large">
+          <i class="mdi mdi-emoticon-sad mdi-48px" />
+        </span>
+      </p>
+      <p>
+        <Translate>
+          There is no transfer yet, add more pressing the + sign
+        </Translate>
+      </p>
+    </div>
+  );
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/index.tsx
new file mode 100644
index 000000000..d8e2f60e9
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/index.tsx
@@ -0,0 +1,85 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode } from 'preact';
+import { useState } from 'preact/hooks';
+import { Loading } from '../../../../components/exception/loading';
+import { MerchantBackend } from '../../../../declaration';
+import { HttpError } from '../../../../hooks/backend';
+import { useInstanceDetails } from '../../../../hooks/instance';
+import { useInstanceTransfers } from "../../../../hooks/transfer";
+import { ListPage } from './ListPage';
+
+interface Props {
+  onUnauthorized: () => VNode;
+  onLoadError: (error: HttpError) => VNode;
+  onNotFound: () => VNode;
+  onCreate: () => void;
+}
+interface Form {
+  verified?: 'yes' | 'no';
+  payto_uri?: string;
+}
+
+export default function ListTransfer({ onUnauthorized, onLoadError, onCreate, 
onNotFound }: Props): VNode {
+  const [form, setForm] = useState<Form>({ payto_uri: '' })
+  const setFilter = (s?: 'yes' | 'no') => setForm({ ...form, verified: s })
+
+  const [position, setPosition] = useState<string | undefined>(undefined)
+
+  const instance = useInstanceDetails()
+  const accounts = !instance.ok ? [] : instance.data.accounts.map(a => 
a.payto_uri)
+
+  const isVerifiedTransfers = form.verified === 'yes'
+  const isNonVerifiedTransfers = form.verified === 'no'
+  const isAllTransfers = form.verified === undefined
+
+  const result = useInstanceTransfers({
+    position,
+    payto_uri: form.payto_uri === '' ? undefined : form.payto_uri,
+    verified: form.verified,
+  }, (id) => setPosition(id))
+
+  if (result.clientError && result.isUnauthorized) return onUnauthorized()
+  if (result.clientError && result.isNotfound) return onNotFound()
+  if (result.loading) return <Loading />
+  if (!result.ok) return onLoadError(result)
+
+  return <ListPage
+    accounts={accounts}
+    transfers={result.data.transfers}
+    onLoadMoreBefore={result.isReachingStart ? result.loadMorePrev : undefined}
+    onLoadMoreAfter={result.isReachingEnd ? result.loadMore : undefined}
+    onCreate={onCreate} 
+    onDelete={() => {null}}
+    // position={position} setPosition={setPosition}
+    onShowAll={() => setFilter(undefined)}
+    onShowUnverified={() => setFilter('no')}
+    onShowVerified={() => setFilter('yes')}
+    isAllTransfers={isAllTransfers}
+    isVerifiedTransfers={isVerifiedTransfers}
+    isNonVerifiedTransfers={isNonVerifiedTransfers}
+    payTo={form.payto_uri}
+    onChangePayTo={(p) => setForm(v => ({ ...v, payto_uri: p }))}
+  />
+
+}
+
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/transfers/update/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/update/index.tsx
new file mode 100644
index 000000000..caa808693
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/transfers/update/index.tsx
@@ -0,0 +1,26 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { h, VNode } from 'preact';
+
+export default function UpdateTransfer():VNode {
+  return <div>order transfer page</div>
+}
\ No newline at end of file
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/update/Update.stories.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/update/Update.stories.tsx
new file mode 100644
index 000000000..3239d9c5c
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/paths/instance/update/Update.stories.tsx
@@ -0,0 +1,61 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { h, VNode, FunctionalComponent } from "preact";
+import { UpdatePage as TestedComponent } from "./UpdatePage";
+
+export default {
+  title: "Pages/Instance/Update",
+  component: TestedComponent,
+  argTypes: {
+    onUpdate: { action: "onUpdate" },
+    onBack: { action: "onBack" },
+  },
+};
+
+function createExample<Props>(
+  Component: FunctionalComponent<Props>,
+  props: Partial<Props>
+) {
+  const r = (args: any) => <Component {...args} />;
+  r.args = props;
+  return r;
+}
+
+export const Example = createExample(TestedComponent, {
+  selected: {
+    accounts: [],
+    name: "name",
+    auth: { method: "external" },
+    address: {},
+    jurisdiction: {},
+    default_max_deposit_fee: "TESTKUDOS:2",
+    default_max_wire_fee: "TESTKUDOS:1",
+    default_pay_delay: {
+      d_us: 1000000,
+    },
+    default_wire_fee_amortization: 1,
+    default_wire_transfer_delay: {
+      d_us: 100000,
+    },
+    merchant_pub: "ASDWQEKASJDKSADJ",
+  },
+});
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx
new file mode 100644
index 000000000..4c7a51121
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx
@@ -0,0 +1,259 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import * as yup from "yup";
+import { AsyncButton } from "../../../components/exception/AsyncButton";
+import {
+  FormProvider,
+  FormErrors,
+} from "../../../components/form/FormProvider";
+import { UpdateTokenModal } from "../../../components/modal";
+import { useInstanceContext } from "../../../context/instance";
+import { MerchantBackend } from "../../../declaration";
+import { Translate, useTranslator } from "../../../i18n";
+import { InstanceUpdateSchema as schema } from "../../../schemas";
+import { DefaultInstanceFormFields } from 
"../../../components/instance/DefaultInstanceFormFields";
+import { PAYTO_REGEX } from "../../../utils/constants";
+import { Amounts } from "@gnu-taler/taler-util";
+
+type Entity = MerchantBackend.Instances.InstanceReconfigurationMessage & {
+  auth_token?: string;
+};
+
+//MerchantBackend.Instances.InstanceAuthConfigurationMessage
+interface Props {
+  onUpdate: (d: Entity) => void;
+  onChangeAuth: (
+    d: MerchantBackend.Instances.InstanceAuthConfigurationMessage
+  ) => Promise<void>;
+  selected: MerchantBackend.Instances.QueryInstancesResponse;
+  isLoading: boolean;
+  onBack: () => void;
+}
+
+function convert(
+  from: MerchantBackend.Instances.QueryInstancesResponse
+): Entity {
+  const { accounts, ...rest } = from;
+  const payto_uris = accounts.filter((a) => a.active).map((a) => a.payto_uri);
+  const defaults = {
+    default_wire_fee_amortization: 1,
+    default_pay_delay: { d_us: 2 * 1000 * 1000 * 60 * 60 }, //two hours
+    default_wire_transfer_delay: { d_us: 2 * 1000 * 1000 * 60 * 60 * 2 }, 
//two hours
+  };
+  return { ...defaults, ...rest, payto_uris };
+}
+
+function getTokenValuePart(t?: string): string | undefined {
+  if (!t) return t;
+  const match = /secret-token:(.*)/.exec(t);
+  if (!match || !match[1]) return undefined;
+  return match[1];
+}
+
+function undefinedIfEmpty<T>(obj: T): T | undefined {
+  return Object.keys(obj).some((k) => (obj as any)[k] !== undefined)
+    ? obj
+    : undefined;
+}
+
+export function UpdatePage({
+  onUpdate,
+  onChangeAuth,
+  selected,
+  onBack,
+}: Props): VNode {
+  const { id, token } = useInstanceContext();
+  const currentTokenValue = getTokenValuePart(token);
+
+  function updateToken(token: string | undefined | null) {
+    const value =
+      token && token.startsWith("secret-token:")
+        ? token.substring("secret-token:".length)
+        : token;
+
+    if (!token) {
+      onChangeAuth({ method: "external" });
+    } else {
+      onChangeAuth({ method: "token", token: `secret-token:${value}` });
+    }
+  }
+
+  const [value, valueHandler] = useState<Partial<Entity>>(convert(selected));
+
+  const i18n = useTranslator();
+
+  const errors: FormErrors<Entity> = {
+    name: !value.name ? i18n`required` : undefined,
+    payto_uris:
+      !value.payto_uris || !value.payto_uris.length
+        ? i18n`required`
+        : undefinedIfEmpty(
+            value.payto_uris.map((p) => {
+              return !PAYTO_REGEX.test(p) ? i18n`is not valid` : undefined;
+            })
+          ),
+    default_max_deposit_fee: !value.default_max_deposit_fee
+      ? i18n`required`
+      : !Amounts.parse(value.default_max_deposit_fee)
+      ? i18n`invalid format`
+      : undefined,
+    default_max_wire_fee: !value.default_max_wire_fee
+      ? i18n`required`
+      : !Amounts.parse(value.default_max_wire_fee)
+      ? i18n`invalid format`
+      : undefined,
+    default_wire_fee_amortization:
+      value.default_wire_fee_amortization === undefined
+        ? i18n`required`
+        : isNaN(value.default_wire_fee_amortization)
+        ? i18n`is not a number`
+        : value.default_wire_fee_amortization < 1
+        ? i18n`must be 1 or greater`
+        : undefined,
+    default_pay_delay: !value.default_pay_delay ? i18n`required` : undefined,
+    default_wire_transfer_delay: !value.default_wire_transfer_delay
+      ? i18n`required`
+      : undefined,
+    address: undefinedIfEmpty({
+      address_lines:
+        value.address?.address_lines && value.address?.address_lines.length > 7
+          ? i18n`max 7 lines`
+          : undefined,
+    }),
+    jurisdiction: undefinedIfEmpty({
+      address_lines:
+        value.address?.address_lines && value.address?.address_lines.length > 7
+          ? i18n`max 7 lines`
+          : undefined,
+    }),
+  };
+
+  const hasErrors = Object.keys(errors).some(
+    (k) => (errors as any)[k] !== undefined
+  );
+  const submit = async (): Promise<void> => {
+    await onUpdate(value as Entity);
+  };
+  const [active, setActive] = useState(false);
+
+  return (
+    <div>
+      <section class="section">
+        <section class="hero is-hero-bar">
+          <div class="hero-body">
+            <div class="level">
+              <div class="level-left">
+                <div class="level-item">
+                  <span class="is-size-4">
+                    <Translate>Instance id</Translate>: <b>{id}</b>
+                  </span>
+                </div>
+              </div>
+              <div class="level-right">
+                <div class="level-item">
+                  <h1 class="title">
+                    <button
+                      class="button is-danger"
+                      data-tooltip={i18n`Change the authorization method use 
for this instance.`}
+                      onClick={(): void => {
+                        setActive(!active);
+                      }}
+                    >
+                      <div class="icon is-left">
+                        <i class="mdi mdi-lock-reset" />
+                      </div>
+                      <span>
+                        <Translate>Manage access token</Translate>
+                      </span>
+                    </button>
+                  </h1>
+                </div>
+              </div>
+            </div>
+          </div>
+        </section>
+
+        <div class="columns">
+          <div class="column" />
+          <div class="column is-four-fifths">
+            {active && (
+              <UpdateTokenModal
+                oldToken={currentTokenValue}
+                onCancel={() => {
+                  setActive(false);
+                }}
+                onClear={() => {
+                  updateToken(null);
+                  setActive(false);
+                }}
+                onConfirm={(newToken) => {
+                  updateToken(newToken);
+                  setActive(false);
+                }}
+              />
+            )}
+          </div>
+          <div class="column" />
+        </div>
+        <hr />
+
+        <div class="columns">
+          <div class="column" />
+          <div class="column is-four-fifths">
+            <FormProvider<Entity>
+              errors={errors}
+              object={value}
+              valueHandler={valueHandler}
+            >
+              <DefaultInstanceFormFields showId={false} />
+            </FormProvider>
+
+            <div class="buttons is-right mt-4">
+              <button
+                class="button"
+                onClick={onBack}
+                data-tooltip="cancel operation"
+              >
+                <Translate>Cancel</Translate>
+              </button>
+
+              <AsyncButton
+                onClick={submit}
+                data-tooltip={
+                  hasErrors
+                    ? i18n`Need to complete marked fields`
+                    : "confirm operation"
+                }
+                disabled={hasErrors}
+              >
+                <Translate>Confirm</Translate>
+              </AsyncButton>
+            </div>
+          </div>
+          <div class="column" />
+        </div>
+      </section>
+    </div>
+  );
+}
diff --git 
a/packages/merchant-backoffice-ui/src/paths/instance/update/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/instance/update/index.tsx
new file mode 100644
index 000000000..bd5f4c727
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/paths/instance/update/index.tsx
@@ -0,0 +1,113 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+import { Fragment, h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { Loading } from "../../../components/exception/loading";
+import { NotificationCard } from "../../../components/menu";
+import { useInstanceContext } from "../../../context/instance";
+import { MerchantBackend } from "../../../declaration";
+import { HttpError, HttpResponse } from "../../../hooks/backend";
+import {
+  useInstanceAPI,
+  useInstanceDetails,
+  useManagedInstanceDetails,
+  useManagementAPI,
+} from "../../../hooks/instance";
+import { useTranslator } from "../../../i18n";
+import { Notification } from "../../../utils/types";
+import { UpdatePage } from "./UpdatePage";
+
+export interface Props {
+  onBack: () => void;
+  onConfirm: () => void;
+
+  onUnauthorized: () => VNode;
+  onNotFound: () => VNode;
+  onLoadError: (e: HttpError) => VNode;
+  onUpdateError: (e: HttpError) => void;
+}
+
+export default function Update(props: Props): VNode {
+  const { updateInstance, clearToken, setNewToken } = useInstanceAPI();
+  const result = useInstanceDetails();
+  return CommonUpdate(props, result, updateInstance, clearToken, setNewToken);
+}
+
+export function AdminUpdate(props: Props & { instanceId: string }): VNode {
+  const { updateInstance, clearToken, setNewToken } = useManagementAPI(
+    props.instanceId
+  );
+  const result = useManagedInstanceDetails(props.instanceId);
+  return CommonUpdate(props, result, updateInstance, clearToken, setNewToken);
+}
+
+function CommonUpdate(
+  {
+    onBack,
+    onConfirm,
+    onLoadError,
+    onNotFound,
+    onUpdateError,
+    onUnauthorized,
+  }: Props,
+  result: HttpResponse<MerchantBackend.Instances.QueryInstancesResponse>,
+  updateInstance: any,
+  clearToken: any,
+  setNewToken: any
+): VNode {
+  const { changeToken } = useInstanceContext();
+  const [notif, setNotif] = useState<Notification | undefined>(undefined);
+  const i18n = useTranslator();
+
+  if (result.clientError && result.isUnauthorized) return onUnauthorized();
+  if (result.clientError && result.isNotfound) return onNotFound();
+  if (result.loading) return <Loading />;
+  if (!result.ok) return onLoadError(result);
+
+  return (
+    <Fragment>
+      <NotificationCard notification={notif} />
+      <UpdatePage
+        onBack={onBack}
+        isLoading={false}
+        selected={result.data}
+        onUpdate={(
+          d: MerchantBackend.Instances.InstanceReconfigurationMessage
+        ): Promise<void> => {
+          return updateInstance(d)
+            .then(onConfirm)
+            .catch((error: Error) =>
+              setNotif({
+                message: i18n`Failed to create instance`,
+                type: "ERROR",
+                description: error.message,
+              })
+            );
+        }}
+        onChangeAuth={(
+          d: MerchantBackend.Instances.InstanceAuthConfigurationMessage
+        ): Promise<void> => {
+          const apiCall =
+            d.method === "external" ? clearToken() : setNewToken(d.token!);
+          return apiCall
+            .then(() => changeToken(d.token))
+            .then(onConfirm)
+            .catch(onUpdateError);
+        }}
+      />
+    </Fragment>
+  );
+}
diff --git a/packages/merchant-backoffice-ui/src/paths/login/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/login/index.tsx
new file mode 100644
index 000000000..acad7fe0b
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/paths/login/index.tsx
@@ -0,0 +1,29 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import { h, VNode } from "preact";
+import { LoginModal } from '../../components/exception/login';
+
+interface Props {
+  onConfirm: (url: string, token?: string) => void;
+}
+export default function LoginPage({ onConfirm }: Props): VNode {
+  return <LoginModal onConfirm={onConfirm} />
+} 
\ No newline at end of file
diff --git a/packages/merchant-backoffice-ui/src/paths/notfound/index.tsx 
b/packages/merchant-backoffice-ui/src/paths/notfound/index.tsx
new file mode 100644
index 000000000..10c3fac25
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/paths/notfound/index.tsx
@@ -0,0 +1,36 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { h, VNode } from 'preact';
+import { Link } from 'preact-router/match';
+
+export default function NotFoundPage(): VNode {
+    return (
+        <div>
+            <h1>Error 404</h1>
+            <p>That page doesn&apos;t exist.</p>
+            <Link href="/">
+                <h4>Back to Home</h4>
+            </Link>
+        </div>
+    );
+}
+
diff --git a/packages/merchant-backoffice-ui/src/schemas/index.ts 
b/packages/merchant-backoffice-ui/src/schemas/index.ts
new file mode 100644
index 000000000..00e80199a
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/schemas/index.ts
@@ -0,0 +1,202 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { isAfter, isFuture } from 'date-fns';
+import * as yup from 'yup';
+import { AMOUNT_REGEX, PAYTO_REGEX } from "../utils/constants";
+
+yup.setLocale({
+  mixed: {
+    default: 'field_invalid',
+  },
+  number: {
+    min: ({ min }: any) => ({ key: 'field_too_short', values: { min } }),
+    max: ({ max }: any) => ({ key: 'field_too_big', values: { max } }),
+  },
+});
+
+function listOfPayToUrisAreValid(values?: (string | undefined)[]): boolean {
+  return !!values && values.every(v => v && PAYTO_REGEX.test(v));
+}
+
+function currencyWithAmountIsValid(value?: string): boolean {
+  return !!value && AMOUNT_REGEX.test(value)
+}
+function currencyGreaterThan0(value?: string) {
+  if (value) {
+    try {
+      const [, amount] = value.split(':')
+      const intAmount = parseInt(amount, 10)
+      return intAmount > 0
+    } catch {
+      return false
+    }
+  }
+  return true
+}
+
+export const InstanceSchema = yup.object().shape({
+  id: yup.string().required().meta({ type: 'url' }),
+  name: yup.string().required(),
+  auth: yup.object().shape({
+    method: yup.string().matches(/^(external|token)$/),
+    token: yup.string().optional().nullable(),
+  }),
+  payto_uris: yup.array().of(yup.string())
+    .min(1)
+    .meta({ type: 'array' })
+    .test('payto', '{path} is not valid', listOfPayToUrisAreValid),
+  default_max_deposit_fee: yup.string()
+    .required()
+    .test('amount', 'the amount is not valid', currencyWithAmountIsValid)
+    .meta({ type: 'amount' }),
+  default_max_wire_fee: yup.string()
+    .required()
+    .test('amount', '{path} is not valid', currencyWithAmountIsValid)
+    .meta({ type: 'amount' }),
+  default_wire_fee_amortization: yup.number()
+    .required(),
+  address: yup.object().shape({
+    country: yup.string().optional(),
+    address_lines: yup.array().of(yup.string()).max(7).optional(),
+    building_number: yup.string().optional(),
+    building_name: yup.string().optional(),
+    street: yup.string().optional(),
+    post_code: yup.string().optional(),
+    town_location: yup.string().optional(),
+    town: yup.string(),
+    district: yup.string().optional(),
+    country_subdivision: yup.string().optional(),
+  }).meta({ type: 'group' }),
+  jurisdiction: yup.object().shape({
+    country: yup.string().optional(),
+    address_lines: yup.array().of(yup.string()).max(7).optional(),
+    building_number: yup.string().optional(),
+    building_name: yup.string().optional(),
+    street: yup.string().optional(),
+    post_code: yup.string().optional(),
+    town_location: yup.string().optional(),
+    town: yup.string(),
+    district: yup.string().optional(),
+    country_subdivision: yup.string().optional(),
+  }).meta({ type: 'group' }),
+  // default_pay_delay: yup.object()
+  //   .shape({ d_us: yup.number() })
+  //   .required()
+  //   .meta({ type: 'duration' }),
+  // .transform(numberToDuration),
+  default_wire_transfer_delay: yup.object()
+    .shape({ d_us: yup.number() })
+    .required()
+    .meta({ type: 'duration' }),
+  // .transform(numberToDuration),
+})
+
+export const InstanceUpdateSchema = InstanceSchema.clone().omit(['id']);
+export const InstanceCreateSchema = InstanceSchema.clone();
+
+export const AuthorizeTipSchema = yup.object().shape({
+  justification: yup.string().required(),
+  amount: yup.string()
+    .required()
+    .test('amount', 'the amount is not valid', currencyWithAmountIsValid)
+    .test('amount_positive', 'the amount is not valid', currencyGreaterThan0),
+  next_url: yup.string().required(),
+})
+
+const stringIsValidJSON = (value?: string) => {
+  const p = value?.trim()
+  if (!p) return true;
+  try {
+    JSON.parse(p)
+    return true
+  } catch {
+    return false
+  }
+}
+
+export const OrderCreateSchema = yup.object().shape({
+  pricing: yup.object().required().shape({
+    summary: yup.string().ensure().required(),
+    order_price: yup.string()
+      .ensure()
+      .required()
+      .test('amount', 'the amount is not valid', currencyWithAmountIsValid)
+      .test('amount_positive', 'the amount should be greater than 0', 
currencyGreaterThan0),
+  }),
+  extra: yup.string().test('extra', 'is not a JSON format', stringIsValidJSON),
+  payments: yup.object().required().shape({
+    refund_deadline: yup.date()
+      .test('future', 'should be in the future', (d) => d ? isFuture(d) : 
true),
+    pay_deadline: yup.date()
+      .test('future', 'should be in the future', (d) => d ? isFuture(d) : 
true),
+    auto_refund_deadline: yup.date()
+      .test('future', 'should be in the future', (d) => d ? isFuture(d) : 
true),
+    delivery_date: yup.date()
+      .test('future', 'should be in the future', (d) => d ? isFuture(d) : 
true),
+  }).test('payment', 'dates', (d) => {
+    if (d.pay_deadline && d.refund_deadline && isAfter(d.refund_deadline, 
d.pay_deadline)) {
+      return new yup.ValidationError('pay deadline should be greater than 
refund', 'asd', 'payments.pay_deadline')
+    }
+    return true
+  })
+})
+
+export const ProductCreateSchema = yup.object().shape({
+  product_id: yup.string().ensure().required(),
+  description: yup.string().required(),
+  unit: yup.string().ensure().required(),
+  price: yup.string()
+    .required()
+    .test('amount', 'the amount is not valid', currencyWithAmountIsValid),
+  stock: yup.object({
+
+  }).optional(),
+  minimum_age: yup.number().optional().min(0),
+})
+
+export const ProductUpdateSchema = yup.object().shape({
+  description: yup.string().required(),
+  price: yup.string()
+    .required()
+    .test('amount', 'the amount is not valid', currencyWithAmountIsValid),
+  stock: yup.object({
+
+  }).optional(),
+  minimum_age: yup.number().optional().min(0),
+})
+
+
+export const TaxSchema = yup.object().shape({
+  name: yup.string().required().ensure(),
+  tax: yup.string()
+    .required()
+    .test('amount', 'the amount is not valid', currencyWithAmountIsValid),
+})
+
+export const NonInventoryProductSchema = yup.object().shape({
+  quantity: yup.number().required().positive(),
+  description: yup.string().required(),
+  unit: yup.string().ensure().required(),
+  price: yup.string()
+    .required()
+    .test('amount', 'the amount is not valid', currencyWithAmountIsValid),
+})
diff --git a/packages/merchant-backoffice-ui/src/scss/DurationPicker.scss 
b/packages/merchant-backoffice-ui/src/scss/DurationPicker.scss
new file mode 100644
index 000000000..a35575324
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/scss/DurationPicker.scss
@@ -0,0 +1,71 @@
+
+.rdp-picker {
+  display: flex;
+  height: 175px;
+}
+
+@media (max-width: 400px) {
+  .rdp-picker {
+    width: 250px;
+  }
+}
+
+.rdp-masked-div {
+  overflow: hidden;
+  height: 175px;
+  position: relative;
+}
+
+.rdp-column-container {
+  flex-grow: 1;
+  display: inline-block;
+}
+
+.rdp-column {
+  position: absolute;
+  z-index: 0;
+  width: 100%;
+}
+
+.rdp-reticule {
+  border: 0;
+  border-top: 2px solid rgba(109, 202, 236, 1);
+  height: 2px;
+  position: absolute;
+  width: 80%;
+  margin: 0;
+  z-index: 100;
+  left: 50%;
+  -webkit-transform: translateX(-50%);
+  transform: translateX(-50%);
+}
+
+.rdp-text-overlay {
+  position: absolute;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  height: 35px;
+  font-size: 20px;
+  left: 50%;
+  -webkit-transform: translateX(-50%);
+  transform: translateX(-50%);
+}
+
+.rdp-cell div {
+  font-size: 17px;
+  color: gray;
+  font-style: italic;
+}
+
+.rdp-cell {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  height: 35px;
+  font-size: 18px;
+}
+
+.rdp-center {
+  font-size: 25px;
+}
diff --git a/packages/merchant-backoffice-ui/src/scss/_aside.scss 
b/packages/merchant-backoffice-ui/src/scss/_aside.scss
new file mode 100644
index 000000000..22258acf8
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/scss/_aside.scss
@@ -0,0 +1,179 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+@include desktop {
+  html {
+    &.has-aside-left {
+      &.has-aside-expanded {
+        nav.navbar, body {
+          padding-left: $aside-width;
+        }
+      }
+      aside.is-placed-left {
+        display: block;
+      }
+    }
+  }
+
+  aside.aside.is-expanded {
+    width: $aside-width;
+
+    .menu-list {
+      @include icon-with-update-mark($aside-icon-width);
+
+      span.menu-item-label {
+        display: inline-block;
+      }
+
+      li.is-active {
+        ul {
+          display: block;
+        }
+      }
+    }
+  }
+}
+
+aside.aside {
+  display: none;
+  position: fixed;
+  top: 0;
+  left: 0;
+  z-index: 40;
+  height: 100vh;
+  padding: 0;
+  box-shadow: $aside-box-shadow;
+  background: $aside-background-color;
+
+  .aside-tools {
+    display: flex;
+    flex-direction: row;
+    width: 100%;
+    background-color: $aside-tools-background-color;
+    color: $aside-tools-color;
+    line-height: $navbar-height;
+    height: $navbar-height;
+    padding-left: $default-padding * .5;
+    flex: 1;
+
+    .icon {
+      margin-right: $default-padding * .5;
+    }
+  }
+
+  .menu-list {
+    li {
+      a {
+        &.has-dropdown-icon {
+          position: relative;
+          padding-right: $aside-icon-width;
+
+          .dropdown-icon {
+            position: absolute;
+            top: $size-base * .5;
+            right: 0;
+          }
+        }
+      }
+      ul {
+        display: none;
+        border-left: 0;
+        background-color: darken($base-color, 2.5%);
+        padding-left: 0;
+        margin: 0 0 $default-padding * .5;
+
+        li {
+          a {
+            padding: $default-padding * .5 0 $default-padding * .5 
$default-padding * .5;
+            font-size: $aside-submenu-font-size;
+
+            &.has-icon {
+              padding-left: 0;
+            }
+            &.is-active {
+              &:not(:hover) {
+                background: transparent;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  .menu-label {
+    padding: 0 $default-padding * .5;
+    margin-top: $default-padding * .5;
+    margin-bottom: $default-padding * .5;
+  }
+
+}
+
+@include touch {
+   nav.navbar {
+    @include transition(margin-left);
+  }
+  aside.aside {
+    @include transition(left);
+  }
+  html.has-aside-mobile-transition {
+    body {
+      overflow-x: hidden;
+    }
+    body,  nav.navbar {
+      width: 100vw;
+    }
+    aside.aside {
+      width: $aside-mobile-width;
+      display: block;
+      left: $aside-mobile-width * -1;
+
+      .image {
+        img {
+          max-width: $aside-mobile-width * .33;
+        }
+      }
+
+      .menu-list {
+        li.is-active {
+          ul {
+            display: block;
+          }
+        }
+        a {
+          @include icon-with-update-mark($aside-icon-width);
+
+          span.menu-item-label {
+            display: inline-block;
+          }
+        }
+      }
+    }
+  }
+  div.has-aside-mobile-expanded {
+    nav.navbar {
+      margin-left: $aside-mobile-width;
+    }
+    aside.aside {
+      left: 0;
+    }
+  }
+}
diff --git a/packages/merchant-backoffice-ui/src/scss/_card.scss 
b/packages/merchant-backoffice-ui/src/scss/_card.scss
new file mode 100644
index 000000000..b2eec27a1
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/scss/_card.scss
@@ -0,0 +1,69 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+.card:not(:last-child) {
+  margin-bottom: $default-padding;
+}
+
+.card {
+  border-radius: $radius-large;
+  border: $card-border;
+
+  &.has-table {
+    .card-content {
+      padding: 0;
+    }
+    .b-table {
+      border-radius: $radius-large;
+      overflow: hidden;
+    }
+  }
+
+  &.is-card-widget {
+    .card-content {
+      padding: $default-padding * .5;
+    }
+  }
+
+  .card-header {
+    border-bottom: 1px solid $base-color-light;
+  }
+
+  .card-content {
+    hr {
+      margin-left: $card-content-padding * -1;
+      margin-right: $card-content-padding * -1;
+    }
+  }
+
+  .is-widget-icon {
+    .icon {
+      width: 5rem;
+      height: 5rem;
+    }
+  }
+
+  .is-widget-label {
+    .subtitle {
+      color: $grey;
+    }
+  }
+}
diff --git a/packages/merchant-backoffice-ui/src/scss/_custom-calendar.scss 
b/packages/merchant-backoffice-ui/src/scss/_custom-calendar.scss
new file mode 100644
index 000000000..9ac877ce0
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/scss/_custom-calendar.scss
@@ -0,0 +1,254 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+:root {
+  --primary-color: #3298dc;
+  
+  --primary-text-color-dark: rgba(0,0,0,.87);
+  --secondary-text-color-dark: rgba(0,0,0,.57);
+  --disabled-text-color-dark: rgba(0,0,0,.13);
+  
+  --primary-text-color-light: rgba(255,255,255,.87);
+  --secondary-text-color-light: rgba(255,255,255,.57);
+  --disabled-text-color-light: rgba(255,255,255,.13);
+  
+  --font-stack: 'Roboto', 'Helvetica Neue', Helvetica, Arial, sans-serif;
+  
+  --primary-card-color: #fff;
+  --primary-background-color: #f2f2f2;
+  
+  --box-shadow-lvl-1: 0 1px 3px rgba(0, 0, 0, 0.12),
+                      0 1px 2px rgba(0, 0, 0, 0.24);
+  --box-shadow-lvl-2: 0 3px 6px rgba(0, 0, 0, 0.16),
+                      0 3px 6px rgba(0, 0, 0, 0.23);
+  --box-shadow-lvl-3: 0 10px 20px rgba(0, 0, 0, 0.19),
+                      0 6px 6px rgba(0, 0, 0, 0.23);
+  --box-shadow-lvl-4: 0 14px 28px rgba(0, 0, 0, 0.25),
+                      0 10px 10px rgba(0, 0, 0, 0.22);
+}
+
+
+.datePicker {
+  text-align: left;
+  background: var(--primary-card-color);
+  border-radius: 3px;
+  z-index: 200;
+  position: fixed;
+  height: auto;
+  max-height: 90vh;
+  width: 90vw;
+  max-width: 448px;
+  transform-origin: top left;
+  transition: transform .22s ease-in-out, opacity .22s ease-in-out;
+  top: 50%;
+  left: 50%;
+  opacity: 0;
+  transform: scale(0) translate(-50%, -50%);
+  user-select: none;
+
+  &.datePicker--opened {
+    opacity: 1;
+    transform: scale(1) translate(-50%, -50%);
+  }
+  
+  .datePicker--titles {
+    border-top-left-radius: 3px;
+    border-top-right-radius: 3px;
+    padding: 24px;
+    height: 100px;
+    background: var(--primary-color);
+
+    h2, h3 {
+      cursor: pointer;
+      color: #fff;
+      line-height: 1;
+      padding: 0;
+      margin: 0;
+      font-size: 32px;
+    }
+
+    h3 {
+      color: rgba(255,255,255,.57);
+      font-size: 18px;
+      padding-bottom: 2px;
+    }
+  }
+
+  nav {
+    padding: 20px;
+    height: 56px;
+
+    h4 {
+      width: calc(100% - 60px);
+      text-align: center;
+      display: inline-block;
+      padding: 0;
+      font-size: 14px;
+      line-height: 24px;
+      margin: 0;
+      position: relative;
+      top: -9px;
+      color: var(--primary-text-color);
+    }
+
+    i {
+      cursor: pointer;
+      color: var(--secondary-text-color);
+      font-size: 26px;
+      user-select: none;
+      border-radius: 50%;
+      
+      &:hover {
+        background: var(--disabled-text-color-dark);
+      }
+    }
+  }
+  
+  .datePicker--scroll {
+    overflow-y: auto;
+    max-height: calc(90vh - 56px - 100px);
+  }
+
+  .datePicker--calendar {
+    padding: 0 20px;
+
+    .datePicker--dayNames {
+      width: 100%;
+      display: grid;
+      text-align: center;
+      
+      // there's probably a better way to do this, but wanted to try out CSS 
grid
+      grid-template-columns: calc(100% / 7) calc(100% / 7) calc(100% / 7) 
calc(100% / 7) calc(100% / 7) calc(100% / 7) calc(100% / 7);
+
+      span {
+        color: var(--secondary-text-color-dark);
+        font-size: 14px;
+        line-height: 42px;
+        display: inline-grid;
+      }
+    }
+
+    .datePicker--days {
+      width: 100%;
+      display: grid;
+      text-align: center;
+      grid-template-columns: calc(100% / 7) calc(100% / 7) calc(100% / 7) 
calc(100% / 7) calc(100% / 7) calc(100% / 7) calc(100% / 7);
+
+      span {
+        color: var(--primary-text-color-dark);
+        line-height: 42px;
+        font-size: 14px;
+        display: inline-grid;
+        transition: color .22s;
+        height: 42px;
+        position: relative;
+        cursor: pointer;
+        user-select: none;
+        border-radius: 50%;
+
+        &::before {
+          content: '';
+          position: absolute;
+          z-index: -1;
+          height: 42px;
+          width: 42px;
+          left: calc(50% - 21px);
+          background: var(--primary-color);
+          border-radius: 50%;
+          transition: transform .22s, opacity .22s;
+          transform: scale(0);
+          opacity: 0;
+        }
+        
+        &[disabled=true] {
+          cursor: unset;
+        }
+
+        &.datePicker--today {
+          font-weight: 700;
+        }
+
+        &.datePicker--selected {
+          color: rgba(255,255,255,.87);
+
+          &:before {
+            transform: scale(1);
+            opacity: 1;
+          }
+        }
+      }
+    }
+  }
+  
+  .datePicker--selectYear {
+    padding: 0 20px;
+    display: block;
+    width: 100%;
+    text-align: center;
+    max-height: 362px;
+    
+    span {
+      display: block;
+      width: 100%;
+      font-size: 24px;
+      margin: 20px auto;
+      cursor: pointer;
+      
+      &.selected {
+        font-size: 42px;
+        color: var(--primary-color);
+      }
+    }
+  }
+
+  div.datePicker--actions {
+    width: 100%;
+    padding: 8px;
+    text-align: right;
+
+    button {
+      margin-bottom: 0;
+      font-size: 15px;
+      cursor: pointer;
+      color: var(--primary-text-color);
+      border: none;
+      margin-left: 8px;
+      min-width: 64px;
+      line-height: 36px;
+      background-color: transparent;
+      appearance: none;
+      padding: 0 16px;
+      border-radius: 3px;
+      transition: background-color .13s;
+
+      &:hover, &:focus {
+        outline: none;
+        background-color: var(--disabled-text-color-dark);
+      }
+    }
+  }
+}
+
+.datePicker--background {
+  z-index: 199;
+  position: fixed;
+  top: 0;
+  left: 0;
+  bottom: 0;
+  right: 0;
+  background: rgba(0,0,0,.52);
+  animation: fadeIn .22s forwards;
+}
diff --git a/packages/merchant-backoffice-ui/src/scss/_footer.scss 
b/packages/merchant-backoffice-ui/src/scss/_footer.scss
new file mode 100644
index 000000000..027a5ca8b
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/scss/_footer.scss
@@ -0,0 +1,35 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+footer.footer {
+  .logo {
+    img {
+      width: auto;
+      height: $footer-logo-height;
+    }
+  }
+}
+
+@include mobile {
+  .footer-copyright {
+    text-align: center;
+  }
+}
diff --git a/packages/merchant-backoffice-ui/src/scss/_form.scss 
b/packages/merchant-backoffice-ui/src/scss/_form.scss
new file mode 100644
index 000000000..71f0d4da4
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/scss/_form.scss
@@ -0,0 +1,64 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+.field {
+  &.has-check {
+    .field-body {
+      margin-top: $default-padding * .125;
+    }
+  }
+  .control {
+    .mdi-24px.mdi-set, .mdi-24px.mdi:before {
+      font-size: inherit;
+    }
+  }
+}
+.upload {
+  .upload-draggable {
+    display: block;
+  }
+}
+
+.input, .textarea, select {
+  box-shadow: none;
+
+  &:focus, &:active {
+    box-shadow: none!important;
+  }
+}
+
+.switch input[type=checkbox]+.check:before {
+  box-shadow: none;
+}
+
+.switch, .b-checkbox.checkbox {
+  input[type=checkbox] {
+    &:focus + .check, &:focus:checked + .check {
+      box-shadow: none!important;
+    }
+  }
+}
+
+.b-checkbox.checkbox input[type=checkbox], .b-radio.radio input[type=radio] {
+  &+.check {
+    border: $checkbox-border;
+  }
+}
diff --git a/packages/merchant-backoffice-ui/src/scss/_hero-bar.scss 
b/packages/merchant-backoffice-ui/src/scss/_hero-bar.scss
new file mode 100644
index 000000000..90b67a2ed
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/scss/_hero-bar.scss
@@ -0,0 +1,55 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+section.hero.is-hero-bar {
+  background-color: $hero-bar-background;
+  border-bottom: $light-border;
+
+  .hero-body {
+    padding: $default-padding;
+
+    .level-item {
+      &.is-hero-avatar-item {
+        margin-right: $default-padding;
+      }
+
+      > div > .level {
+        margin-bottom: $default-padding * .5;
+      }
+
+      .subtitle + p {
+        margin-top: $default-padding * .5;
+      }
+    }
+
+    .button {
+      &.is-hero-button {
+        background-color: rgba($white, .5);
+        font-weight: 300;
+        @include transition(background-color);
+
+        &:hover {
+          background-color: $white;
+        }
+      }
+    }
+  }
+}
diff --git a/packages/merchant-backoffice-ui/src/scss/_loading.scss 
b/packages/merchant-backoffice-ui/src/scss/_loading.scss
new file mode 100644
index 000000000..d25bf8048
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/scss/_loading.scss
@@ -0,0 +1,51 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+.lds-ring {
+  display: inline-block;
+  position: relative;
+  width: 80px;
+  height: 80px;
+}
+.lds-ring div {
+  box-sizing: border-box;
+  display: block;
+  position: absolute;
+  width: 64px;
+  height: 64px;
+  margin: 8px;
+  border: 8px solid black;
+  border-radius: 50%;
+  animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
+  border-color: black transparent transparent transparent;
+}
+.lds-ring div:nth-child(1) {
+  animation-delay: -0.45s;
+}
+.lds-ring div:nth-child(2) {
+  animation-delay: -0.3s;
+}
+.lds-ring div:nth-child(3) {
+  animation-delay: -0.15s;
+}
+@keyframes lds-ring {
+  0% {
+    transform: rotate(0deg);
+  }
+  100% {
+    transform: rotate(360deg);
+  }
+}
diff --git a/packages/merchant-backoffice-ui/src/scss/_main-section.scss 
b/packages/merchant-backoffice-ui/src/scss/_main-section.scss
new file mode 100644
index 000000000..1a4fad81d
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/scss/_main-section.scss
@@ -0,0 +1,24 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+section.section.is-main-section {
+  padding-top: $default-padding;
+}
diff --git a/packages/merchant-backoffice-ui/src/scss/_misc.scss 
b/packages/merchant-backoffice-ui/src/scss/_misc.scss
new file mode 100644
index 000000000..65bd28dbd
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/scss/_misc.scss
@@ -0,0 +1,50 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+.is-user-avatar {
+  &.has-max-width {
+    max-width: $size-base * 7;
+  }
+
+  &.is-aligned-center {
+    margin: 0 auto;
+  }
+
+  img {
+    margin: 0 auto;
+    border-radius: $radius-rounded;
+  }
+}
+
+.icon.has-update-mark {
+  position: relative;
+
+  &:after {
+    content: "";
+    width: $icon-update-mark-size;
+    height: $icon-update-mark-size;
+    position: absolute;
+    top: 1px;
+    right: 1px;
+    background-color: $icon-update-mark-color;
+    border-radius: $radius-rounded;
+  }
+}
diff --git a/packages/merchant-backoffice-ui/src/scss/_mixins.scss 
b/packages/merchant-backoffice-ui/src/scss/_mixins.scss
new file mode 100644
index 000000000..0809033ed
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/scss/_mixins.scss
@@ -0,0 +1,34 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+@mixin transition($t) {
+  transition: $t 250ms ease-in-out 50ms;
+}
+
+@mixin icon-with-update-mark ($icon-base-width) {
+  .icon {
+    width: $icon-base-width;
+
+    &.has-update-mark:after {
+      right: ($icon-base-width / 2) - .85;
+    }
+  }
+}
diff --git a/packages/merchant-backoffice-ui/src/scss/_modal.scss 
b/packages/merchant-backoffice-ui/src/scss/_modal.scss
new file mode 100644
index 000000000..3edbb8d3a
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/scss/_modal.scss
@@ -0,0 +1,35 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+.modal-card {
+  width: $modal-card-width;
+}
+
+.modal-card-foot {
+  background-color: $modal-card-foot-background-color;
+}
+
+@include mobile {
+  .modal .animation-content .modal-card {
+    width: $modal-card-width-mobile;
+    margin: 0 auto;
+  }
+}
diff --git a/packages/merchant-backoffice-ui/src/scss/_nav-bar.scss 
b/packages/merchant-backoffice-ui/src/scss/_nav-bar.scss
new file mode 100644
index 000000000..09f1e2326
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/scss/_nav-bar.scss
@@ -0,0 +1,144 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+nav.navbar {
+  box-shadow: $navbar-box-shadow;
+
+  .navbar-item {
+    &.has-user-avatar {
+      .is-user-avatar {
+        margin-right: $default-padding * .5;
+        display: inline-flex;
+        width: $navbar-avatar-size;
+        height: $navbar-avatar-size;
+      }
+    }
+
+    &.has-divider {
+      border-right: $navbar-divider-border;
+    }
+
+    &.no-left-space {
+      padding-left: 0;
+    }
+
+    &.has-dropdown {
+      padding-right: 0;
+      padding-left: 0;
+
+      .navbar-link {
+        padding-right: $navbar-item-h-padding;
+        padding-left: $navbar-item-h-padding;
+      }
+    }
+
+    &.has-control {
+      padding-top: 0;
+      padding-bottom: 0;
+    }
+
+    .control {
+      .input {
+        color: $navbar-input-color;
+        border: 0;
+        box-shadow: none;
+        background: transparent;
+
+        &::placeholder {
+          color: $navbar-input-placeholder-color;
+        }
+      }
+    }
+  }
+}
+
+@include touch {
+  nav.navbar {
+    display: flex;
+    padding-right: 0;
+
+    .navbar-brand {
+      flex: 1;
+
+      &.is-right {
+        flex: none;
+      }
+    }
+
+    .navbar-item {
+      &.no-left-space-touch {
+        padding-left: 0;
+      }
+    }
+
+    .navbar-menu {
+      position: absolute;
+      width: 100vw;
+      padding-top: 0;
+      top: $navbar-height;
+      left: 0;
+
+      .navbar-item {
+        .icon:first-child {
+          margin-right: $default-padding * .5;
+        }
+
+        &.has-dropdown {
+          >.navbar-link {
+            background-color: $white-ter;
+            .icon:last-child {
+              display: none;
+            }
+          }
+        }
+
+        &.has-user-avatar {
+          >.navbar-link {
+            display: flex;
+            align-items: center;
+            padding-top: $default-padding * .5;
+            padding-bottom: $default-padding * .5;
+          }
+        }
+      }
+    }
+  }
+}
+
+@include desktop {
+  nav.navbar {
+    .navbar-item {
+      padding-right: $navbar-item-h-padding;
+      padding-left: $navbar-item-h-padding;
+
+      &:not(.is-desktop-icon-only) {
+        .icon:first-child {
+          margin-right: $default-padding * .5;
+        }
+      }
+      &.is-desktop-icon-only {
+        span:not(.icon) {
+          display: none;
+        }
+      }
+    }
+  }
+}
diff --git a/packages/merchant-backoffice-ui/src/scss/_table.scss 
b/packages/merchant-backoffice-ui/src/scss/_table.scss
new file mode 100644
index 000000000..9cf6f4dcd
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/scss/_table.scss
@@ -0,0 +1,173 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+table.table {
+  thead {
+    th {
+      border-bottom-width: 1px;
+    }
+  }
+
+  td, th {
+    &.checkbox-cell {
+      .b-checkbox.checkbox:not(.button) {
+        margin-right: 0;
+        width: 20px;
+
+        .control-label {
+          display: none;
+          padding: 0;
+        }
+      }
+    }
+  }
+
+  td {
+    .image {
+      margin: 0 auto;
+      width: $table-avatar-size;
+      height: $table-avatar-size;
+    }
+
+    &.is-progress-col {
+      min-width: 5rem;
+      vertical-align: middle;
+    }
+  }
+}
+
+.b-table {
+  .table {
+    border: 0;
+    border-radius: 0;
+  }
+
+  /* This stylizes buefy's pagination */
+  .table-wrapper {
+    margin-bottom: 0;
+  }
+
+  .table-wrapper + .level {
+    padding: $notification-padding;
+    padding-left: $card-content-padding;
+    padding-right: $card-content-padding;
+    margin: 0;
+    border-top: $base-color-light;
+    background: $notification-background-color;
+
+    .pagination-link {
+      background: $button-background-color;
+      color: $button-color;
+      border-color: $button-border-color;
+
+      &.is-current {
+        border-color: $button-active-border-color;
+      }
+    }
+
+    .pagination-previous, .pagination-next, .pagination-link {
+      border-color: $button-border-color;
+      color: $base-color;
+
+      &[disabled] {
+        background-color: transparent;
+      }
+    }
+  }
+}
+
+@include mobile {
+  .card {
+    &.has-table {
+      .b-table {
+        .table-wrapper + .level {
+          .level-left + .level-right {
+            margin-top: 0;
+          }
+        }
+      }
+    }
+    &.has-mobile-sort-spaced {
+      .b-table {
+        .field.table-mobile-sort {
+          padding-top: $default-padding * .5;
+        }
+      }
+    }
+  }
+  .b-table {
+    .field.table-mobile-sort {
+      padding: 0 $default-padding * .5;
+    }
+
+    .table-wrapper.has-mobile-cards {
+      tr {
+        box-shadow: 0 2px 3px rgba(10, 10, 10, 0.1);
+        margin-bottom: 3px!important;
+      }
+      td {
+        &.is-progress-col {
+          span, progress {
+            display: flex;
+            width: 45%;
+            align-items: center;
+            align-self: center;
+          }
+        }
+
+        &.checkbox-cell, &.is-image-cell {
+          border-bottom: 0!important;
+        }
+
+        &.checkbox-cell, &.is-actions-cell {
+          &:before {
+            display: none;
+          }
+        }
+
+        &.has-no-head-mobile {
+          &:before {
+            display: none;
+          }
+
+          span {
+            display: block;
+            width: 100%;
+          }
+
+          &.is-progress-col {
+            progress {
+              width: 100%;
+            }
+          }
+
+          &.is-image-cell {
+            .image {
+              width: $table-avatar-size-mobile;
+              height: auto;
+              margin: 0 auto $default-padding * .25;
+            }
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/packages/merchant-backoffice-ui/src/scss/_theme-default.scss 
b/packages/merchant-backoffice-ui/src/scss/_theme-default.scss
new file mode 100644
index 000000000..538dfd4da
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/scss/_theme-default.scss
@@ -0,0 +1,136 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+/* We'll need some initial vars to use here */
+@import "node_modules/bulma/sass/utilities/initial-variables";
+
+/* Base: Size  */
+$size-base: 1rem;
+$default-padding: $size-base * 1.5;
+
+/* Default font */
+$family-sans-serif: "Nunito", sans-serif;
+
+/* Base color */
+$base-color: #2e323a;
+$base-color-light: rgba(24, 28, 33, 0.06);
+
+/* General overrides */
+$primary: $turquoise;
+$body-background-color: #f8f8f8;
+$link: $blue;
+$link-visited: $purple;
+$light-border: 1px solid $base-color-light;
+$hr-height: 1px;
+
+/* NavBar: specifics */
+$navbar-input-color: $grey-darker;
+$navbar-input-placeholder-color: $grey-lighter;
+$navbar-box-shadow: 0 1px 0 rgba(24, 28, 33, 0.04);
+$navbar-divider-border: 1px solid rgba($grey-lighter, 0.25);
+$navbar-item-h-padding: $default-padding * 0.75;
+$navbar-avatar-size: 1.75rem;
+
+/* Aside: Bulma override */
+$menu-item-radius: 0;
+$menu-list-link-padding: $size-base * 0.5 0;
+$menu-label-color: lighten($base-color, 25%);
+$menu-item-color: lighten($base-color, 30%);
+$menu-item-hover-color: $white;
+$menu-item-hover-background-color: darken($base-color, 3.5%);
+$menu-item-active-color: $white;
+$menu-item-active-background-color: darken($base-color, 2.5%);
+
+/* Aside: specifics */
+$aside-width: $size-base * 14;
+$aside-mobile-width: $size-base * 15;
+$aside-icon-width: $size-base * 3;
+$aside-submenu-font-size: $size-base * 0.95;
+$aside-box-shadow: none;
+$aside-background-color: $base-color;
+$aside-tools-background-color: darken($aside-background-color, 10%);
+$aside-tools-color: $white;
+
+/* Title Bar: specifics */
+$title-bar-color: $grey;
+$title-bar-active-color: $black-ter;
+
+/* Hero Bar: specifics */
+$hero-bar-background: $white;
+
+/* Card: Bulma override */
+$card-shadow: none;
+$card-header-shadow: none;
+
+/* Card: specifics */
+$card-border: 1px solid $base-color-light;
+$card-header-border-bottom-color: $base-color-light;
+
+/* Table: Bulma override */
+$table-cell-border: 1px solid $white-bis;
+
+/* Table: specifics */
+$table-avatar-size: $size-base * 1.5;
+$table-avatar-size-mobile: 25vw;
+
+/* Form */
+$checkbox-border: 1px solid $base-color;
+
+/* Modal card: Bulma override */
+$modal-card-head-background-color: $white-ter;
+$modal-card-title-size: $size-base;
+$modal-card-body-padding: $default-padding 20px;
+$modal-card-head-border-bottom: 1px solid $white-ter;
+$modal-card-foot-border-top: 0;
+
+/* Modal card: specifics */
+$modal-card-width: 80vw;
+$modal-card-width-mobile: 90vw;
+$modal-card-foot-background-color: $white-ter;
+
+/* Notification: Bulma override */
+$notification-padding: $default-padding * 0.75 $default-padding;
+
+/* Footer: Bulma override */
+$footer-background-color: $white;
+$footer-padding: $default-padding * 0.33 $default-padding;
+
+/* Footer: specifics */
+$footer-logo-height: $size-base * 2;
+
+/* Progress: Bulma override */
+$progress-bar-background-color: $grey-lighter;
+
+/* Icon: specifics */
+$icon-update-mark-size: $size-base * 0.5;
+$icon-update-mark-color: $yellow;
+
+$input-disabled-border-color: $grey-lighter;
+$table-row-hover-background-color: hsl(0, 0%, 80%);
+
+.menu-list {
+  div {
+    border-radius: $menu-item-radius;
+    color: $menu-item-color;
+    display: block;
+    padding: $menu-list-link-padding;
+  }
+}
diff --git a/packages/merchant-backoffice-ui/src/scss/_tiles.scss 
b/packages/merchant-backoffice-ui/src/scss/_tiles.scss
new file mode 100644
index 000000000..94fc04e70
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/scss/_tiles.scss
@@ -0,0 +1,25 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+
+.is-tiles-wrapper {
+  margin-bottom: $default-padding;
+}
diff --git a/packages/merchant-backoffice-ui/src/scss/_title-bar.scss 
b/packages/merchant-backoffice-ui/src/scss/_title-bar.scss
new file mode 100644
index 000000000..736f26cbd
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/scss/_title-bar.scss
@@ -0,0 +1,50 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+section.section.is-title-bar {
+  padding: $default-padding;
+  border-bottom: $light-border;
+
+  ul {
+    li {
+      display: inline-block;
+      padding: 0 $default-padding * .5 0 0;
+      font-size: $default-padding;
+      color: $title-bar-color;
+
+      &:after {
+        display: inline-block;
+        content: '/';
+        padding-left: $default-padding * .5;
+      }
+
+      &:last-child {
+        padding-right: 0;
+        font-weight: 900;
+        color: $title-bar-active-color;
+
+        &:after {
+          display: none;
+        }
+      }
+    }
+  }
+}
diff --git a/packages/anastasis-webui/src/scss/fonts/XRXV3I6Li01BKofINeaE.ttf 
b/packages/merchant-backoffice-ui/src/scss/fonts/XRXV3I6Li01BKofINeaE.ttf
similarity index 100%
copy from packages/anastasis-webui/src/scss/fonts/XRXV3I6Li01BKofINeaE.ttf
copy to packages/merchant-backoffice-ui/src/scss/fonts/XRXV3I6Li01BKofINeaE.ttf
diff --git a/packages/merchant-backoffice-ui/src/scss/fonts/nunito.css 
b/packages/merchant-backoffice-ui/src/scss/fonts/nunito.css
new file mode 100644
index 000000000..ab30db36b
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/scss/fonts/nunito.css
@@ -0,0 +1,22 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+@font-face {
+  font-family: 'Nunito';
+  font-style: normal;
+  font-weight: 400;
+  src: url(./XRXV3I6Li01BKofINeaE.ttf) format('truetype');
+}
diff --git 
a/packages/anastasis-webui/src/scss/fonts/materialdesignicons-webfont-4.9.95.eot
 
b/packages/merchant-backoffice-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.eot
similarity index 100%
copy from 
packages/anastasis-webui/src/scss/fonts/materialdesignicons-webfont-4.9.95.eot
copy to 
packages/merchant-backoffice-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.eot
diff --git 
a/packages/anastasis-webui/src/scss/fonts/materialdesignicons-webfont-4.9.95.ttf
 
b/packages/merchant-backoffice-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.ttf
similarity index 100%
copy from 
packages/anastasis-webui/src/scss/fonts/materialdesignicons-webfont-4.9.95.ttf
copy to 
packages/merchant-backoffice-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.ttf
diff --git 
a/packages/anastasis-webui/src/scss/fonts/materialdesignicons-webfont-4.9.95.woff
 
b/packages/merchant-backoffice-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.woff
similarity index 100%
copy from 
packages/anastasis-webui/src/scss/fonts/materialdesignicons-webfont-4.9.95.woff
copy to 
packages/merchant-backoffice-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.woff
diff --git 
a/packages/anastasis-webui/src/scss/fonts/materialdesignicons-webfont-4.9.95.woff2
 
b/packages/merchant-backoffice-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.woff2
similarity index 100%
copy from 
packages/anastasis-webui/src/scss/fonts/materialdesignicons-webfont-4.9.95.woff2
copy to 
packages/merchant-backoffice-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.woff2
diff --git 
a/packages/merchant-backoffice-ui/src/scss/icons/materialdesignicons-4.9.95.min.css
 
b/packages/merchant-backoffice-ui/src/scss/icons/materialdesignicons-4.9.95.min.css
new file mode 100644
index 000000000..24a89d639
--- /dev/null
+++ 
b/packages/merchant-backoffice-ui/src/scss/icons/materialdesignicons-4.9.95.min.css
@@ -0,0 +1,3 @@
+@font-face{font-family:"Material Design 
Icons";src:url("./fonts/materialdesignicons-webfont-4.9.95.eot");src:url("./fonts/materialdesignicons-webfont-4.9.95.woff2")
 format("woff2"),url("./fonts/materialdesignicons-webfont-4.9.95.woff") 
format("woff"),url("./fonts/materialdesignicons-webfont-4.9.95.ttf") 
format("truetype");font-weight:normal;font-style:normal}.mdi:before,.mdi-set{display:inline-block;font:normal
 normal normal 24px/1 "Material Design Icons";font-size:inherit;text-rendering 
[...]
+
+/*# sourceMappingURL=materialdesignicons.css.map */
diff --git a/packages/merchant-backoffice-ui/src/scss/libs/_all.scss 
b/packages/merchant-backoffice-ui/src/scss/libs/_all.scss
new file mode 100644
index 000000000..313eb52f9
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/scss/libs/_all.scss
@@ -0,0 +1,29 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+@import "node_modules/bulma-radio/bulma-radio";
+// @import "node_modules/bulma-responsive-tables/bulma-responsive-tables";
+@import "node_modules/bulma-checkbox/bulma-checkbox";
+@import "node_modules/bulma-switch-control/bulma-switch-control";
+@import "node_modules/bulma-upload-control/bulma-upload-control";
+
+/* Bulma */
+@import "node_modules/bulma/bulma";
diff --git a/packages/merchant-backoffice-ui/src/scss/main.scss 
b/packages/merchant-backoffice-ui/src/scss/main.scss
new file mode 100644
index 000000000..b523566c1
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/scss/main.scss
@@ -0,0 +1,191 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+ 
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+/* Theme style (colors & sizes) */
+@import "theme-default";
+
+/* Core Libs & Lib configs */
+@import "libs/all";
+
+/* Mixins */
+@import "mixins";
+
+/* Theme components */
+@import "nav-bar";
+@import "aside";
+@import "title-bar";
+@import "hero-bar";
+@import "card";
+@import "table";
+@import "tiles";
+@import "form";
+@import "main-section";
+@import "modal";
+@import "footer";
+@import "misc";
+@import "custom-calendar";
+@import "loading";
+
+@import "fonts/nunito.css";
+@import "icons/materialdesignicons-4.9.95.min.css";
+
+$tooltip-color: red;
+
+@import 
"../../node_modules/@creativebulma/bulma-tooltip/dist/bulma-tooltip.min.css";
+@import "../../node_modules/bulma-timeline/dist/css/bulma-timeline.min.css";
+
+.notification {
+  background-color: transparent;
+}
+
+.timeline .timeline-item .timeline-content {
+  padding-top: 0;
+}
+
+.timeline .timeline-item:last-child::before {
+  display: none;
+}
+
+.timeline .timeline-item .timeline-marker {
+  top: 0;
+}
+
+.toast {
+  position: absolute;
+  width: 60%;
+  margin-left: 10%;
+  margin-right: 10%;
+  z-index: 999;
+
+  display: flex;
+  flex-direction: column;
+  padding: 15px;
+  text-align: center;
+  pointer-events: none;
+}
+
+.toast > .message {
+  white-space: pre-wrap;
+  opacity: 80%;
+}
+
+div {
+  &.is-loading {
+    position: relative;
+    pointer-events: none;
+    opacity: 0.5;
+    &:after {
+      // @include loader;
+      position: absolute;
+      top: calc(50% - 2.5em);
+      left: calc(50% - 2.5em);
+      width: 5em;
+      height: 5em;
+      border-width: 0.25em;
+    }
+  }
+}
+
+input[type="checkbox"]:indeterminate + .check {
+  background: red !important;
+}
+
+.right-sticky {
+  position: sticky;
+  right: 0px;
+  background-color: $white;
+}
+
+.right-sticky .buttons {
+  flex-wrap: nowrap;
+}
+
+.table.is-striped tbody tr:not(.is-selected):nth-child(even) .right-sticky {
+  background-color: #fafafa;
+}
+
+tr:hover .right-sticky {
+  background-color: hsl(0, 0%, 80%);
+}
+.table.is-striped tbody tr:nth-child(even):hover .right-sticky {
+  background-color: hsl(0, 0%, 95%);
+}
+
+.content-full-size {
+  height: calc(100% - 3rem);
+  position: absolute;
+  width: calc(100% - 14rem);
+  display: flex;
+}
+
+.content-full-size .column .card {
+  min-width: 200px;
+}
+
+@include touch {
+  .content-full-size {
+    height: 100%;
+    position: absolute;
+    width: 100%;
+  }
+}
+
+.column.is-half {
+  flex: none;
+  width: 50%;
+}
+
+input:read-only {
+  cursor: initial;
+}
+
+[data-tooltip]:before {
+  max-width: 15rem;
+  width: max-content;
+  text-align: left;
+  transition: opacity 0.1s linear 1s;
+  // transform: inherit !important;
+  white-space: pre-wrap !important;
+  font-weight: normal;
+  // position: relative;
+}
+
+.icon[data-tooltip]:before {
+  transition: none;
+  z-index: 5;
+}
+
+span[data-tooltip] {
+  border-bottom: none;
+}
+
+div[data-tooltip]::before {
+  position: absolute;
+}
+
+.modal-card-body > p {
+  padding: 1em;
+}
+
+.modal-card-body > p.warning {
+  background-color: #fffbdd;
+  border: solid 1px #f2e9bf;
+}
diff --git a/packages/merchant-backoffice-ui/src/sw.js 
b/packages/merchant-backoffice-ui/src/sw.js
new file mode 100644
index 000000000..5fcde8281
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/sw.js
@@ -0,0 +1,25 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+// import { getFiles, setupPrecaching, setupRouting } from 'preact-cli/sw/';
+
+// setupRouting();
+// setupPrecaching(getFiles());
diff --git a/packages/merchant-backoffice-ui/src/template.html 
b/packages/merchant-backoffice-ui/src/template.html
new file mode 100644
index 000000000..ccccab167
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/template.html
@@ -0,0 +1,52 @@
+<!--
+        This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+
+ @author Sebastian Javier Marchano
+-->
+<!DOCTYPE html>
+<html lang="en" class="has-aside-left has-aside-mobile-transition 
has-navbar-fixed-top has-aside-expanded">
+       <head>
+               <meta charset="utf-8">
+               <title><%= htmlWebpackPlugin.options.title %></title>
+               <meta name="viewport" 
content="width=device-width,initial-scale=1">
+               <meta name="mobile-web-app-capable" content="yes">
+               <meta name="apple-mobile-web-app-capable" content="yes">
+
+               <link rel="icon" 
href="data:;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAD///////////////////////////////////////////////////////////////////////////////////////////////////7//v38//78/P/+/fz//vz7///+/v/+/f3//vz7///+/v/+/fz//v38///////////////////////+/v3///7+/////////////////////////////////////////////////////////v3//v79///////+/v3///////r28v/ct5//06SG/9Gffv/Xqo7/7N/V/9e2nf/bsJb/6uDW/9Sskf/euKH/+/j2///////+/v3//////+3azv+/eE3/2rWd/9Kkhv/Vr5
 [...]
+               <link rel="shortcut icon" href="data:image/x-icon;," 
type="image/x-icon" />
+
+               <% if (htmlWebpackPlugin.options.manifest.theme_color) { %>
+                       <meta name="theme-color" content="<%= 
htmlWebpackPlugin.options.manifest.theme_color %>">
+               <% } %>
+
+               <% for (const index in htmlWebpackPlugin.files.css) { %>
+                       <% const file = htmlWebpackPlugin.files.css[index] %>
+                       <style data-href='<%= file %>' >
+                               <%= 
compilation.assets[file.substr(htmlWebpackPlugin.files.publicPath.length)].source()
 %>
+                       </style>
+               <% } %>
+               
+       </head>
+       <body>
+
+               <script>
+                       <%= 
compilation.assets[htmlWebpackPlugin.files.chunks["polyfills"].entry.substr(htmlWebpackPlugin.files.publicPath.length)].source()
 %>
+               </script>
+               <script>
+                       <%= 
compilation.assets[htmlWebpackPlugin.files.chunks["bundle"].entry.substr(htmlWebpackPlugin.files.publicPath.length)].source()
 %>
+               </script>
+
+       </body>
+</html>
diff --git a/packages/merchant-backoffice-ui/src/utils/amount.ts 
b/packages/merchant-backoffice-ui/src/utils/amount.ts
new file mode 100644
index 000000000..61e33129c
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/utils/amount.ts
@@ -0,0 +1,70 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+import { amountFractionalBase, AmountJson, Amounts } from 
"@gnu-taler/taler-util";
+import { MerchantBackend } from "../declaration";
+
+/**
+ * sums two prices, 
+ * @param one 
+ * @param two 
+ * @returns 
+ */
+const sumPrices = (one: string, two: string) => {
+  const [currency, valueOne] = one.split(':')
+  const [, valueTwo] = two.split(':')
+  return `${currency}:${parseInt(valueOne, 10) + parseInt(valueTwo, 10)}`
+}
+
+/**
+ * merge refund with the same description and a difference less than one minute
+ * @param prev list of refunds that will hold the merged refunds 
+ * @param cur new refund to add to the list
+ * @returns list with the new refund, may be merged with the last
+ */
+export function mergeRefunds(prev: MerchantBackend.Orders.RefundDetails[], 
cur: MerchantBackend.Orders.RefundDetails) {
+  let tail;
+
+  if (prev.length === 0 ||  //empty list
+    cur.timestamp.t_s === 'never' || //current doesnt have timestamp
+    (tail = prev[prev.length - 1]).timestamp.t_s === 'never' || // last doesnt 
have timestamp
+    cur.reason !== tail.reason || //different reason
+    cur.pending !== tail.pending || //different pending state
+    Math.abs(cur.timestamp.t_s - tail.timestamp.t_s) > 1000 * 60) {//more than 
1 minute difference
+
+    prev.push(cur)
+    return prev
+  }
+
+  prev[prev.length - 1] = {
+    ...tail,
+    amount: sumPrices(tail.amount, cur.amount)
+  }
+
+  return prev
+}
+
+export const rate = (one: string, two: string) => {
+  const a = Amounts.parseOrThrow(one)
+  const b = Amounts.parseOrThrow(two)
+  const af = toFloat(a)
+  const bf = toFloat(b)
+  if (bf === 0) return 0
+  return af / bf
+}
+
+function toFloat(amount: AmountJson) {
+  return amount.value + (amount.fraction / amountFractionalBase);
+}
diff --git a/packages/merchant-backoffice-ui/src/utils/constants.ts 
b/packages/merchant-backoffice-ui/src/utils/constants.ts
new file mode 100644
index 000000000..5356a1a49
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/utils/constants.ts
@@ -0,0 +1,194 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+//https://tools.ietf.org/html/rfc8905
+export const PAYTO_REGEX = 
/^payto:\/\/[a-zA-Z][a-zA-Z0-9-.]+(\/[a-zA-Z0-9\-\.\~\(\)@_%:!$&'*+,;=]*)*\??((amount|receiver-name|sender-name|instruction|message)=[a-zA-Z0-9\-\.\~\(\)@_%:!$'*+,;=]*&?)*$/
+export const PAYTO_WIRE_METHOD_LOOKUP = 
/payto:\/\/([a-zA-Z][a-zA-Z0-9-.]+)\/.*/
+
+export const AMOUNT_REGEX = /^[a-zA-Z][a-zA-Z]*:[0-9][0-9,]*\.?[0-9,]*$/
+
+export const INSTANCE_ID_LOOKUP = /\/instances\/([^/]*)\/?$/
+
+export const AMOUNT_ZERO_REGEX = /^[a-zA-Z][a-zA-Z]*:0$/
+
+export const CROCKFORD_BASE32_REGEX = 
/^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]+[*~$=U]*$/
+
+export const URL_REGEX = 
/^((https?:)(\/\/\/?)([\w]*(?::[\w]*)?@)?([\d\w\.-]+)(?::(\d+))?)\/$/
+
+// how much rows we add every time user hit load more
+export const PAGE_SIZE = 20
+// how bigger can be the result set
+// after this threshold, load more with move the cursor
+export const MAX_RESULT_SIZE = PAGE_SIZE * 2 - 1;
+
+// how much we will wait for all request, in seconds
+export const DEFAULT_REQUEST_TIMEOUT = 10;
+
+export const MAX_IMAGE_SIZE = 1024 * 1024;
+
+export const INSTANCE_ID_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9_.@-]+$/
+
+export const COUNTRY_TABLE = {
+  AE: "U.A.E.",
+  AF: "Afghanistan",
+  AL: "Albania",
+  AM: "Armenia",
+  AN: "Netherlands Antilles",
+  AR: "Argentina",
+  AT: "Austria",
+  AU: "Australia",
+  AZ: "Azerbaijan",
+  BA: "Bosnia and Herzegovina",
+  BD: "Bangladesh",
+  BE: "Belgium",
+  BG: "Bulgaria",
+  BH: "Bahrain",
+  BN: "Brunei Darussalam",
+  BO: "Bolivia",
+  BR: "Brazil",
+  BT: "Bhutan",
+  BY: "Belarus",
+  BZ: "Belize",
+  CA: "Canada",
+  CG: "Congo",
+  CH: "Switzerland",
+  CI: "Cote d'Ivoire",
+  CL: "Chile",
+  CM: "Cameroon",
+  CN: "People's Republic of China",
+  CO: "Colombia",
+  CR: "Costa Rica",
+  CS: "Serbia and Montenegro",
+  CZ: "Czech Republic",
+  DE: "Germany",
+  DK: "Denmark",
+  DO: "Dominican Republic",
+  DZ: "Algeria",
+  EC: "Ecuador",
+  EE: "Estonia",
+  EG: "Egypt",
+  ER: "Eritrea",
+  ES: "Spain",
+  ET: "Ethiopia",
+  FI: "Finland",
+  FO: "Faroe Islands",
+  FR: "France",
+  GB: "United Kingdom",
+  GD: "Caribbean",
+  GE: "Georgia",
+  GL: "Greenland",
+  GR: "Greece",
+  GT: "Guatemala",
+  HK: "Hong Kong",
+  // HK: "Hong Kong S.A.R.",
+  HN: "Honduras",
+  HR: "Croatia",
+  HT: "Haiti",
+  HU: "Hungary",
+  ID: "Indonesia",
+  IE: "Ireland",
+  IL: "Israel",
+  IN: "India",
+  IQ: "Iraq",
+  IR: "Iran",
+  IS: "Iceland",
+  IT: "Italy",
+  JM: "Jamaica",
+  JO: "Jordan",
+  JP: "Japan",
+  KE: "Kenya",
+  KG: "Kyrgyzstan",
+  KH: "Cambodia",
+  KR: "South Korea",
+  KW: "Kuwait",
+  KZ: "Kazakhstan",
+  LA: "Laos",
+  LB: "Lebanon",
+  LI: "Liechtenstein",
+  LK: "Sri Lanka",
+  LT: "Lithuania",
+  LU: "Luxembourg",
+  LV: "Latvia",
+  LY: "Libya",
+  MA: "Morocco",
+  MC: "Principality of Monaco",
+  MD: "Moldava",
+  // MD: "Moldova",
+  ME: "Montenegro",
+  MK: "Former Yugoslav Republic of Macedonia",
+  ML: "Mali",
+  MM: "Myanmar",
+  MN: "Mongolia",
+  MO: "Macau S.A.R.",
+  MT: "Malta",
+  MV: "Maldives",
+  MX: "Mexico",
+  MY: "Malaysia",
+  NG: "Nigeria",
+  NI: "Nicaragua",
+  NL: "Netherlands",
+  NO: "Norway",
+  NP: "Nepal",
+  NZ: "New Zealand",
+  OM: "Oman",
+  PA: "Panama",
+  PE: "Peru",
+  PH: "Philippines",
+  PK: "Islamic Republic of Pakistan",
+  PL: "Poland",
+  PR: "Puerto Rico",
+  PT: "Portugal",
+  PY: "Paraguay",
+  QA: "Qatar",
+  RE: "Reunion",
+  RO: "Romania",
+  RS: "Serbia",
+  RU: "Russia",
+  RW: "Rwanda",
+  SA: "Saudi Arabia",
+  SE: "Sweden",
+  SG: "Singapore",
+  SI: "Slovenia",
+  SK: "Slovak",
+  SN: "Senegal",
+  SO: "Somalia",
+  SR: "Suriname",
+  SV: "El Salvador",
+  SY: "Syria",
+  TH: "Thailand",
+  TJ: "Tajikistan",
+  TM: "Turkmenistan",
+  TN: "Tunisia",
+  TR: "Turkey",
+  TT: "Trinidad and Tobago",
+  TW: "Taiwan",
+  TZ: "Tanzania",
+  UA: "Ukraine",
+  US: "United States",
+  UY: "Uruguay",
+  VA: "Vatican",
+  VE: "Venezuela",
+  VN: "Viet Nam",
+  YE: "Yemen",
+  ZA: "South Africa",
+  ZW: "Zimbabwe"
+}
+
diff --git a/packages/merchant-backoffice-ui/src/utils/switchableAxios.ts 
b/packages/merchant-backoffice-ui/src/utils/switchableAxios.ts
new file mode 100644
index 000000000..be7eedd48
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/utils/switchableAxios.ts
@@ -0,0 +1,66 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+import axios, { AxiosPromise, AxiosRequestConfig } from "axios";
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+export let removeAxiosCancelToken = false;
+
+export let axiosHandler = function doAxiosRequest(config: AxiosRequestConfig): 
AxiosPromise<any> {
+  return axios(config)
+}
+
+/**
+ * Set this backend library to testing mode.
+ * Instead of calling the axios library the @handler will be called
+ * 
+ * @param handler callback that will mock axios 
+ */
+export function setAxiosRequestAsTestingEnvironment(handler: AxiosHandler): 
void {
+  removeAxiosCancelToken = true;
+  axiosHandler = function defaultTestingHandler(config) {
+    const currentHanlder = listOfHandlersToUseOnce.shift()
+    if (!currentHanlder) {
+      return handler(config)
+    }
+
+    return currentHanlder(config)
+  }
+}
+
+type AxiosHandler = (config: AxiosRequestConfig) => AxiosPromise<any>;
+type AxiosArguments = { args: AxiosRequestConfig | undefined }
+
+
+const listOfHandlersToUseOnce = new Array<AxiosHandler>()
+
+/**
+ * 
+ * @param handler mock function
+ * @returns savedArgs
+ */
+export function mockAxiosOnce(handler: AxiosHandler): { args: 
AxiosRequestConfig | undefined } {
+  const savedArgs: AxiosArguments = { args: undefined }
+  listOfHandlersToUseOnce.push((config: AxiosRequestConfig): AxiosPromise<any> 
=> {
+    savedArgs.args = config;
+    return handler(config)
+  })
+  return savedArgs;
+}
diff --git a/packages/merchant-backoffice-ui/src/utils/table.ts 
b/packages/merchant-backoffice-ui/src/utils/table.ts
new file mode 100644
index 000000000..3d713a6f7
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/utils/table.ts
@@ -0,0 +1,37 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+import { WithId } from "../declaration";
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+export interface Actions<T extends WithId> {
+  element: T;
+  type: 'DELETE' | 'UPDATE';
+}
+
+function notEmpty<TValue>(value: TValue | null | undefined): value is TValue {
+  return value !== null && value !== undefined;
+}
+
+export function buildActions<T extends WithId>(intances: T[], selected: 
string[], action: 'DELETE'): Actions<T>[] {
+  return selected.map(id => intances.find(i => i.id === id))
+    .filter(notEmpty)
+    .map(id => ({ element: id, type: action }))
+}
diff --git a/packages/merchant-backoffice-ui/src/utils/types.ts 
b/packages/merchant-backoffice-ui/src/utils/types.ts
new file mode 100644
index 000000000..a3f23ac10
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/utils/types.ts
@@ -0,0 +1,31 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+import { VNode } from "preact";
+
+export interface KeyValue {
+  [key: string]: string;
+}
+
+export interface Notification {
+  message: string;
+  description?: string | VNode;
+  details?: string | VNode;
+  type: MessageType;
+}
+
+export type ValueOrFunction<T> = T | ((p: T) => T);
+export type MessageType = "INFO" | "WARN" | "ERROR" | "SUCCESS";
diff --git a/packages/merchant-backoffice-ui/tests/__mocks__/browserMocks.ts 
b/packages/merchant-backoffice-ui/tests/__mocks__/browserMocks.ts
new file mode 100644
index 000000000..ee6bba505
--- /dev/null
+++ b/packages/merchant-backoffice-ui/tests/__mocks__/browserMocks.ts
@@ -0,0 +1,42 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+// Mock Browser API's which are not supported by JSDOM, e.g. ServiceWorker, 
LocalStorage
+/**
+ * An example how to mock localStorage is given below 👇
+ */
+
+/* 
+// Mocks localStorage
+const localStorageMock = (function() {
+       let store = {};
+
+       return {
+               getItem: (key) => store[key] || null,
+               setItem: (key, value) => store[key] = value.toString(),
+               clear: () => store = {}
+       };
+
+})();
+
+Object.defineProperty(window, 'localStorage', {
+       value: localStorageMock
+}); */
diff --git a/packages/merchant-backoffice-ui/tests/__mocks__/fileMocks.ts 
b/packages/merchant-backoffice-ui/tests/__mocks__/fileMocks.ts
new file mode 100644
index 000000000..0c045e9d1
--- /dev/null
+++ b/packages/merchant-backoffice-ui/tests/__mocks__/fileMocks.ts
@@ -0,0 +1,24 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+// This fixed an error related to the CSS and loading gif breaking my Jest test
+// See 
https://facebook.github.io/jest/docs/en/webpack.html#handling-static-assets
+export default 'test-file-stub';
diff --git a/packages/merchant-backoffice-ui/tests/__mocks__/fileTransformer.js 
b/packages/merchant-backoffice-ui/tests/__mocks__/fileTransformer.js
new file mode 100644
index 000000000..e6193f8fd
--- /dev/null
+++ b/packages/merchant-backoffice-ui/tests/__mocks__/fileTransformer.js
@@ -0,0 +1,31 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+// fileTransformer.js
+
+// eslint-disable-next-line @typescript-eslint/no-var-requires
+const path = require('path');
+
+module.exports = {
+    process(src, filename, config, options) {
+        return 'module.exports = ' + JSON.stringify(path.basename(filename)) + 
';';
+    },
+};
+
diff --git a/packages/merchant-backoffice-ui/tests/__mocks__/setupTests.ts 
b/packages/merchant-backoffice-ui/tests/__mocks__/setupTests.ts
new file mode 100644
index 000000000..b08eb7fe6
--- /dev/null
+++ b/packages/merchant-backoffice-ui/tests/__mocks__/setupTests.ts
@@ -0,0 +1,28 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import "regenerator-runtime/runtime";
+// import { configure } from 'enzyme';
+// import Adapter from 'enzyme-adapter-preact-pure';
+
+// configure({
+//     adapter: new Adapter()
+// });
diff --git a/packages/merchant-backoffice-ui/tests/axiosMock.ts 
b/packages/merchant-backoffice-ui/tests/axiosMock.ts
new file mode 100644
index 000000000..13ddab598
--- /dev/null
+++ b/packages/merchant-backoffice-ui/tests/axiosMock.ts
@@ -0,0 +1,445 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+import * as axios from 'axios';
+import { MerchantBackend } from '../src/declaration';
+import { mockAxiosOnce, setAxiosRequestAsTestingEnvironment } from 
'../src/utils/switchableAxios';
+// import { mockAxiosOnce, setAxiosRequestAsTestingEnvironment } from 
"../src/hooks/backend";
+
+export type Query<Req, Res> = (GetQuery | PostQuery | DeleteQuery | 
PatchQuery) & RequestResponse<Req, Res>
+
+interface RequestResponse<Req, Res> {
+  code?: number,
+}
+interface GetQuery { get: string }
+interface PostQuery { post: string }
+interface DeleteQuery { delete: string }
+interface PatchQuery { patch: string }
+
+
+const JEST_DEBUG_LOG = process.env['JEST_DEBUG_LOG'] !== undefined
+
+type ExpectationValues = { query: Query<any, any>; params?: { auth?: string, 
request?: any, qparam?: any, response?: any } }
+
+type TestValues = [axios.AxiosRequestConfig | undefined, ExpectationValues | 
undefined]
+
+const defaultCallback = (actualQuery?: axios.AxiosRequestConfig): 
axios.AxiosPromise<any> => {
+  if (JEST_DEBUG_LOG) {
+    console.log('UNEXPECTED QUERY', actualQuery)
+  }
+  throw Error('Default Axios mock callback is called, this mean that the test 
did a tried to use axios but there was no expectation in place, try using 
JEST_DEBUG_LOG env')
+}
+
+setAxiosRequestAsTestingEnvironment(
+  defaultCallback
+);
+
+export class AxiosMockEnvironment {
+  expectations: Array<{
+    query: Query<any, any>,
+    auth?: string,
+    params?: { request?: any, qparam?: any, response?: any },
+    result: { args: axios.AxiosRequestConfig | undefined }
+  } | undefined> = []
+  // axiosMock: jest.MockedFunction<axios.AxiosStatic>
+
+  addRequestExpectation<RequestType, ResponseType>(expectedQuery: 
Query<RequestType, ResponseType>, params: { auth?: string, request?: 
RequestType, qparam?: any, response?: ResponseType }): void {
+    const result = mockAxiosOnce(function (actualQuery?: 
axios.AxiosRequestConfig): axios.AxiosPromise {
+
+      if (JEST_DEBUG_LOG) {
+        console.log('query to the backend is made', actualQuery)
+      }
+      if (!expectedQuery) {
+        return Promise.reject("a query was made but it was not expected")
+      }
+      if (JEST_DEBUG_LOG) {
+        console.log('expected query:', params?.request)
+        console.log('expected qparams:', params?.qparam)
+        console.log('sending response:', params?.response)
+      }
+
+      const responseCode = expectedQuery.code || 200
+
+      //This response is what buildRequestOk is expecting in file 
hook/backend.ts
+      if (responseCode >= 200 && responseCode < 300) {
+        return Promise.resolve({
+          data: params?.response, config: {
+            data: params?.response,
+            params: actualQuery?.params || {},
+          }, request: { params: actualQuery?.params || {} }
+        } as any);
+      }
+      //This response is what buildRequestFailed is expecting in file 
hook/backend.ts
+      return Promise.reject({
+        response: {
+          status: responseCode
+        },
+        request: {
+          data: params?.response,
+          params: actualQuery?.params || {},
+        }
+      })
+
+    } as any)
+
+    this.expectations.push(expectedQuery ? { query: expectedQuery, params, 
result } : undefined)
+  }
+
+  getLastTestValues(): TestValues {
+    const expectedQuery = this.expectations.shift()
+
+    return [
+      expectedQuery?.result.args, expectedQuery
+    ]
+  }
+
+}
+
+export function assertJustExpectedRequestWereMade(env: AxiosMockEnvironment): 
void {
+  let size = env.expectations.length
+  while (size-- > 0) {
+    assertNextRequest(env)
+  }
+  assertNoMoreRequestWereMade(env)
+}
+
+export function assertNoMoreRequestWereMade(env: AxiosMockEnvironment): void {
+  const [actualQuery, expectedQuery] = env.getLastTestValues()
+
+  expect(actualQuery).toBeUndefined();
+  expect(expectedQuery).toBeUndefined();
+}
+
+export function assertNextRequest(env: AxiosMockEnvironment): void {
+  const [actualQuery, expectedQuery] = env.getLastTestValues()
+
+  if (!actualQuery) {
+    //expected one query but the tested component didn't execute one
+    expect(actualQuery).toBe(expectedQuery);
+    return
+  }
+
+  if (!expectedQuery) {
+    const errorMessage = 'a query was made to the backend but the test 
explicitly expected no query';
+    if (JEST_DEBUG_LOG) {
+      console.log(errorMessage, actualQuery)
+    }
+    throw Error(errorMessage)
+  }
+  if ('get' in expectedQuery.query) {
+    expect(actualQuery.method).toBe('get');
+    expect(actualQuery.url).toBe(expectedQuery.query.get);
+  }
+  if ('post' in expectedQuery.query) {
+    expect(actualQuery.method).toBe('post');
+    expect(actualQuery.url).toBe(expectedQuery.query.post);
+  }
+  if ('delete' in expectedQuery.query) {
+    expect(actualQuery.method).toBe('delete');
+    expect(actualQuery.url).toBe(expectedQuery.query.delete);
+  }
+  if ('patch' in expectedQuery.query) {
+    expect(actualQuery.method).toBe('patch');
+    expect(actualQuery.url).toBe(expectedQuery.query.patch);
+  }
+
+  if (expectedQuery.params?.request) {
+    expect(actualQuery.data).toMatchObject(expectedQuery.params.request)
+  }
+  if (expectedQuery.params?.qparam) {
+    expect(actualQuery.params).toMatchObject(expectedQuery.params.qparam)
+  }
+
+  if (expectedQuery.params?.auth) {
+    expect(actualQuery.headers.Authorization).toBe(expectedQuery.params?.auth)
+  }
+
+}
+
+////////////////////
+// ORDER
+////////////////////
+
+export const API_CREATE_ORDER: Query<
+  MerchantBackend.Orders.PostOrderRequest,
+  MerchantBackend.Orders.PostOrderResponse
+> = {
+  post: "http://backend/instances/default/private/orders";,
+};
+
+export const API_GET_ORDER_BY_ID = (
+  id: string
+): Query<
+  unknown,
+  MerchantBackend.Orders.MerchantOrderStatusResponse
+> => ({
+  get: `http://backend/instances/default/private/orders/${id}`,
+});
+
+export const API_LIST_ORDERS: Query<
+  unknown,
+  MerchantBackend.Orders.OrderHistory
+> = {
+  get: "http://backend/instances/default/private/orders";,
+};
+
+export const API_REFUND_ORDER_BY_ID = (
+  id: string
+): Query<
+  MerchantBackend.Orders.RefundRequest,
+  MerchantBackend.Orders.MerchantRefundResponse
+> => ({
+  post: `http://backend/instances/default/private/orders/${id}/refund`,
+});
+
+export const API_FORGET_ORDER_BY_ID = (
+  id: string
+): Query<
+  MerchantBackend.Orders.ForgetRequest,
+  unknown
+> => ({
+  patch: `http://backend/instances/default/private/orders/${id}/forget`,
+});
+
+export const API_DELETE_ORDER = (
+  id: string
+): Query<
+  MerchantBackend.Orders.ForgetRequest,
+  unknown
+> => ({
+  delete: `http://backend/instances/default/private/orders/${id}`,
+});
+
+////////////////////
+// TRANSFER
+////////////////////
+
+export const API_LIST_TRANSFERS: Query<
+  unknown,
+  MerchantBackend.Transfers.TransferList
+> = {
+  get: "http://backend/instances/default/private/transfers";,
+};
+
+export const API_INFORM_TRANSFERS: Query<
+  MerchantBackend.Transfers.TransferInformation,
+  MerchantBackend.Transfers.MerchantTrackTransferResponse
+> = {
+  post: "http://backend/instances/default/private/transfers";,
+};
+
+////////////////////
+// PRODUCT
+////////////////////
+
+export const API_CREATE_PRODUCT: Query<
+  MerchantBackend.Products.ProductAddDetail,
+  unknown
+> = {
+  post: "http://backend/instances/default/private/products";,
+};
+
+export const API_LIST_PRODUCTS: Query<
+  unknown,
+  MerchantBackend.Products.InventorySummaryResponse
+> = {
+  get: "http://backend/instances/default/private/products";,
+};
+
+export const API_GET_PRODUCT_BY_ID = (
+  id: string
+): Query<unknown, MerchantBackend.Products.ProductDetail> => ({
+  get: `http://backend/instances/default/private/products/${id}`,
+});
+
+export const API_UPDATE_PRODUCT_BY_ID = (
+  id: string
+): Query<
+  MerchantBackend.Products.ProductPatchDetail,
+  MerchantBackend.Products.InventorySummaryResponse
+> => ({
+  patch: `http://backend/instances/default/private/products/${id}`,
+});
+
+export const API_DELETE_PRODUCT = (
+  id: string
+): Query<
+  unknown, unknown
+> => ({
+  delete: `http://backend/instances/default/private/products/${id}`,
+});
+
+////////////////////
+// RESERVES
+////////////////////
+
+export const API_CREATE_RESERVE: Query<
+  MerchantBackend.Tips.ReserveCreateRequest,
+  MerchantBackend.Tips.ReserveCreateConfirmation
+> = {
+  post: "http://backend/instances/default/private/reserves";,
+};
+export const API_LIST_RESERVES: Query<
+  unknown,
+  MerchantBackend.Tips.TippingReserveStatus
+> = {
+  get: "http://backend/instances/default/private/reserves";,
+};
+
+export const API_GET_RESERVE_BY_ID = (
+  pub: string
+): Query<unknown, MerchantBackend.Tips.ReserveDetail> => ({
+  get: `http://backend/instances/default/private/reserves/${pub}`,
+});
+
+export const API_GET_TIP_BY_ID = (
+  pub: string
+): Query<
+  unknown,
+  MerchantBackend.Tips.TipDetails
+> => ({
+  get: `http://backend/instances/default/private/tips/${pub}`,
+});
+
+export const API_AUTHORIZE_TIP_FOR_RESERVE = (
+  pub: string
+): Query<
+  MerchantBackend.Tips.TipCreateRequest,
+  MerchantBackend.Tips.TipCreateConfirmation
+> => ({
+  post: 
`http://backend/instances/default/private/reserves/${pub}/authorize-tip`,
+});
+
+export const API_AUTHORIZE_TIP: Query<
+  MerchantBackend.Tips.TipCreateRequest,
+  MerchantBackend.Tips.TipCreateConfirmation
+> = ({
+  post: `http://backend/instances/default/private/tips`,
+});
+
+
+export const API_DELETE_RESERVE = (
+  id: string
+): Query<unknown, unknown> => ({
+  delete: `http://backend/instances/default/private/reserves/${id}`,
+});
+
+
+////////////////////
+// INSTANCE ADMIN
+////////////////////
+
+export const API_CREATE_INSTANCE: Query<
+  MerchantBackend.Instances.InstanceConfigurationMessage,
+  unknown
+> = {
+  post: "http://backend/management/instances";,
+};
+
+export const API_GET_INSTANCE_BY_ID = (
+  id: string
+): Query<
+  unknown,
+  MerchantBackend.Instances.QueryInstancesResponse
+> => ({
+  get: `http://backend/management/instances/${id}`,
+});
+
+export const API_GET_INSTANCE_KYC_BY_ID = (
+  id: string
+): Query<
+  unknown,
+  MerchantBackend.Instances.AccountKycRedirects
+> => ({
+  get: `http://backend/management/instances/${id}/kyc`,
+});
+
+export const API_LIST_INSTANCES: Query<
+  unknown,
+  MerchantBackend.Instances.InstancesResponse
+> = {
+  get: "http://backend/management/instances";,
+};
+
+export const API_UPDATE_INSTANCE_BY_ID = (
+  id: string
+): Query<
+  MerchantBackend.Instances.InstanceReconfigurationMessage,
+  unknown
+> => ({
+  patch: `http://backend/management/instances/${id}`,
+});
+
+export const API_UPDATE_INSTANCE_AUTH_BY_ID = (
+  id: string
+): Query<
+  MerchantBackend.Instances.InstanceAuthConfigurationMessage,
+  unknown
+> => ({
+  post: `http://backend/management/instances/${id}/auth`,
+});
+
+export const API_DELETE_INSTANCE = (
+  id: string
+): Query<unknown, unknown> => ({
+  delete: `http://backend/management/instances/${id}`,
+});
+
+////////////////////
+// INSTANCE 
+////////////////////
+
+export const API_GET_CURRENT_INSTANCE: Query<
+  unknown,
+  MerchantBackend.Instances.QueryInstancesResponse
+> = ({
+  get: `http://backend/instances/default/private/`,
+});
+
+export const API_GET_CURRENT_INSTANCE_KYC: Query<
+  unknown,
+  MerchantBackend.Instances.AccountKycRedirects
+> =
+  ({
+    get: `http://backend/instances/default/private/kyc`,
+  });
+
+export const API_UPDATE_CURRENT_INSTANCE: Query<
+  MerchantBackend.Instances.InstanceReconfigurationMessage,
+  unknown
+> = {
+  patch: `http://backend/instances/default/private/`,
+};
+
+export const API_UPDATE_CURRENT_INSTANCE_AUTH: Query<
+  MerchantBackend.Instances.InstanceAuthConfigurationMessage,
+  unknown
+> = {
+  post: `http://backend/instances/default/private/auth`,
+};
+
+export const API_DELETE_CURRENT_INSTANCE: Query<
+  unknown,
+  unknown
+> = ({
+  delete: `http://backend/instances/default/private`,
+});
+
+
diff --git a/packages/merchant-backoffice-ui/tests/context/backend.test.tsx 
b/packages/merchant-backoffice-ui/tests/context/backend.test.tsx
new file mode 100644
index 000000000..b7b50fd47
--- /dev/null
+++ b/packages/merchant-backoffice-ui/tests/context/backend.test.tsx
@@ -0,0 +1,172 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { renderHook } from "@testing-library/preact-hooks";
+import { ComponentChildren, h, VNode } from "preact";
+import { act } from "preact/test-utils";
+import { BackendContextProvider } from "../../src/context/backend";
+import { InstanceContextProvider } from "../../src/context/instance";
+import { MerchantBackend } from "../../src/declaration";
+import {
+  useAdminAPI,
+  useInstanceAPI,
+  useManagementAPI,
+} from "../../src/hooks/instance";
+import {
+  API_CREATE_INSTANCE,
+  API_GET_CURRENT_INSTANCE,
+  API_UPDATE_CURRENT_INSTANCE_AUTH,
+  API_UPDATE_INSTANCE_AUTH_BY_ID,
+  assertJustExpectedRequestWereMade,
+  AxiosMockEnvironment,
+} from "../axiosMock";
+
+interface TestingContextProps {
+  children?: ComponentChildren;
+}
+
+function TestingContext({ children }: TestingContextProps): VNode {
+  return (
+    <BackendContextProvider defaultUrl="http://backend"; initialToken="token">
+      {children}
+    </BackendContextProvider>
+  );
+}
+function AdminTestingContext({ children }: TestingContextProps): VNode {
+  return (
+    <BackendContextProvider defaultUrl="http://backend"; initialToken="token">
+      <InstanceContextProvider
+        value={{
+          token: "token",
+          id: "default",
+          admin: true,
+          changeToken: () => null,
+        }}
+      >
+        {children}
+      </InstanceContextProvider>
+    </BackendContextProvider>
+  );
+}
+
+describe("backend context api ", () => {
+  it("should use new token after updating the instance token in the settings 
as user", async () => {
+    const env = new AxiosMockEnvironment();
+
+    const { result, waitForNextUpdate } = renderHook(
+      () => {
+        const instance = useInstanceAPI();
+        const management = useManagementAPI("default");
+        const admin = useAdminAPI();
+
+        return { instance, management, admin };
+      },
+      { wrapper: TestingContext }
+    );
+
+    if (!result.current) {
+      expect(result.current).toBeDefined();
+      return;
+    }
+
+    env.addRequestExpectation(API_UPDATE_INSTANCE_AUTH_BY_ID("default"), {
+      request: {
+        method: "token",
+        token: "another_token",
+      },
+      response: {
+        name: "instance_name",
+      } as MerchantBackend.Instances.QueryInstancesResponse,
+    });
+
+    await act(async () => {
+      await result.current?.management.setNewToken("another_token");
+    });
+
+    // await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    env.addRequestExpectation(API_CREATE_INSTANCE, {
+      auth: "Bearer another_token",
+      request: {
+        id: "new_instance_id",
+      } as MerchantBackend.Instances.InstanceConfigurationMessage,
+    });
+
+    result.current.admin.createInstance({
+      id: "new_instance_id",
+    } as MerchantBackend.Instances.InstanceConfigurationMessage);
+
+    assertJustExpectedRequestWereMade(env);
+  });
+
+  it("should use new token after updating the instance token in the settings 
as admin", async () => {
+    const env = new AxiosMockEnvironment();
+
+    const { result, waitForNextUpdate } = renderHook(
+      () => {
+        const instance = useInstanceAPI();
+        const management = useManagementAPI("default");
+        const admin = useAdminAPI();
+
+        return { instance, management, admin };
+      },
+      { wrapper: AdminTestingContext }
+    );
+
+    if (!result.current) {
+      expect(result.current).toBeDefined();
+      return;
+    }
+
+    env.addRequestExpectation(API_UPDATE_CURRENT_INSTANCE_AUTH, {
+      request: {
+        method: "token",
+        token: "another_token",
+      },
+      response: {
+        name: "instance_name",
+      } as MerchantBackend.Instances.QueryInstancesResponse,
+    });
+
+    await act(async () => {
+      await result.current?.instance.setNewToken("another_token");
+    });
+
+    // await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    env.addRequestExpectation(API_CREATE_INSTANCE, {
+      auth: "Bearer another_token",
+      request: {
+        id: "new_instance_id",
+      } as MerchantBackend.Instances.InstanceConfigurationMessage,
+    });
+
+    result.current.admin.createInstance({
+      id: "new_instance_id",
+    } as MerchantBackend.Instances.InstanceConfigurationMessage);
+
+    assertJustExpectedRequestWereMade(env);
+  });
+});
diff --git a/packages/merchant-backoffice-ui/tests/declarations.d.ts 
b/packages/merchant-backoffice-ui/tests/declarations.d.ts
new file mode 100644
index 000000000..61a53dc69
--- /dev/null
+++ b/packages/merchant-backoffice-ui/tests/declarations.d.ts
@@ -0,0 +1,28 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+declare global {
+  namespace jest {
+    interface Matchers<R> {
+      toBeWithinRange(a: number, b: number): R;
+    }
+  }
+}
diff --git a/packages/merchant-backoffice-ui/tests/functions/regex.test.ts 
b/packages/merchant-backoffice-ui/tests/functions/regex.test.ts
new file mode 100644
index 000000000..fc8a6a42f
--- /dev/null
+++ b/packages/merchant-backoffice-ui/tests/functions/regex.test.ts
@@ -0,0 +1,87 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { AMOUNT_REGEX, PAYTO_REGEX } from "../../src/utils/constants";
+
+describe('payto uri format', () => {
+  const valids = [
+    'payto://iban/DE75512108001245126199?amount=EUR:200.0&message=hello',
+    'payto://ach/122000661/1234',
+    'payto://upi/alice@example.com?receiver-name=Alice&amount=INR:200',
+    'payto://void/?amount=EUR:10.5',
+    'payto://ilp/g.acme.bob'
+  ]
+  
+  test('should be valid', () => {
+    valids.forEach(v => expect(v).toMatch(PAYTO_REGEX))
+  });
+  
+  const invalids = [
+    // has two question marks
+    'payto://iban/DE75?512108001245126199?amount=EUR:200.0&message=hello',
+    // has a space
+    'payto://ach /122000661/1234',
+    // has a space
+    'payto://upi/alice@ example.com?receiver-name=Alice&amount=INR:200',
+    // invalid field name (mount instead of amount)
+    'payto://void/?mount=EUR:10.5',
+    // payto:// is incomplete
+    'payto: //ilp/g.acme.bob'
+  ]
+  
+  test('should not be valid', () => {
+    invalids.forEach(v => expect(v).not.toMatch(PAYTO_REGEX))
+  });  
+})
+
+describe('amount format', () => {
+  const valids = [
+    'ARS:10',
+    'COL:10.2',
+    'UY:1,000.2',
+    'ARS:10.123,123',
+    'ARS:1,000,000',
+    'ARSCOL:10',
+    'THISISTHEMOTHERCOIN:1,000,000.123,123',
+  ]
+  
+  test('should be valid', () => {
+    valids.forEach(v => expect(v).toMatch(AMOUNT_REGEX))
+  });
+  
+  const invalids = [
+    //no currency name
+    ':10',
+    //use . instead of ,
+    'ARS:1.000.000',
+    //currency name with numbers
+    '1ARS:10',
+    //currency name with numbers
+    'AR5:10',
+    //missing value
+    'USD:',
+  ]
+  
+  test('should not be valid', () => {
+    invalids.forEach(v => expect(v).not.toMatch(AMOUNT_REGEX))
+  });  
+
+})
\ No newline at end of file
diff --git a/packages/merchant-backoffice-ui/tests/header.test.tsx 
b/packages/merchant-backoffice-ui/tests/header.test.tsx
new file mode 100644
index 000000000..f098b70d5
--- /dev/null
+++ b/packages/merchant-backoffice-ui/tests/header.test.tsx
@@ -0,0 +1,63 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { h } from "preact";
+import { ProductList } from "../src/components/product/ProductList";
+// See: https://github.com/preactjs/enzyme-adapter-preact-pure
+// import { shallow } from 'enzyme';
+import * as backend from "../src/context/config";
+import { render, findAllByText } from "@testing-library/preact";
+import * as i18n from "../src/context/translation";
+
+import * as jedLib from "jed";
+const handler = new jedLib.Jed("en");
+
+describe("Initial Test of the Sidebar", () => {
+  beforeEach(() => {
+    jest
+      .spyOn(backend, "useConfigContext")
+      .mockImplementation(() => ({ version: "", currency: "" }));
+    jest.spyOn(i18n, "useTranslationContext").mockImplementation(() => ({
+      changeLanguage: () => null,
+      handler,
+      lang: "en",
+    }));
+  });
+  test("Product list renders a table", () => {
+    const context = render(
+      <ProductList
+        list={[
+          {
+            description: "description of the product",
+            image: "asdasda",
+            price: "USD:10",
+            quantity: 1,
+            taxes: [{ name: "VAT", tax: "EUR:1" }],
+            unit: "book",
+          },
+        ]}
+      />
+    );
+
+    expect(context.findAllByText("description of the product")).toBeDefined();
+    // expect(context.find('table tr td img').map(img => 
img.prop('src'))).toEqual('');
+  });
+});
diff --git a/packages/merchant-backoffice-ui/tests/hooks/async.test.ts 
b/packages/merchant-backoffice-ui/tests/hooks/async.test.ts
new file mode 100644
index 000000000..a6d0cddfa
--- /dev/null
+++ b/packages/merchant-backoffice-ui/tests/hooks/async.test.ts
@@ -0,0 +1,158 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+import { renderHook } from "@testing-library/preact-hooks"
+import { useAsync } from "../../src/hooks/async"
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+test("async function is called", async () => {
+  jest.useFakeTimers()
+
+  const timeout = 500
+
+  const asyncFunction = jest.fn(() => new Promise((res) => {
+    setTimeout(() => {
+      res({ the_answer: 'yes' })
+    }, timeout);
+  }))
+
+  const { result, waitForNextUpdate } = renderHook(() => {
+    return useAsync(asyncFunction)
+  })
+
+  expect(result.current?.isLoading).toBeFalsy()
+
+  result.current?.request()
+  expect(asyncFunction).toBeCalled()
+  await waitForNextUpdate({ timeout: 1 })
+  expect(result.current?.isLoading).toBeTruthy()
+
+  jest.advanceTimersByTime(timeout + 1)
+  await waitForNextUpdate({ timeout: 1 })
+  expect(result.current?.isLoading).toBeFalsy()
+  expect(result.current?.data).toMatchObject({ the_answer: 'yes' })
+  expect(result.current?.error).toBeUndefined()
+  expect(result.current?.isSlow).toBeFalsy()
+})
+
+test("async function return error if rejected", async () => {
+  jest.useFakeTimers()
+
+  const timeout = 500
+
+  const asyncFunction = jest.fn(() => new Promise((_, rej) => {
+    setTimeout(() => {
+      rej({ the_error: 'yes' })
+    }, timeout);
+  }))
+
+  const { result, waitForNextUpdate } = renderHook(() => {
+    return useAsync(asyncFunction)
+  })
+
+  expect(result.current?.isLoading).toBeFalsy()
+
+  result.current?.request()
+  expect(asyncFunction).toBeCalled()
+  await waitForNextUpdate({ timeout: 1 })
+  expect(result.current?.isLoading).toBeTruthy()
+
+  jest.advanceTimersByTime(timeout + 1)
+  await waitForNextUpdate({ timeout: 1 })
+  expect(result.current?.isLoading).toBeFalsy()
+  expect(result.current?.error).toMatchObject({ the_error: 'yes' })
+  expect(result.current?.data).toBeUndefined()
+  expect(result.current?.isSlow).toBeFalsy()
+})
+
+test("async function is slow", async () => {
+  jest.useFakeTimers()
+
+  const timeout = 2200
+
+  const asyncFunction = jest.fn(() => new Promise((res) => {
+    setTimeout(() => {
+      res({ the_answer: 'yes' })
+    }, timeout);
+  }))
+
+  const { result, waitForNextUpdate } = renderHook(() => {
+    return useAsync(asyncFunction)
+  })
+
+  expect(result.current?.isLoading).toBeFalsy()
+
+  result.current?.request()
+  expect(asyncFunction).toBeCalled()
+  await waitForNextUpdate({ timeout: 1 })
+  expect(result.current?.isLoading).toBeTruthy()
+
+  jest.advanceTimersByTime(timeout / 2)
+  await waitForNextUpdate({ timeout: 1 })
+  expect(result.current?.isLoading).toBeTruthy()
+  expect(result.current?.isSlow).toBeTruthy()
+  expect(result.current?.data).toBeUndefined()
+  expect(result.current?.error).toBeUndefined()
+
+  jest.advanceTimersByTime(timeout / 2)
+  await waitForNextUpdate({ timeout: 1 })
+  expect(result.current?.isLoading).toBeFalsy()
+  expect(result.current?.data).toMatchObject({ the_answer: 'yes' })
+  expect(result.current?.error).toBeUndefined()
+  expect(result.current?.isSlow).toBeFalsy()
+
+})
+
+test("async function is cancellable", async () => {
+  jest.useFakeTimers()
+
+  const timeout = 2200
+
+  const asyncFunction = jest.fn(() => new Promise((res) => {
+    setTimeout(() => {
+      res({ the_answer: 'yes' })
+    }, timeout);
+  }))
+
+  const { result, waitForNextUpdate } = renderHook(() => {
+    return useAsync(asyncFunction)
+  })
+
+  expect(result.current?.isLoading).toBeFalsy()
+
+  result.current?.request()
+  expect(asyncFunction).toBeCalled()
+  await waitForNextUpdate({ timeout: 1 })
+  expect(result.current?.isLoading).toBeTruthy()
+
+  jest.advanceTimersByTime(timeout / 2)
+  await waitForNextUpdate({ timeout: 1 })
+  expect(result.current?.isLoading).toBeTruthy()
+  expect(result.current?.isSlow).toBeTruthy()
+  expect(result.current?.data).toBeUndefined()
+  expect(result.current?.error).toBeUndefined()
+
+  result.current?.cancel()
+  await waitForNextUpdate({ timeout: 1 })
+  expect(result.current?.isLoading).toBeFalsy()
+  expect(result.current?.data).toBeUndefined()
+  expect(result.current?.error).toBeUndefined()
+  expect(result.current?.isSlow).toBeFalsy()
+
+})
diff --git a/packages/merchant-backoffice-ui/tests/hooks/listener.test.ts 
b/packages/merchant-backoffice-ui/tests/hooks/listener.test.ts
new file mode 100644
index 000000000..ae34c1339
--- /dev/null
+++ b/packages/merchant-backoffice-ui/tests/hooks/listener.test.ts
@@ -0,0 +1,62 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { renderHook, act } from '@testing-library/preact-hooks';
+import { useListener } from '../../src/hooks/listener';
+
+// jest.useFakeTimers()
+
+test('listener', async () => {
+
+
+  function createSomeString() {
+    return "hello"
+  }
+  async function addWorldToTheEnd(resultFromComponentB: string) {
+    return `${resultFromComponentB} world`
+  }
+  const expectedResult = "hello world"
+
+  const { result } = renderHook(() => useListener(addWorldToTheEnd))
+
+  if (!result.current) {
+    expect(result.current).toBeDefined()
+    return;
+  }
+
+  {
+    const [activator, subscriber] = result.current
+    expect(activator).toBeUndefined()
+
+    act(() => {
+      subscriber(createSomeString)
+    })
+
+  }
+
+  const [activator] = result.current
+  expect(activator).toBeDefined()
+  if (!activator) return;
+
+  const response = await activator()
+  expect(response).toBe(expectedResult)
+
+});
diff --git a/packages/merchant-backoffice-ui/tests/hooks/notification.test.ts 
b/packages/merchant-backoffice-ui/tests/hooks/notification.test.ts
new file mode 100644
index 000000000..6825a825a
--- /dev/null
+++ b/packages/merchant-backoffice-ui/tests/hooks/notification.test.ts
@@ -0,0 +1,51 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+ /**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { renderHook, act} from '@testing-library/preact-hooks';
+import { useNotifications } from '../../src/hooks/notifications';
+
+jest.useFakeTimers()
+
+test('notification should disapear after timeout', () => {
+  jest.spyOn(global, 'setTimeout');
+
+  const timeout = 1000
+  const { result, rerender } = renderHook(() => useNotifications(undefined, 
timeout));
+
+  expect(result.current?.notifications.length).toBe(0);
+
+  act(() => {
+    result.current?.pushNotification({
+      message: 'some_id',
+      type: 'INFO'
+    });
+  });
+  expect(result.current?.notifications.length).toBe(1);
+
+  jest.advanceTimersByTime(timeout/2);
+  rerender()
+  expect(result.current?.notifications.length).toBe(1);
+
+  jest.advanceTimersByTime(timeout);
+  rerender()
+  expect(result.current?.notifications.length).toBe(0);
+
+});
diff --git a/packages/merchant-backoffice-ui/tests/hooks/swr/index.tsx 
b/packages/merchant-backoffice-ui/tests/hooks/swr/index.tsx
new file mode 100644
index 000000000..44514855d
--- /dev/null
+++ b/packages/merchant-backoffice-ui/tests/hooks/swr/index.tsx
@@ -0,0 +1,45 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { ComponentChildren, h, VNode } from "preact";
+import { SWRConfig } from "swr";
+import { BackendContextProvider } from "../../../src/context/backend";
+import { InstanceContextProvider } from "../../../src/context/instance";
+
+interface TestingContextProps {
+  children?: ComponentChildren;
+}
+export function TestingContext({ children }: TestingContextProps): VNode {
+  return (
+    <BackendContextProvider defaultUrl="http://backend"; initialToken="token">
+      <InstanceContextProvider
+        value={{
+          token: "token",
+          id: "default",
+          admin: true,
+          changeToken: () => null,
+        }}
+      >
+        <SWRConfig value={{ provider: () => new Map() }}>{children}</SWRConfig>
+      </InstanceContextProvider>
+    </BackendContextProvider>
+  );
+}
diff --git a/packages/merchant-backoffice-ui/tests/hooks/swr/instance.test.ts 
b/packages/merchant-backoffice-ui/tests/hooks/swr/instance.test.ts
new file mode 100644
index 000000000..55d9fa6ee
--- /dev/null
+++ b/packages/merchant-backoffice-ui/tests/hooks/swr/instance.test.ts
@@ -0,0 +1,636 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { renderHook } from "@testing-library/preact-hooks";
+import { act } from "preact/test-utils";
+import { MerchantBackend } from "../../../src/declaration";
+import { useAdminAPI, useBackendInstances, useInstanceAPI, useInstanceDetails, 
useManagementAPI } from "../../../src/hooks/instance";
+import {
+  API_CREATE_INSTANCE,
+  API_DELETE_INSTANCE,
+  API_GET_CURRENT_INSTANCE,
+  API_LIST_INSTANCES,
+  API_UPDATE_CURRENT_INSTANCE,
+  API_UPDATE_CURRENT_INSTANCE_AUTH,
+  API_UPDATE_INSTANCE_AUTH_BY_ID,
+  API_UPDATE_INSTANCE_BY_ID,
+  assertJustExpectedRequestWereMade,
+  AxiosMockEnvironment
+} from "../../axiosMock";
+import { TestingContext } from "./index";
+
+describe("instance api interaction with details ", () => {
+
+  it("should evict cache when updating an instance", async () => {
+
+    const env = new AxiosMockEnvironment();
+
+    env.addRequestExpectation(API_GET_CURRENT_INSTANCE, {
+      response: {
+        name: 'instance_name'
+      } as MerchantBackend.Instances.QueryInstancesResponse,
+    });
+
+    const { result, waitForNextUpdate } = renderHook(
+      () => {
+        const api = useInstanceAPI();
+        const query = useInstanceDetails();
+
+        return { query, api };
+      },
+      { wrapper: TestingContext }
+    );
+
+    if (!result.current) {
+      expect(result.current).toBeDefined();
+      return;
+    }
+    expect(result.current.query.loading).toBeTruthy();
+
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      name: 'instance_name'
+    });
+
+    env.addRequestExpectation(API_UPDATE_CURRENT_INSTANCE, {
+      request: {
+        name: 'other_name'
+      } as MerchantBackend.Instances.InstanceReconfigurationMessage,
+    });
+
+    act(async () => {
+      await result.current?.api.updateInstance({
+        name: 'other_name'
+      } as MerchantBackend.Instances.InstanceReconfigurationMessage);
+    });
+
+    assertJustExpectedRequestWereMade(env);
+
+    env.addRequestExpectation(API_GET_CURRENT_INSTANCE, {
+      response: {
+        name: 'other_name'
+      } as MerchantBackend.Instances.QueryInstancesResponse,
+    });
+
+    expect(result.current.query.loading).toBeFalsy();
+
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current.query.ok).toBeTruthy();
+
+    expect(result.current.query.data).toEqual({
+      name: 'other_name'
+    });
+  });
+
+  it("should evict cache when setting the instance's token", async () => {
+    const env = new AxiosMockEnvironment();
+
+    env.addRequestExpectation(API_GET_CURRENT_INSTANCE, {
+      response: {
+        name: 'instance_name',
+        auth: {
+          method: 'token',
+          token: 'not-secret',
+        }
+      } as MerchantBackend.Instances.QueryInstancesResponse,
+    });
+
+    const { result, waitForNextUpdate } = renderHook(
+      () => {
+        const api = useInstanceAPI();
+        const query = useInstanceDetails();
+
+        return { query, api };
+      },
+      { wrapper: TestingContext }
+    );
+
+    if (!result.current) {
+      expect(result.current).toBeDefined();
+      return;
+    }
+    expect(result.current.query.loading).toBeTruthy();
+
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      name: 'instance_name',
+      auth: {
+        method: 'token',
+        token: 'not-secret',
+      }
+    });
+
+    env.addRequestExpectation(API_UPDATE_CURRENT_INSTANCE_AUTH, {
+      request: {
+        method: 'token',
+        token: 'secret'
+      } as MerchantBackend.Instances.InstanceAuthConfigurationMessage,
+    });
+
+    act(async () => {
+      await result.current?.api.setNewToken('secret');
+    });
+
+    assertJustExpectedRequestWereMade(env);
+
+    env.addRequestExpectation(API_GET_CURRENT_INSTANCE, {
+      response: {
+        name: 'instance_name',
+        auth: {
+          method: 'token',
+          token: 'secret',
+        }
+      } as MerchantBackend.Instances.QueryInstancesResponse,
+    });
+
+    expect(result.current.query.loading).toBeFalsy();
+
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current.query.ok).toBeTruthy();
+
+    expect(result.current.query.data).toEqual({
+      name: 'instance_name',
+      auth: {
+        method: 'token',
+        token: 'secret',
+      }
+    });
+  });
+
+  it("should evict cache when clearing the instance's token", async () => {
+    const env = new AxiosMockEnvironment();
+
+    env.addRequestExpectation(API_GET_CURRENT_INSTANCE, {
+      response: {
+        name: 'instance_name',
+        auth: {
+          method: 'token',
+          token: 'not-secret',
+        }
+      } as MerchantBackend.Instances.QueryInstancesResponse,
+    });
+
+    const { result, waitForNextUpdate } = renderHook(
+      () => {
+        const api = useInstanceAPI();
+        const query = useInstanceDetails();
+
+        return { query, api };
+      },
+      { wrapper: TestingContext }
+    );
+
+    if (!result.current) {
+      expect(result.current).toBeDefined();
+      return;
+    }
+    expect(result.current.query.loading).toBeTruthy();
+
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      name: 'instance_name',
+      auth: {
+        method: 'token',
+        token: 'not-secret',
+      }
+    });
+
+    env.addRequestExpectation(API_UPDATE_CURRENT_INSTANCE_AUTH, {
+      request: {
+        method: 'external',
+      } as MerchantBackend.Instances.InstanceAuthConfigurationMessage,
+    });
+
+    act(async () => {
+      await result.current?.api.clearToken();
+    });
+
+    assertJustExpectedRequestWereMade(env);
+
+    env.addRequestExpectation(API_GET_CURRENT_INSTANCE, {
+      response: {
+        name: 'instance_name',
+        auth: {
+          method: 'external',
+        }
+      } as MerchantBackend.Instances.QueryInstancesResponse,
+    });
+
+    expect(result.current.query.loading).toBeFalsy();
+
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current.query.ok).toBeTruthy();
+
+    expect(result.current.query.data).toEqual({
+      name: 'instance_name',
+      auth: {
+        method: 'external',
+      }
+    });
+  });
+});
+
+describe("instance admin api interaction with listing ", () => {
+
+  it("should evict cache when creating a new instance", async () => {
+    const env = new AxiosMockEnvironment();
+
+    env.addRequestExpectation(API_LIST_INSTANCES, {
+      response: {
+        instances: [{
+          name: 'instance_name'
+        } as MerchantBackend.Instances.Instance]
+      },
+    });
+
+    const { result, waitForNextUpdate } = renderHook(
+      () => {
+        const api = useAdminAPI();
+        const query = useBackendInstances();
+
+        return { query, api };
+      },
+      { wrapper: TestingContext }
+    );
+
+    if (!result.current) {
+      expect(result.current).toBeDefined();
+      return;
+    }
+    expect(result.current.query.loading).toBeTruthy();
+
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      instances: [{
+        name: 'instance_name'
+      }]
+    });
+
+    env.addRequestExpectation(API_CREATE_INSTANCE, {
+      request: {
+        name: 'other_name'
+      } as MerchantBackend.Instances.InstanceConfigurationMessage,
+    });
+
+    act(async () => {
+      await result.current?.api.createInstance({
+        name: 'other_name'
+      } as MerchantBackend.Instances.InstanceConfigurationMessage);
+    });
+
+    assertJustExpectedRequestWereMade(env);
+
+    env.addRequestExpectation(API_LIST_INSTANCES, {
+      response: {
+        instances: [{
+          name: 'instance_name'
+        } as MerchantBackend.Instances.Instance,
+        {
+          name: 'other_name'
+        } as MerchantBackend.Instances.Instance]
+      },
+    });
+
+    expect(result.current.query.loading).toBeFalsy();
+
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current.query.ok).toBeTruthy();
+
+    expect(result.current.query.data).toEqual({
+      instances: [{
+        name: 'instance_name'
+      }, {
+        name: 'other_name'
+      }]
+    });
+  });
+
+  it("should evict cache when deleting an instance", async () => {
+    const env = new AxiosMockEnvironment();
+
+    env.addRequestExpectation(API_LIST_INSTANCES, {
+      response: {
+        instances: [{
+          id: 'default',
+          name: 'instance_name'
+        } as MerchantBackend.Instances.Instance,
+        {
+          id: 'the_id',
+          name: 'second_instance'
+        } as MerchantBackend.Instances.Instance]
+      },
+    });
+
+    const { result, waitForNextUpdate } = renderHook(
+      () => {
+        const api = useAdminAPI();
+        const query = useBackendInstances();
+
+        return { query, api };
+      },
+      { wrapper: TestingContext }
+    );
+
+    if (!result.current) {
+      expect(result.current).toBeDefined();
+      return;
+    }
+    expect(result.current.query.loading).toBeTruthy();
+
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      instances: [{
+        id: 'default',
+        name: 'instance_name'
+      }, {
+        id: 'the_id',
+        name: 'second_instance'
+      }]
+    });
+
+    env.addRequestExpectation(API_DELETE_INSTANCE('the_id'), {});
+
+    act(async () => {
+      await result.current?.api.deleteInstance('the_id');
+    });
+
+    assertJustExpectedRequestWereMade(env);
+
+    env.addRequestExpectation(API_LIST_INSTANCES, {
+      response: {
+        instances: [{
+          id: 'default',
+          name: 'instance_name'
+        } as MerchantBackend.Instances.Instance]
+      },
+    });
+
+    expect(result.current.query.loading).toBeFalsy();
+
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current.query.ok).toBeTruthy();
+
+    expect(result.current.query.data).toEqual({
+      instances: [{
+        id: 'default',
+        name: 'instance_name'
+      }]
+    });
+  });
+  it("should evict cache when deleting (purge) an instance", async () => {
+    const env = new AxiosMockEnvironment();
+
+    env.addRequestExpectation(API_LIST_INSTANCES, {
+      response: {
+        instances: [{
+          id: 'default',
+          name: 'instance_name'
+        } as MerchantBackend.Instances.Instance,
+        {
+          id: 'the_id',
+          name: 'second_instance'
+        } as MerchantBackend.Instances.Instance]
+      },
+    });
+
+    const { result, waitForNextUpdate } = renderHook(
+      () => {
+        const api = useAdminAPI();
+        const query = useBackendInstances();
+
+        return { query, api };
+      },
+      { wrapper: TestingContext }
+    );
+
+    if (!result.current) {
+      expect(result.current).toBeDefined();
+      return;
+    }
+    expect(result.current.query.loading).toBeTruthy();
+
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      instances: [{
+        id: 'default',
+        name: 'instance_name'
+      }, {
+        id: 'the_id',
+        name: 'second_instance'
+      }]
+    });
+
+    env.addRequestExpectation(API_DELETE_INSTANCE('the_id'), {
+      qparam: {
+        purge: 'YES'
+      }
+    });
+
+    act(async () => {
+      await result.current?.api.purgeInstance('the_id');
+    });
+
+    assertJustExpectedRequestWereMade(env);
+
+    env.addRequestExpectation(API_LIST_INSTANCES, {
+      response: {
+        instances: [{
+          id: 'default',
+          name: 'instance_name'
+        } as MerchantBackend.Instances.Instance]
+      },
+    });
+
+    expect(result.current.query.loading).toBeFalsy();
+
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current.query.ok).toBeTruthy();
+
+    expect(result.current.query.data).toEqual({
+      instances: [{
+        id: 'default',
+        name: 'instance_name'
+      }]
+    });
+  });
+});
+
+describe("instance management api interaction with listing ", () => {
+
+  it("should evict cache when updating an instance", async () => {
+    const env = new AxiosMockEnvironment();
+
+    env.addRequestExpectation(API_LIST_INSTANCES, {
+      response: {
+        instances: [{
+          id: 'managed',
+          name: 'instance_name'
+        } as MerchantBackend.Instances.Instance]
+      },
+    });
+
+    const { result, waitForNextUpdate } = renderHook(
+      () => {
+        const api = useManagementAPI('managed');
+        const query = useBackendInstances();
+
+        return { query, api };
+      },
+      { wrapper: TestingContext }
+    );
+
+    if (!result.current) {
+      expect(result.current).toBeDefined();
+      return;
+    }
+    expect(result.current.query.loading).toBeTruthy();
+
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      instances: [{
+        id: 'managed',
+        name: 'instance_name'
+      }]
+    });
+
+    env.addRequestExpectation(API_UPDATE_INSTANCE_BY_ID('managed'), {
+      request: {
+        name: 'other_name'
+      } as MerchantBackend.Instances.InstanceReconfigurationMessage,
+    });
+
+    act(async () => {
+      await result.current?.api.updateInstance({
+        name: 'other_name'
+      } as MerchantBackend.Instances.InstanceConfigurationMessage);
+    });
+
+    assertJustExpectedRequestWereMade(env);
+
+    env.addRequestExpectation(API_LIST_INSTANCES, {
+      response: {
+        instances: [
+          {
+            id: 'managed',
+            name: 'other_name'
+          } as MerchantBackend.Instances.Instance]
+      },
+    });
+
+    expect(result.current.query.loading).toBeFalsy();
+
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current.query.ok).toBeTruthy();
+
+    expect(result.current.query.data).toEqual({
+      instances: [{
+        id: 'managed',
+        name: 'other_name'
+      }]
+    });
+  });
+
+});
+
diff --git a/packages/merchant-backoffice-ui/tests/hooks/swr/order.test.ts 
b/packages/merchant-backoffice-ui/tests/hooks/swr/order.test.ts
new file mode 100644
index 000000000..e7f6c9334
--- /dev/null
+++ b/packages/merchant-backoffice-ui/tests/hooks/swr/order.test.ts
@@ -0,0 +1,567 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { renderHook } from "@testing-library/preact-hooks";
+import { act } from "preact/test-utils";
+import { TestingContext } from ".";
+import { MerchantBackend } from "../../../src/declaration";
+import { useInstanceOrders, useOrderAPI, useOrderDetails } from 
"../../../src/hooks/order";
+import {
+  API_CREATE_ORDER,
+  API_DELETE_ORDER,
+  API_FORGET_ORDER_BY_ID,
+  API_GET_ORDER_BY_ID,
+  API_LIST_ORDERS, API_REFUND_ORDER_BY_ID, assertJustExpectedRequestWereMade, 
assertNextRequest, assertNoMoreRequestWereMade, AxiosMockEnvironment
+} from "../../axiosMock";
+
+describe("order api interaction with listing", () => {
+
+  it("should evict cache when creating an order", async () => {
+    const env = new AxiosMockEnvironment();
+
+    env.addRequestExpectation(API_LIST_ORDERS, {
+      qparam: { delta: 0, paid: "yes" },
+      response: {
+        orders: [{ order_id: "1" } as 
MerchantBackend.Orders.OrderHistoryEntry],
+      },
+    });
+
+    env.addRequestExpectation(API_LIST_ORDERS, {
+      qparam: { delta: -20, paid: "yes" },
+      response: {
+        orders: [{ order_id: "2" } as 
MerchantBackend.Orders.OrderHistoryEntry],
+      },
+    });
+
+
+    const { result, waitForNextUpdate } = renderHook(() => {
+      const newDate = (d: Date) => {
+        console.log("new date", d);
+      };
+      const query = useInstanceOrders({ paid: "yes" }, newDate);
+      const api = useOrderAPI();
+
+      return { query, api };
+    }, { wrapper: TestingContext });
+
+    if (!result.current) {
+      expect(result.current).toBeDefined();
+      return;
+    }
+
+    expect(result.current.query.loading).toBeTruthy();
+    await waitForNextUpdate({ timeout: 1 });
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      orders: [{ order_id: "1" }, { order_id: "2" }],
+    });
+
+    env.addRequestExpectation(API_CREATE_ORDER, {
+      request: {
+        order: { amount: "ARS:12", summary: "pay me" },
+      },
+      response: { order_id: "3" },
+    });
+
+    env.addRequestExpectation(API_LIST_ORDERS, {
+      qparam: { delta: 0, paid: "yes" },
+      response: {
+        orders: [{ order_id: "1" } as any],
+      },
+    });
+
+    env.addRequestExpectation(API_LIST_ORDERS, {
+      qparam: { delta: -20, paid: "yes" },
+      response: {
+        orders: [{ order_id: "2" } as any, { order_id: "3" } as any],
+      },
+    });
+
+    act(async () => {
+      await result.current?.api.createOrder({
+        order: { amount: "ARS:12", summary: "pay me" },
+      } as any);
+    });
+
+    await waitForNextUpdate({ timeout: 1 });
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      orders: [{ order_id: "1" }, { order_id: "2" }, { order_id: "3" }],
+    });
+  });
+  it("should evict cache when doing a refund", async () => {
+    const env = new AxiosMockEnvironment();
+
+    env.addRequestExpectation(API_LIST_ORDERS, {
+      qparam: { delta: 0, paid: "yes" },
+      response: {
+        orders: [{ order_id: "1", amount: 'EUR:12', refundable: true } as 
MerchantBackend.Orders.OrderHistoryEntry],
+      },
+    });
+
+    env.addRequestExpectation(API_LIST_ORDERS, {
+      qparam: { delta: -20, paid: "yes" },
+      response: { orders: [], },
+    });
+
+
+    const { result, waitForNextUpdate } = renderHook(() => {
+      const newDate = (d: Date) => {
+        console.log("new date", d);
+      };
+      const query = useInstanceOrders({ paid: "yes" }, newDate);
+      const api = useOrderAPI();
+
+      return { query, api };
+    }, { wrapper: TestingContext });
+
+    if (!result.current) {
+      expect(result.current).toBeDefined();
+      return;
+    }
+
+    expect(result.current.query.loading).toBeTruthy();
+    await waitForNextUpdate({ timeout: 1 });
+    assertJustExpectedRequestWereMade(env);
+
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      orders: [{
+        order_id: "1",
+        amount: 'EUR:12',
+        refundable: true,
+      }],
+    });
+
+    env.addRequestExpectation(API_REFUND_ORDER_BY_ID('1'), {
+      request: {
+        reason: 'double pay',
+        refund: 'EUR:1'
+      },
+    });
+
+    env.addRequestExpectation(API_LIST_ORDERS, {
+      qparam: { delta: 0, paid: "yes" },
+      response: {
+        orders: [{ order_id: "1", amount: 'EUR:12', refundable: false } as 
any],
+      },
+    });
+
+    env.addRequestExpectation(API_LIST_ORDERS, {
+      qparam: { delta: -20, paid: "yes" },
+      response: { orders: [], },
+    });
+
+    act(async () => {
+      await result.current?.api.refundOrder('1', {
+        reason: 'double pay',
+        refund: 'EUR:1'
+      });
+    });
+
+    await waitForNextUpdate({ timeout: 1 });
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      orders: [{
+        order_id: "1",
+        amount: 'EUR:12',
+        refundable: false,
+      }],
+    });
+  });
+  it("should evict cache when deleting an order", async () => {
+    const env = new AxiosMockEnvironment();
+
+    env.addRequestExpectation(API_LIST_ORDERS, {
+      qparam: { delta: 0, paid: "yes" },
+      response: {
+        orders: [{ order_id: "1" } as 
MerchantBackend.Orders.OrderHistoryEntry],
+      },
+    });
+
+    env.addRequestExpectation(API_LIST_ORDERS, {
+      qparam: { delta: -20, paid: "yes" },
+      response: {
+        orders: [{ order_id: "2" } as 
MerchantBackend.Orders.OrderHistoryEntry],
+      },
+    });
+
+
+    const { result, waitForNextUpdate } = renderHook(() => {
+      const newDate = (d: Date) => {
+        console.log("new date", d);
+      };
+      const query = useInstanceOrders({ paid: "yes" }, newDate);
+      const api = useOrderAPI();
+
+      return { query, api };
+    }, { wrapper: TestingContext });
+
+    if (!result.current) {
+      expect(result.current).toBeDefined();
+      return;
+    }
+
+    expect(result.current.query.loading).toBeTruthy();
+    await waitForNextUpdate({ timeout: 1 });
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      orders: [{ order_id: "1" }, { order_id: "2" }],
+    });
+
+    env.addRequestExpectation(API_DELETE_ORDER('1'), {});
+
+    env.addRequestExpectation(API_LIST_ORDERS, {
+      qparam: { delta: 0, paid: "yes" },
+      response: {
+        orders: [],
+      },
+    });
+
+    env.addRequestExpectation(API_LIST_ORDERS, {
+      qparam: { delta: -20, paid: "yes" },
+      response: {
+        orders: [{ order_id: "2" } as any],
+      },
+    });
+
+    act(async () => {
+      await result.current?.api.deleteOrder('1');
+    });
+
+    await waitForNextUpdate({ timeout: 1 });
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      orders: [{ order_id: "2" }],
+    });
+  });
+
+});
+
+describe("order api interaction with details", () => {
+
+  it("should evict cache when doing a refund", async () => {
+    const env = new AxiosMockEnvironment();
+
+    env.addRequestExpectation(API_GET_ORDER_BY_ID('1'), {
+      // qparam: { delta: 0, paid: "yes" },
+      response: {
+        summary: 'description',
+        refund_amount: 'EUR:0',
+      } as unknown as MerchantBackend.Orders.CheckPaymentPaidResponse,
+    });
+
+    const { result, waitForNextUpdate } = renderHook(() => {
+      const query = useOrderDetails('1')
+      const api = useOrderAPI();
+
+      return { query, api };
+    }, { wrapper: TestingContext });
+
+    if (!result.current) {
+      expect(result.current).toBeDefined();
+      return;
+    }
+
+    expect(result.current.query.loading).toBeTruthy();
+    await waitForNextUpdate({ timeout: 1 });
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      summary: 'description',
+      refund_amount: 'EUR:0',
+    });
+
+    env.addRequestExpectation(API_REFUND_ORDER_BY_ID('1'), {
+      request: {
+        reason: 'double pay',
+        refund: 'EUR:1'
+      },
+    });
+
+    env.addRequestExpectation(API_GET_ORDER_BY_ID('1'), {
+      response: {
+        summary: 'description',
+        refund_amount: 'EUR:1',
+      } as unknown as MerchantBackend.Orders.CheckPaymentPaidResponse,
+    });
+
+    act(async () => {
+      await result.current?.api.refundOrder('1', {
+        reason: 'double pay',
+        refund: 'EUR:1'
+      });
+    });
+
+    await waitForNextUpdate({ timeout: 1 });
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      summary: 'description',
+      refund_amount: 'EUR:1',
+    });
+  })
+  it("should evict cache when doing a forget", async () => {
+    const env = new AxiosMockEnvironment();
+
+    env.addRequestExpectation(API_GET_ORDER_BY_ID('1'), {
+      // qparam: { delta: 0, paid: "yes" },
+      response: {
+        summary: 'description',
+        refund_amount: 'EUR:0',
+      } as unknown as MerchantBackend.Orders.CheckPaymentPaidResponse,
+    });
+
+    const { result, waitForNextUpdate } = renderHook(() => {
+      const query = useOrderDetails('1')
+      const api = useOrderAPI();
+
+      return { query, api };
+    }, { wrapper: TestingContext });
+
+    if (!result.current) {
+      expect(result.current).toBeDefined();
+      return;
+    }
+
+    expect(result.current.query.loading).toBeTruthy();
+    await waitForNextUpdate({ timeout: 1 });
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      summary: 'description',
+      refund_amount: 'EUR:0',
+    });
+
+    env.addRequestExpectation(API_FORGET_ORDER_BY_ID('1'), {
+      request: {
+        fields: ['$.summary']
+      },
+    });
+
+    env.addRequestExpectation(API_GET_ORDER_BY_ID('1'), {
+      response: {
+        summary: undefined,
+      } as unknown as MerchantBackend.Orders.CheckPaymentPaidResponse,
+    });
+
+    act(async () => {
+      await result.current?.api.forgetOrder('1', {
+        fields: ['$.summary']
+      });
+    });
+
+    await waitForNextUpdate({ timeout: 1 });
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      summary: undefined,
+    });
+  })
+})
+
+describe("order listing pagination", () => {
+
+  it("should not load more if has reach the end", async () => {
+    const env = new AxiosMockEnvironment();
+    env.addRequestExpectation(API_LIST_ORDERS, {
+      qparam: { delta: 20, wired: "yes", date_ms: 12 },
+      response: {
+        orders: [{ order_id: "1" } as any],
+      },
+    });
+
+    env.addRequestExpectation(API_LIST_ORDERS, {
+      qparam: { delta: -20, wired: "yes", date_ms: 13 },
+      response: {
+        orders: [{ order_id: "2" } as any],
+      },
+    });
+
+
+    const { result, waitForNextUpdate } = renderHook(() => {
+      const newDate = (d: Date) => {
+        console.log("new date", d);
+      };
+      const date = new Date(12);
+      const query = useInstanceOrders({ wired: "yes", date }, newDate)
+      return { query }
+    }, { wrapper: TestingContext });
+
+    assertJustExpectedRequestWereMade(env);
+
+    await waitForNextUpdate();
+
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      orders: [{ order_id: "1" }, { order_id: "2" }],
+    });
+
+    expect(result.current.query.isReachingEnd).toBeTruthy()
+    expect(result.current.query.isReachingStart).toBeTruthy()
+
+    await act(() => {
+      if (!result.current?.query.ok) throw Error("not ok");
+      result.current.query.loadMore();
+    });
+    assertNoMoreRequestWereMade(env);
+
+    await act(() => {
+      if (!result.current?.query.ok) throw Error("not ok");
+      result.current.query.loadMorePrev();
+    });
+    assertNoMoreRequestWereMade(env);
+
+    expect(result.current.query.data).toEqual({
+      orders: [
+        { order_id: "1" },
+        { order_id: "2" },
+      ],
+    });
+  });
+
+  it("should load more if result brings more that PAGE_SIZE", async () => {
+    const env = new AxiosMockEnvironment();
+
+    const ordersFrom0to20 = Array.from({ length: 20 }).map((e, i) => ({ 
order_id: String(i) }))
+    const ordersFrom20to40 = Array.from({ length: 20 }).map((e, i) => ({ 
order_id: String(i + 20) }))
+    const ordersFrom20to0 = [...ordersFrom0to20].reverse()
+
+    env.addRequestExpectation(API_LIST_ORDERS, {
+      qparam: { delta: 20, wired: "yes", date_ms: 12 },
+      response: {
+        orders: ordersFrom0to20,
+      },
+    });
+
+    env.addRequestExpectation(API_LIST_ORDERS, {
+      qparam: { delta: -20, wired: "yes", date_ms: 13 },
+      response: {
+        orders: ordersFrom20to40,
+      },
+    });
+
+    const { result, waitForNextUpdate } = renderHook(() => {
+      const newDate = (d: Date) => {
+        console.log("new date", d);
+      };
+      const date = new Date(12);
+      const query = useInstanceOrders({ wired: "yes", date }, newDate)
+      return { query }
+    }, { wrapper: TestingContext });
+
+    assertJustExpectedRequestWereMade(env);
+
+    await waitForNextUpdate({ timeout: 1 });
+
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      orders: [...ordersFrom20to0, ...ordersFrom20to40],
+    });
+
+    expect(result.current.query.isReachingEnd).toBeFalsy()
+    expect(result.current.query.isReachingStart).toBeFalsy()
+
+    env.addRequestExpectation(API_LIST_ORDERS, {
+      qparam: { delta: -40, wired: "yes", date_ms: 13 },
+      response: {
+        orders: [...ordersFrom20to40, { order_id: '41' }],
+      },
+    });
+
+    await act(() => {
+      if (!result.current?.query.ok) throw Error("not ok");
+      result.current.query.loadMore();
+    });
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    env.addRequestExpectation(API_LIST_ORDERS, {
+      qparam: { delta: 40, wired: "yes", date_ms: 12 },
+      response: {
+        orders: [...ordersFrom0to20, { order_id: '-1' }],
+      },
+    });
+
+    await act(() => {
+      if (!result.current?.query.ok) throw Error("not ok");
+      result.current.query.loadMorePrev();
+    });
+    await waitForNextUpdate({ timeout: 1 });
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.data).toEqual({
+      orders: [{ order_id: '-1' }, ...ordersFrom20to0, ...ordersFrom20to40, { 
order_id: '41' }],
+    });
+  });
+
+
+});
diff --git a/packages/merchant-backoffice-ui/tests/hooks/swr/product.test.ts 
b/packages/merchant-backoffice-ui/tests/hooks/swr/product.test.ts
new file mode 100644
index 000000000..5d39a7c47
--- /dev/null
+++ b/packages/merchant-backoffice-ui/tests/hooks/swr/product.test.ts
@@ -0,0 +1,338 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { renderHook } from "@testing-library/preact-hooks";
+import { act } from "preact/test-utils";
+import { TestingContext } from ".";
+import { MerchantBackend } from "../../../src/declaration";
+import { useInstanceProducts, useProductAPI, useProductDetails } from 
"../../../src/hooks/product";
+import {
+  API_CREATE_PRODUCT,
+  API_DELETE_PRODUCT, API_GET_PRODUCT_BY_ID,
+  API_LIST_PRODUCTS,
+  API_UPDATE_PRODUCT_BY_ID,
+  assertJustExpectedRequestWereMade,
+  assertNextRequest,
+  AxiosMockEnvironment
+} from "../../axiosMock";
+
+describe("product api interaction with listing ", () => {
+  it("should evict cache when creating a product", async () => {
+    const env = new AxiosMockEnvironment();
+
+    env.addRequestExpectation(API_LIST_PRODUCTS, {
+      response: {
+        products: [{ product_id: "1234" }],
+      },
+    });
+    env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), {
+      response: { price: "ARS:12" } as MerchantBackend.Products.ProductDetail,
+    });
+
+    const { result, waitForNextUpdate } = renderHook(
+      () => {
+        const query = useInstanceProducts();
+        const api = useProductAPI();
+        return { api, query };
+      },
+      { wrapper: TestingContext }
+    ); // get products -> loading
+
+    if (!result.current) {
+      expect(result.current).toBeDefined();
+      return;
+    }
+    expect(result.current.query.loading).toBeTruthy();
+    await waitForNextUpdate({ timeout: 1 });
+
+    await waitForNextUpdate({ timeout: 1 });
+    assertJustExpectedRequestWereMade(env);
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual([
+      { id: "1234", price: "ARS:12" },
+    ]);
+
+    env.addRequestExpectation(API_CREATE_PRODUCT, {
+      request: { price: "ARS:23" } as 
MerchantBackend.Products.ProductAddDetail,
+    });
+
+    env.addRequestExpectation(API_LIST_PRODUCTS, {
+      response: {
+        products: [{ product_id: "1234" }, { product_id: "2345" }],
+      },
+    });
+    env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), {
+      response: { price: "ARS:12" } as MerchantBackend.Products.ProductDetail,
+    });
+    env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), {
+      response: { price: "ARS:12" } as MerchantBackend.Products.ProductDetail,
+    });
+    env.addRequestExpectation(API_GET_PRODUCT_BY_ID("2345"), {
+      response: { price: "ARS:23" } as MerchantBackend.Products.ProductDetail,
+    });
+
+    act(async () => {
+      await result.current?.api.createProduct({
+        price: "ARS:23",
+      } as any);
+    });
+
+    assertNextRequest(env);
+    await waitForNextUpdate({ timeout: 1 });
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual([
+      {
+        id: "1234",
+        price: "ARS:12",
+      },
+      {
+        id: "2345",
+        price: "ARS:23",
+      },
+    ]);
+  });
+
+  it("should evict cache when updating a product", async () => {
+    const env = new AxiosMockEnvironment();
+
+    env.addRequestExpectation(API_LIST_PRODUCTS, {
+      response: {
+        products: [{ product_id: "1234" }],
+      },
+    });
+    env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), {
+      response: { price: "ARS:12" } as MerchantBackend.Products.ProductDetail,
+    });
+
+    const { result, waitForNextUpdate } = renderHook(
+      () => {
+        const query = useInstanceProducts();
+        const api = useProductAPI();
+        return { api, query };
+      },
+      { wrapper: TestingContext }
+    ); // get products -> loading
+
+    if (!result.current) {
+      expect(result.current).toBeDefined();
+      return;
+    }
+    expect(result.current.query.loading).toBeTruthy();
+    await waitForNextUpdate({ timeout: 1 });
+
+    await waitForNextUpdate({ timeout: 1 });
+    assertJustExpectedRequestWereMade(env);
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual([
+      { id: "1234", price: "ARS:12" },
+    ]);
+
+    env.addRequestExpectation(API_UPDATE_PRODUCT_BY_ID("1234"), {
+      request: { price: "ARS:13" } as 
MerchantBackend.Products.ProductPatchDetail,
+    });
+
+    env.addRequestExpectation(API_LIST_PRODUCTS, {
+      response: {
+        products: [{ product_id: "1234" }],
+      },
+    });
+    env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), {
+      response: { price: "ARS:13" } as MerchantBackend.Products.ProductDetail,
+    });
+
+    act(async () => {
+      await result.current?.api.updateProduct("1234", {
+        price: "ARS:13",
+      } as any);
+    });
+
+    assertNextRequest(env);
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual([
+      {
+        id: "1234",
+        price: "ARS:13",
+      },
+    ]);
+  });
+
+  it("should evict cache when deleting a product", async () => {
+    const env = new AxiosMockEnvironment();
+
+    env.addRequestExpectation(API_LIST_PRODUCTS, {
+      response: {
+        products: [{ product_id: "1234" }, { product_id: "2345" }],
+      },
+    });
+    env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), {
+      response: { price: "ARS:12" } as MerchantBackend.Products.ProductDetail,
+    });
+    env.addRequestExpectation(API_GET_PRODUCT_BY_ID("2345"), {
+      response: { price: "ARS:23" } as MerchantBackend.Products.ProductDetail,
+    });
+
+    const { result, waitForNextUpdate } = renderHook(
+      () => {
+        const query = useInstanceProducts();
+        const api = useProductAPI();
+        return { api, query };
+      },
+      { wrapper: TestingContext }
+    ); // get products -> loading
+
+    if (!result.current) {
+      expect(result.current).toBeDefined();
+      return;
+    }
+    expect(result.current.query.loading).toBeTruthy();
+    await waitForNextUpdate({ timeout: 1 });
+
+    await waitForNextUpdate({ timeout: 1 });
+    // await waitForNextUpdate({ timeout: 1 });
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual([
+      { id: "1234", price: "ARS:12" },
+      { id: "2345", price: "ARS:23" },
+    ]);
+
+    env.addRequestExpectation(API_DELETE_PRODUCT("2345"), {});
+
+    env.addRequestExpectation(API_LIST_PRODUCTS, {
+      response: {
+        products: [{ product_id: "1234" }],
+      },
+    });
+    env.addRequestExpectation(API_GET_PRODUCT_BY_ID("1234"), {
+      response: { price: "ARS:13" } as MerchantBackend.Products.ProductDetail,
+    });
+
+    act(async () => {
+      await result.current?.api.deleteProduct("2345");
+    });
+
+    assertNextRequest(env);
+    await waitForNextUpdate({ timeout: 1 });
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual([
+      {
+        id: "1234",
+        price: "ARS:13",
+      },
+    ]);
+  });
+
+});
+
+describe("product api interaction with details", () => {
+  it("should evict cache when updating a product", async () => {
+    const env = new AxiosMockEnvironment();
+
+    env.addRequestExpectation(API_GET_PRODUCT_BY_ID("12"), {
+      response: {
+        description: "this is a description",
+      } as MerchantBackend.Products.ProductDetail,
+    });
+
+    const { result, waitForNextUpdate } = renderHook(() => {
+      const query = useProductDetails("12");
+      const api = useProductAPI();
+      return { query, api };
+    }, { wrapper: TestingContext });
+
+    if (!result.current) {
+      expect(result.current).toBeDefined();
+      return;
+    }
+    expect(result.current.query.loading).toBeTruthy();
+    await waitForNextUpdate();
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      description: "this is a description",
+    });
+
+    env.addRequestExpectation(API_UPDATE_PRODUCT_BY_ID("12"), {
+      request: { description: "other description" } as 
MerchantBackend.Products.ProductPatchDetail,
+    });
+
+    env.addRequestExpectation(API_GET_PRODUCT_BY_ID("12"), {
+      response: {
+        description: "other description",
+      } as MerchantBackend.Products.ProductDetail,
+    });
+
+    act(async () => {
+      return await result.current?.api.updateProduct("12", {
+        description: "other description",
+      } as any);
+    });
+
+    assertNextRequest(env);
+    await waitForNextUpdate();
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      description: "other description",
+    });
+  })
+})
\ No newline at end of file
diff --git a/packages/merchant-backoffice-ui/tests/hooks/swr/reserve.test.ts 
b/packages/merchant-backoffice-ui/tests/hooks/swr/reserve.test.ts
new file mode 100644
index 000000000..0361c54e8
--- /dev/null
+++ b/packages/merchant-backoffice-ui/tests/hooks/swr/reserve.test.ts
@@ -0,0 +1,470 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { renderHook } from "@testing-library/preact-hooks";
+import { act } from "preact/test-utils";
+import { MerchantBackend } from "../../../src/declaration";
+import {
+  useInstanceReserves,
+  useReserveDetails,
+  useReservesAPI,
+  useTipDetails,
+} from "../../../src/hooks/reserves";
+import {
+  API_AUTHORIZE_TIP,
+  API_AUTHORIZE_TIP_FOR_RESERVE,
+  API_CREATE_RESERVE,
+  API_DELETE_RESERVE,
+  API_GET_RESERVE_BY_ID,
+  API_GET_TIP_BY_ID,
+  API_LIST_RESERVES,
+  assertJustExpectedRequestWereMade,
+  AxiosMockEnvironment,
+} from "../../axiosMock";
+import { TestingContext } from "./index";
+
+describe("reserve api interaction with listing ", () => {
+  it("should evict cache when creating a reserve", async () => {
+    const env = new AxiosMockEnvironment();
+
+    env.addRequestExpectation(API_LIST_RESERVES, {
+      response: {
+        reserves: [
+          {
+            reserve_pub: "11",
+          } as MerchantBackend.Tips.ReserveStatusEntry,
+        ],
+      },
+    });
+
+    const { result, waitForNextUpdate } = renderHook(
+      () => {
+        const api = useReservesAPI();
+        const query = useInstanceReserves();
+
+        return { query, api };
+      },
+      { wrapper: TestingContext }
+    );
+
+    if (!result.current) {
+      expect(result.current).toBeDefined();
+      return;
+    }
+    expect(result.current.query.loading).toBeTruthy();
+
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      reserves: [{ reserve_pub: "11" }],
+    });
+
+    env.addRequestExpectation(API_CREATE_RESERVE, {
+      request: {
+        initial_balance: "ARS:3333",
+        exchange_url: "http://url";,
+        wire_method: "iban",
+      },
+      response: {
+        reserve_pub: "22",
+        payto_uri: "payto",
+      },
+    });
+
+    act(async () => {
+      await result.current?.api.createReserve({
+        initial_balance: "ARS:3333",
+        exchange_url: "http://url";,
+        wire_method: "iban",
+      });
+      return;
+    });
+
+    assertJustExpectedRequestWereMade(env);
+
+    env.addRequestExpectation(API_LIST_RESERVES, {
+      response: {
+        reserves: [
+          {
+            reserve_pub: "11",
+          } as MerchantBackend.Tips.ReserveStatusEntry,
+          {
+            reserve_pub: "22",
+          } as MerchantBackend.Tips.ReserveStatusEntry,
+        ],
+      },
+    });
+
+    expect(result.current.query.loading).toBeFalsy();
+
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current.query.ok).toBeTruthy();
+
+    expect(result.current.query.data).toEqual({
+      reserves: [
+        {
+          reserve_pub: "11",
+        } as MerchantBackend.Tips.ReserveStatusEntry,
+        {
+          reserve_pub: "22",
+        } as MerchantBackend.Tips.ReserveStatusEntry,
+      ],
+    });
+  });
+
+  it("should evict cache when deleting a reserve", async () => {
+    const env = new AxiosMockEnvironment();
+
+    env.addRequestExpectation(API_LIST_RESERVES, {
+      response: {
+        reserves: [
+          {
+            reserve_pub: "11",
+          } as MerchantBackend.Tips.ReserveStatusEntry,
+          {
+            reserve_pub: "22",
+          } as MerchantBackend.Tips.ReserveStatusEntry,
+          {
+            reserve_pub: "33",
+          } as MerchantBackend.Tips.ReserveStatusEntry,
+        ],
+      },
+    });
+
+    const { result, waitForNextUpdate } = renderHook(
+      () => {
+        const api = useReservesAPI();
+        const query = useInstanceReserves();
+
+        return { query, api };
+      },
+      {
+        wrapper: TestingContext,
+      }
+    );
+
+    if (!result.current) {
+      expect(result.current).toBeDefined();
+      return;
+    }
+    expect(result.current.query.loading).toBeTruthy();
+
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      reserves: [
+        { reserve_pub: "11" },
+        { reserve_pub: "22" },
+        { reserve_pub: "33" },
+      ],
+    });
+
+    env.addRequestExpectation(API_DELETE_RESERVE("11"), {});
+
+    act(async () => {
+      await result.current?.api.deleteReserve("11");
+      return;
+    });
+
+    assertJustExpectedRequestWereMade(env);
+
+    env.addRequestExpectation(API_LIST_RESERVES, {
+      response: {
+        reserves: [
+          {
+            reserve_pub: "22",
+          } as MerchantBackend.Tips.ReserveStatusEntry,
+          {
+            reserve_pub: "33",
+          } as MerchantBackend.Tips.ReserveStatusEntry,
+        ],
+      },
+    });
+
+    expect(result.current.query.loading).toBeFalsy();
+
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current.query.ok).toBeTruthy();
+
+    expect(result.current.query.data).toEqual({
+      reserves: [
+        {
+          reserve_pub: "22",
+        } as MerchantBackend.Tips.ReserveStatusEntry,
+        {
+          reserve_pub: "33",
+        } as MerchantBackend.Tips.ReserveStatusEntry,
+      ],
+    });
+  });
+});
+
+describe("reserve api interaction with details", () => {
+  it("should evict cache when adding a tip for a specific reserve", async () 
=> {
+    const env = new AxiosMockEnvironment();
+
+    env.addRequestExpectation(API_GET_RESERVE_BY_ID("11"), {
+      response: {
+        payto_uri: "payto://here",
+        tips: [{ reason: "why?", tip_id: "id1", total_amount: "USD:10" }],
+      } as MerchantBackend.Tips.ReserveDetail,
+    });
+
+    const { result, waitForNextUpdate } = renderHook(
+      () => {
+        const api = useReservesAPI();
+        const query = useReserveDetails("11");
+
+        return { query, api };
+      },
+      {
+        wrapper: TestingContext,
+      }
+    );
+
+    if (!result.current) {
+      expect(result.current).toBeDefined();
+      return;
+    }
+    expect(result.current.query.loading).toBeTruthy();
+
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      payto_uri: "payto://here",
+      tips: [{ reason: "why?", tip_id: "id1", total_amount: "USD:10" }],
+    });
+
+    env.addRequestExpectation(API_AUTHORIZE_TIP_FOR_RESERVE("11"), {
+      request: {
+        amount: "USD:12",
+        justification: "not",
+        next_url: "http://taler.net";,
+      },
+      response: {
+        tip_id: "id2",
+        taler_tip_uri: "uri",
+        tip_expiration: { t_s: 1 },
+        tip_status_url: "url",
+      },
+    });
+
+    act(async () => {
+      await result.current?.api.authorizeTipReserve("11", {
+        amount: "USD:12",
+        justification: "not",
+        next_url: "http://taler.net";,
+      });
+    });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+
+    env.addRequestExpectation(API_GET_RESERVE_BY_ID("11"), {
+      response: {
+        payto_uri: "payto://here",
+        tips: [
+          { reason: "why?", tip_id: "id1", total_amount: "USD:10" },
+          { reason: "not", tip_id: "id2", total_amount: "USD:12" },
+        ],
+      } as MerchantBackend.Tips.ReserveDetail,
+    });
+
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current.query.ok).toBeTruthy();
+
+    expect(result.current.query.data).toEqual({
+      payto_uri: "payto://here",
+      tips: [
+        { reason: "why?", tip_id: "id1", total_amount: "USD:10" },
+        { reason: "not", tip_id: "id2", total_amount: "USD:12" },
+      ],
+    });
+  });
+
+  it("should evict cache when adding a tip for a random reserve", async () => {
+    const env = new AxiosMockEnvironment();
+
+    env.addRequestExpectation(API_GET_RESERVE_BY_ID("11"), {
+      response: {
+        payto_uri: "payto://here",
+        tips: [{ reason: "why?", tip_id: "id1", total_amount: "USD:10" }],
+      } as MerchantBackend.Tips.ReserveDetail,
+    });
+
+    const { result, waitForNextUpdate } = renderHook(
+      () => {
+        const api = useReservesAPI();
+        const query = useReserveDetails("11");
+
+        return { query, api };
+      },
+      {
+        wrapper: TestingContext,
+      }
+    );
+
+    if (!result.current) {
+      expect(result.current).toBeDefined();
+      return;
+    }
+    expect(result.current.query.loading).toBeTruthy();
+
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      payto_uri: "payto://here",
+      tips: [{ reason: "why?", tip_id: "id1", total_amount: "USD:10" }],
+    });
+
+    env.addRequestExpectation(API_AUTHORIZE_TIP, {
+      request: {
+        amount: "USD:12",
+        justification: "not",
+        next_url: "http://taler.net";,
+      },
+      response: {
+        tip_id: "id2",
+        taler_tip_uri: "uri",
+        tip_expiration: { t_s: 1 },
+        tip_status_url: "url",
+      },
+    });
+
+    act(async () => {
+      await result.current?.api.authorizeTip({
+        amount: "USD:12",
+        justification: "not",
+        next_url: "http://taler.net";,
+      });
+    });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+
+    env.addRequestExpectation(API_GET_RESERVE_BY_ID("11"), {
+      response: {
+        payto_uri: "payto://here",
+        tips: [
+          { reason: "why?", tip_id: "id1", total_amount: "USD:10" },
+          { reason: "not", tip_id: "id2", total_amount: "USD:12" },
+        ],
+      } as MerchantBackend.Tips.ReserveDetail,
+    });
+
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current.query.ok).toBeTruthy();
+
+    expect(result.current.query.data).toEqual({
+      payto_uri: "payto://here",
+      tips: [
+        { reason: "why?", tip_id: "id1", total_amount: "USD:10" },
+        { reason: "not", tip_id: "id2", total_amount: "USD:12" },
+      ],
+    });
+  });
+});
+
+describe("reserve api interaction with tip details", () => {
+  it("should list tips", async () => {
+    const env = new AxiosMockEnvironment();
+
+    env.addRequestExpectation(API_GET_TIP_BY_ID("11"), {
+      response: {
+        total_picked_up: "USD:12",
+        reason: "not",
+      } as MerchantBackend.Tips.TipDetails,
+    });
+
+    const { result, waitForNextUpdate } = renderHook(
+      () => {
+        // const api = useReservesAPI();
+        const query = useTipDetails("11");
+
+        return { query };
+      },
+      {
+        wrapper: TestingContext,
+      }
+    );
+
+    if (!result.current) {
+      expect(result.current).toBeDefined();
+      return;
+    }
+    expect(result.current.query.loading).toBeTruthy();
+
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      total_picked_up: "USD:12",
+      reason: "not",
+    });
+  });
+});
diff --git a/packages/merchant-backoffice-ui/tests/hooks/swr/transfer.test.ts 
b/packages/merchant-backoffice-ui/tests/hooks/swr/transfer.test.ts
new file mode 100644
index 000000000..612cf8842
--- /dev/null
+++ b/packages/merchant-backoffice-ui/tests/hooks/swr/transfer.test.ts
@@ -0,0 +1,268 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { act, renderHook } from "@testing-library/preact-hooks";
+import { TestingContext } from "./index";
+import { useInstanceTransfers, useTransferAPI } from 
"../../../src/hooks/transfer";
+import {
+  API_INFORM_TRANSFERS,
+  API_LIST_TRANSFERS,
+  assertJustExpectedRequestWereMade,
+  assertNoMoreRequestWereMade,
+  AxiosMockEnvironment,
+} from "../../axiosMock";
+import { MerchantBackend } from "../../../src/declaration";
+
+describe("transfer api interaction with listing", () => {
+
+  it("should evict cache when informing a transfer", async () => {
+    const env = new AxiosMockEnvironment();
+
+    env.addRequestExpectation(API_LIST_TRANSFERS, {
+      qparam: { limit: 0 },
+      response: {
+        transfers: [{ wtid: "2" } as 
MerchantBackend.Transfers.TransferDetails],
+      },
+    });
+    // FIXME: is this query really needed? if the hook is rendered without
+    // position argument then then backend is returning the newest and no need
+    // to this second query 
+    env.addRequestExpectation(API_LIST_TRANSFERS, {
+      qparam: { limit: -20 },
+      response: {
+        transfers: [],
+      },
+    });
+
+    const { result, waitForNextUpdate } = renderHook(() => {
+      const moveCursor = (d: string) => {
+        console.log("new position", d);
+      };
+      const query = useInstanceTransfers({}, moveCursor);
+      const api = useTransferAPI();
+
+      return { query, api };
+    }, { wrapper: TestingContext });
+
+    if (!result.current) {
+      expect(result.current).toBeDefined();
+      return;
+    }
+
+    expect(result.current.query.loading).toBeTruthy();
+    await waitForNextUpdate({ timeout: 1 });
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current.query.ok).toBeTruthy();
+    if (!result.current.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      transfers: [{ wtid: "2" }],
+    });
+
+    env.addRequestExpectation(API_INFORM_TRANSFERS, {
+      request: {
+        wtid: '3',
+        credit_amount: 'EUR:1',
+        exchange_url: 'exchange.url',
+        payto_uri: 'payto://'
+      },
+      response: { total: '' } as any,
+    });
+
+    env.addRequestExpectation(API_LIST_TRANSFERS, {
+      qparam: { limit: 0 },
+      response: {
+        transfers: [{ wtid: "2" } as any, { wtid: "3" } as any],
+      },
+    });
+
+    env.addRequestExpectation(API_LIST_TRANSFERS, {
+      qparam: { limit: -20 },
+      response: {
+        transfers: [],
+      },
+    });
+
+    act(async () => {
+      await result.current?.api.informTransfer({
+        wtid: '3',
+        credit_amount: 'EUR:1',
+        exchange_url: 'exchange.url',
+        payto_uri: 'payto://'
+      });
+    });
+
+    await waitForNextUpdate({ timeout: 1 });
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.loading).toBeFalsy();
+    expect(result.current.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      transfers: [{ wtid: "3" }, { wtid: "2" }],
+    });
+  });
+
+});
+
+describe("transfer listing pagination", () => {
+
+  it("should not load more if has reach the end", async () => {
+    const env = new AxiosMockEnvironment();
+    env.addRequestExpectation(API_LIST_TRANSFERS, {
+      qparam: { limit: 0, payto_uri: 'payto://' },
+      response: {
+        transfers: [{ wtid: "2" } as any],
+      },
+    });
+
+    env.addRequestExpectation(API_LIST_TRANSFERS, {
+      qparam: { limit: -20, payto_uri: 'payto://' },
+      response: {
+        transfers: [{ wtid: "1" } as any],
+      },
+    });
+
+
+    const { result, waitForNextUpdate } = renderHook(() => {
+      const moveCursor = (d: string) => {
+        console.log("new position", d);
+      };
+      const query = useInstanceTransfers({ payto_uri: 'payto://' }, moveCursor)
+      return { query }
+    }, { wrapper: TestingContext });
+
+    assertJustExpectedRequestWereMade(env);
+
+    await waitForNextUpdate();
+
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      transfers: [{ wtid: "2" }, { wtid: "1" }],
+    });
+
+    expect(result.current.query.isReachingEnd).toBeTruthy()
+    expect(result.current.query.isReachingStart).toBeTruthy()
+
+    await act(() => {
+      if (!result.current?.query.ok) throw Error("not ok");
+      result.current.query.loadMore();
+    });
+    assertNoMoreRequestWereMade(env);
+
+    await act(() => {
+      if (!result.current?.query.ok) throw Error("not ok");
+      result.current.query.loadMorePrev();
+    });
+    assertNoMoreRequestWereMade(env);
+
+    expect(result.current.query.data).toEqual({
+      transfers: [
+        { wtid: "2" },
+        { wtid: "1" },
+      ],
+    });
+  });
+
+  it("should load more if result brings more that PAGE_SIZE", async () => {
+    const env = new AxiosMockEnvironment();
+
+    const transfersFrom0to20 = Array.from({ length: 20 }).map((e, i) => ({ 
wtid: String(i) }))
+    const transfersFrom20to40 = Array.from({ length: 20 }).map((e, i) => ({ 
wtid: String(i + 20) }))
+    const transfersFrom20to0 = [...transfersFrom0to20].reverse()
+
+    env.addRequestExpectation(API_LIST_TRANSFERS, {
+      qparam: { limit: 20, payto_uri: 'payto://' },
+      response: {
+        transfers: transfersFrom0to20,
+      },
+    });
+
+    env.addRequestExpectation(API_LIST_TRANSFERS, {
+      qparam: { limit: -20, payto_uri: 'payto://' },
+      response: {
+        transfers: transfersFrom20to40,
+      },
+    });
+
+    const { result, waitForNextUpdate } = renderHook(() => {
+      const moveCursor = (d: string) => {
+        console.log("new position", d);
+      };
+      const query = useInstanceTransfers({ payto_uri: 'payto://', position: 
'1' }, moveCursor)
+      return { query }
+    }, { wrapper: TestingContext });
+
+    assertJustExpectedRequestWereMade(env);
+
+    await waitForNextUpdate({ timeout: 1 });
+
+    expect(result.current?.query.ok).toBeTruthy();
+    if (!result.current?.query.ok) return;
+
+    expect(result.current.query.data).toEqual({
+      transfers: [...transfersFrom20to0, ...transfersFrom20to40],
+    });
+
+    expect(result.current.query.isReachingEnd).toBeFalsy()
+    expect(result.current.query.isReachingStart).toBeFalsy()
+
+    env.addRequestExpectation(API_LIST_TRANSFERS, {
+      qparam: { limit: -40, payto_uri: 'payto://', offset: "1" },
+      response: {
+        transfers: [...transfersFrom20to40, { wtid: '41' }],
+      },
+    });
+
+    await act(() => {
+      if (!result.current?.query.ok) throw Error("not ok");
+      result.current.query.loadMore();
+    });
+    await waitForNextUpdate({ timeout: 1 });
+
+    assertJustExpectedRequestWereMade(env);
+
+    env.addRequestExpectation(API_LIST_TRANSFERS, {
+      qparam: { limit: 40, payto_uri: 'payto://', offset: "1" },
+      response: {
+        transfers: [...transfersFrom0to20, { wtid: '-1' }],
+      },
+    });
+
+    await act(() => {
+      if (!result.current?.query.ok) throw Error("not ok");
+      result.current.query.loadMorePrev();
+    });
+    await waitForNextUpdate({ timeout: 1 });
+    assertJustExpectedRequestWereMade(env);
+
+    expect(result.current.query.data).toEqual({
+      transfers: [{ wtid: '-1' }, ...transfersFrom20to0, 
...transfersFrom20to40, { wtid: '41' }],
+    });
+  });
+
+
+});
diff --git a/packages/merchant-backoffice-ui/tests/stories.test.tsx 
b/packages/merchant-backoffice-ui/tests/stories.test.tsx
new file mode 100644
index 000000000..5fb3483d2
--- /dev/null
+++ b/packages/merchant-backoffice-ui/tests/stories.test.tsx
@@ -0,0 +1,89 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+import { h, VNode } from "preact";
+import * as config from "../src/context/config";
+import * as i18n from "../src/context/translation";
+import { cleanup, render as originalRender } from "@testing-library/preact";
+import { SWRConfig } from "swr";
+
+import fs from "fs";
+
+function getFiles(dir: string, files_: string[] = []) {
+  const files = fs.readdirSync(dir);
+  for (const i in files) {
+    const name = dir + "/" + files[i];
+    if (fs.statSync(name).isDirectory()) {
+      getFiles(name, files_);
+    } else {
+      files_.push(name);
+    }
+  }
+  return files_;
+}
+
+const STORIES_NAME_REGEX = RegExp(".*.stories.tsx");
+
+function render(vnode: VNode) {
+  return originalRender(
+    <SWRConfig
+      value={{
+        provider: () => new Map(),
+      }}
+    >
+      {vnode}
+    </SWRConfig>
+  );
+}
+
+import * as jedLib from "jed";
+const handler = new jedLib.Jed("en");
+
+describe("storybook testing", () => {
+  it("render every story", () => {
+    jest
+      .spyOn(config, "useConfigContext")
+      .mockImplementation(() => ({ version: "1.0.0", currency: "EUR" }));
+    jest.spyOn(i18n, "useTranslationContext").mockImplementation(() => ({
+      changeLanguage: () => null,
+      handler,
+      lang: "en",
+    }));
+
+    getFiles("./src")
+      .filter((f) => STORIES_NAME_REGEX.test(f))
+      .map((f) => {
+        // const f = "./src/paths/instance/transfers/list/List.stories.tsx";
+        // eslint-disable-next-line @typescript-eslint/no-var-requires
+        const s = require(`../${f}`);
+
+        delete s.default;
+        Object.keys(s).forEach((k) => {
+          const Component = s[k];
+          const vdom = <Component {...Component.args} />;
+          expect(() => {
+            const { unmount } = render(vdom);
+            unmount();
+          }).not.toThrow(); //`problem rendering ${f} example ${k}`
+          cleanup();
+        });
+      });
+  });
+});
diff --git a/packages/merchant-backoffice-ui/tsconfig.json 
b/packages/merchant-backoffice-ui/tsconfig.json
new file mode 100644
index 000000000..dfb87582a
--- /dev/null
+++ b/packages/merchant-backoffice-ui/tsconfig.json
@@ -0,0 +1,61 @@
+{
+    "compilerOptions": {
+        /* Basic Options */
+        "target": "ES5",                          /* Specify ECMAScript target 
version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
+        "module": "ESNext",                       /* Specify module code 
generation: 'none', commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
+        // "lib": [],                             /* Specify library files to 
be included in the compilation:  */
+        "allowJs": true,                          /* Allow javascript files to 
be compiled. */
+        // "checkJs": true,                       /* Report errors in .js 
files. */
+        "jsx": "react",                           /* Specify JSX code 
generation: 'preserve', 'react-native', or 'react'. */
+        "jsxFactory": "h",                        /* Specify the JSX factory 
function to use when targeting react JSX emit, e.g. React.createElement or h. */
+        "jsxFragmentFactory": "Fragment",         // 
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-0.html#custom-jsx-factories
+        // "declaration": true,                   /* Generates corresponding 
'.d.ts' file. */
+        // "sourceMap": true,                     /* Generates corresponding 
'.map' file. */
+        // "outFile": "./",                       /* Concatenate and emit 
output to single file. */
+        // "outDir": "./",                        /* Redirect output structure 
to the directory. */
+        // "rootDir": "./",                       /* Specify the root 
directory of input files. Use to control the output directory structure with 
--outDir. */
+        // "removeComments": true,                /* Do not emit comments to 
output. */
+        "noEmit": true,                           /* Do not emit outputs. */
+        // "importHelpers": true,                 /* Import emit helpers from 
'tslib'. */
+        // "downlevelIteration": true,            /* Provide full support for 
iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. 
*/
+        // "isolatedModules": true,               /* Transpile each file as a 
separate module (similar to 'ts.transpileModule'). */
+
+        /* Strict Type-Checking Options */
+        "strict": true,                           /* Enable all strict 
type-checking options. */
+        // "noImplicitAny": true,                 /* Raise error on 
expressions and declarations with an implied 'any' type. */
+        // "strictNullChecks": true,              /* Enable strict null 
checks. */
+        // "noImplicitThis": true,                /* Raise error on 'this' 
expressions with an implied 'any' type. */
+        // "alwaysStrict": true,                  /* Parse in strict mode and 
emit "use strict" for each source file. */
+
+        /* Additional Checks */
+        // "noUnusedLocals": true,                /* Report errors on unused 
locals. */
+        // "noUnusedParameters": true,            /* Report errors on unused 
parameters. */
+        // "noImplicitReturns": true,             /* Report error when not all 
code paths in function return a value. */
+        // "noFallthroughCasesInSwitch": true,    /* Report errors for 
fallthrough cases in switch statement. */
+
+        /* Module Resolution Options */
+        "moduleResolution": "node",               /* Specify module resolution 
strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
+        "esModuleInterop": true,                  /* */
+        // "baseUrl": "./",                       /* Base directory to resolve 
non-absolute module names. */
+        // "paths": {},                           /* A series of entries which 
re-map imports to lookup locations relative to the 'baseUrl'. */
+        // "rootDirs": [],                        /* List of root folders 
whose combined content represents the structure of the project at runtime. */
+        // "typeRoots": [],                       /* List of folders to 
include type definitions from. */
+        // "types": [],                           /* Type declaration files to 
be included in compilation. */
+        // "allowSyntheticDefaultImports": true,  /* Allow default imports 
from modules with no default export. This does not affect code emit, just 
typechecking. */
+        // "preserveSymlinks": true,              /* Do not resolve the real 
path of symlinks. */
+
+        /* Source Map Options */
+        // "sourceRoot": "./",                    /* Specify the location 
where debugger should locate TypeScript files instead of source locations. */
+        // "mapRoot": "./",                       /* Specify the location 
where debugger should locate map files instead of generated locations. */
+        // "inlineSourceMap": true,               /* Emit a single file with 
source maps instead of having a separate file. */
+        // "inlineSources": true,                 /* Emit the source alongside 
the sourcemaps within a single file; requires '--inlineSourceMap' or 
'--sourceMap' to be set. */
+
+        /* Experimental Options */
+        // "experimentalDecorators": true,        /* Enables experimental 
support for ES7 decorators. */
+        // "emitDecoratorMetadata": true,         /* Enables experimental 
support for emitting type metadata for decorators. */
+
+        /* Advanced Options */
+        "skipLibCheck": true                      /* Skip type checking of 
declaration files. */
+    },
+    "include": ["src/**/*", "tests/**/*"]
+}
diff --git 
a/packages/taler-wallet-cli/src/integrationtests/test-clause-schnorr.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-clause-schnorr.ts
index 5a84866ac..bf42dc4c6 100644
--- a/packages/taler-wallet-cli/src/integrationtests/test-clause-schnorr.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-clause-schnorr.ts
@@ -93,5 +93,5 @@ export async function runClauseSchnorrTest(t: 
GlobalTestState) {
   await wallet.runUntilDone();
 }
 
-runClauseSchnorrTest.suites = ["wallet"];
+runClauseSchnorrTest.suites = ["experimental-wallet"];
 runClauseSchnorrTest.excludeByDefault = true;
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 8e506d65f..6aa8ce202 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -90,6 +90,115 @@ importers:
       typescript: 4.8.4
       ws: 7.4.5
 
+  packages/demobank-ui:
+    specifiers:
+      '@babel/core': ^7.13.16
+      '@babel/plugin-transform-react-jsx': ^7.12.13
+      '@babel/plugin-transform-react-jsx-source': ^7.12.13
+      '@babel/preset-env': ^7.16.7
+      '@creativebulma/bulma-tooltip': ^1.2.0
+      '@gnu-taler/pogen': ^0.0.5
+      '@storybook/addon-a11y': 6.2.9
+      '@storybook/addon-actions': 6.2.9
+      '@storybook/addon-essentials': 6.2.9
+      '@storybook/addon-links': 6.2.9
+      '@storybook/preact': 6.2.9
+      '@storybook/preset-scss': ^1.0.3
+      '@testing-library/jest-dom': ^5.16.1
+      '@testing-library/preact': ^2.0.1
+      '@testing-library/preact-hooks': ^1.1.0
+      '@types/enzyme': ^3.10.10
+      '@types/jest': ^27.0.2
+      '@typescript-eslint/eslint-plugin': ^5.3.0
+      '@typescript-eslint/parser': ^5.3.0
+      babel-loader: ^8.2.2
+      base64-inline-loader: 1.1.1
+      bulma: ^0.9.3
+      bulma-checkbox: ^1.1.1
+      bulma-radio: ^1.1.1
+      date-fns: 2.25.0
+      enzyme: ^3.11.0
+      enzyme-adapter-preact-pure: ^3.2.0
+      eslint: ^8.1.0
+      eslint-config-preact: ^1.2.0
+      html-webpack-inline-chunk-plugin: ^1.1.1
+      html-webpack-inline-source-plugin: 0.0.10
+      html-webpack-skip-assets-plugin: ^1.0.1
+      inline-chunk-html-plugin: ^1.1.1
+      jed: 1.1.1
+      jest: ^27.3.1
+      jest-environment-jsdom: ^27.4.6
+      jest-fetch-mock: ^3.0.3
+      jest-preset-preact: ^4.0.5
+      jest-watch-typeahead: ^1.0.0
+      jssha: ^3.2.0
+      po2json: ^0.4.5
+      preact: ^10.5.15
+      preact-cli: 3.0.5
+      preact-render-to-string: ^5.1.19
+      preact-router: ^3.2.1
+      qrcode-generator: ^1.4.4
+      sass: 1.32.13
+      sass-loader: ^10
+      script-ext-html-webpack-plugin: ^2.1.5
+      sirv-cli: ^1.0.14
+      swr: '1.1'
+      typescript: ^4.4.4
+    dependencies:
+      base64-inline-loader: 1.1.1
+      date-fns: 2.25.0
+      jed: 1.1.1
+      preact: 10.6.5
+      preact-render-to-string: 5.1.19_preact@10.6.5
+      preact-router: 3.2.1_preact@10.6.5
+      qrcode-generator: 1.4.4
+      swr: 1.1.2
+    devDependencies:
+      '@babel/core': 7.17.2
+      '@babel/plugin-transform-react-jsx': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-transform-react-jsx-source': 7.14.5_@babel+core@7.17.2
+      '@babel/preset-env': 7.16.11_@babel+core@7.17.2
+      '@creativebulma/bulma-tooltip': 1.2.0
+      '@gnu-taler/pogen': link:../pogen
+      '@storybook/addon-a11y': 6.2.9
+      '@storybook/addon-actions': 6.2.9
+      '@storybook/addon-essentials': 6.2.9_dtgd2mm6ybnh5irau5bfapxhdy
+      '@storybook/addon-links': 6.2.9
+      '@storybook/preact': 6.2.9_lmcptaky2e4dapkymvnphph734
+      '@storybook/preset-scss': 1.0.3_sass-loader@10.3.1
+      '@testing-library/jest-dom': 5.16.5
+      '@testing-library/preact': 2.0.1_preact@10.6.5
+      '@testing-library/preact-hooks': 1.1.0_vfcmu6iy7nffpurikpgxo6gwxi
+      '@types/enzyme': 3.10.12
+      '@types/jest': 27.5.2
+      '@typescript-eslint/eslint-plugin': 5.36.1_gjcw3hhr2cxnngiu5lw4bi633m
+      '@typescript-eslint/parser': 5.36.1_o2nrgn6wwxunlqlzzokx4es3q4
+      babel-loader: 8.2.3_@babel+core@7.17.2
+      bulma: 0.9.3
+      bulma-checkbox: 1.2.1
+      bulma-radio: 1.2.0
+      enzyme: 3.11.0
+      enzyme-adapter-preact-pure: 3.4.0_fh4cerfcdrs5uit63qwkqtrfyi
+      eslint: 8.8.0
+      eslint-config-preact: 1.3.0_w4k36q7phb5aratcwbohw6kmxe
+      html-webpack-inline-chunk-plugin: 1.1.1
+      html-webpack-inline-source-plugin: 0.0.10
+      html-webpack-skip-assets-plugin: 1.0.3
+      inline-chunk-html-plugin: 1.1.1
+      jest: 27.5.1
+      jest-environment-jsdom: 27.5.1
+      jest-fetch-mock: 3.0.3
+      jest-preset-preact: 4.0.5_e2p4bsvs32uygapo46tobni7si
+      jest-watch-typeahead: 1.1.0_jest@27.5.1
+      jssha: 3.2.0
+      po2json: 0.4.5
+      preact-cli: 3.0.5_ka7slmjrdyz4arupkjrkg4jzfm
+      sass: 1.32.13
+      sass-loader: 10.3.1_sass@1.32.13
+      script-ext-html-webpack-plugin: 2.1.5
+      sirv-cli: 1.0.14
+      typescript: 4.8.4
+
   packages/idb-bridge:
     specifiers:
       '@types/node': ^18.8.5
@@ -109,6 +218,290 @@ importers:
       rimraf: 3.0.2
       typescript: 4.8.4
 
+  packages/merchant-backend-ui:
+    specifiers:
+      '@babel/core': ^7.13.16
+      '@babel/plugin-transform-react-jsx-source': ^7.12.13
+      '@creativebulma/bulma-tooltip': ^1.2.0
+      '@gnu-taler/pogen': ^0.0.5
+      '@gnu-taler/taler-util': workspace:*
+      '@linaria/babel-preset': ^3.0.0-beta.4
+      '@linaria/core': ^3.0.0-beta.4
+      '@linaria/react': ^3.0.0-beta.7
+      '@linaria/rollup': ^3.0.0-beta.7
+      '@linaria/shaker': ^3.0.0-beta.7
+      '@linaria/webpack-loader': ^3.0.0-beta.7
+      '@rollup/plugin-alias': ^3.1.5
+      '@rollup/plugin-babel': ^5.3.0
+      '@rollup/plugin-commonjs': ^20.0.0
+      '@rollup/plugin-html': ^0.2.3
+      '@rollup/plugin-image': ^2.1.1
+      '@rollup/plugin-json': ^4.1.0
+      '@rollup/plugin-replace': ^3.0.0
+      '@rollup/plugin-typescript': ^8.2.5
+      '@storybook/addon-a11y': ^6.2.9
+      '@storybook/addon-actions': ^6.2.9
+      '@storybook/addon-essentials': ^6.2.9
+      '@storybook/addon-links': ^6.2.9
+      '@storybook/preact': ^6.2.9
+      '@storybook/preset-scss': ^1.0.3
+      '@testing-library/preact': ^2.0.1
+      '@testing-library/preact-hooks': ^1.1.0
+      '@types/enzyme': ^3.10.8
+      '@types/history': ^4.7.8
+      '@types/jest': ^26.0.23
+      '@types/mocha': ^8.2.2
+      '@types/mustache': ^4.1.2
+      '@typescript-eslint/eslint-plugin': ^4.22.0
+      '@typescript-eslint/parser': ^4.22.0
+      axios: ^0.21.1
+      babel-loader: ^8.2.2
+      base64-inline-loader: ^1.1.1
+      bulma: ^0.9.2
+      bulma-checkbox: ^1.1.1
+      bulma-radio: ^1.1.1
+      bulma-responsive-tables: ^1.2.3
+      bulma-switch-control: ^1.1.1
+      bulma-timeline: ^3.0.4
+      bulma-upload-control: ^1.2.0
+      date-fns: ^2.21.1
+      dotenv: ^8.2.0
+      enzyme: ^3.11.0
+      enzyme-adapter-preact-pure: ^3.1.0
+      eslint: ^7.25.0
+      eslint-config-preact: ^1.1.4
+      eslint-plugin-header: ^3.1.1
+      history: 4.10.1
+      html-webpack-inline-chunk-plugin: ^1.1.1
+      html-webpack-inline-source-plugin: 0.0.10
+      html-webpack-skip-assets-plugin: ^1.0.1
+      inline-chunk-html-plugin: ^1.1.1
+      jed: ^1.1.1
+      jest: ^26.6.3
+      jest-preset-preact: ^4.0.2
+      mustache: ^4.2.0
+      po2json: ^0.4.5
+      preact: ^10.5.13
+      preact-cli: ^3.0.5
+      preact-render-to-json: ^3.6.6
+      preact-render-to-string: ^5.1.19
+      preact-router: ^3.2.1
+      qrcode-generator: ^1.4.4
+      rimraf: ^3.0.2
+      rollup: ^2.56.3
+      rollup-plugin-bundle-html: ^0.2.2
+      rollup-plugin-css-only: ^3.1.0
+      sass: ^1.32.13
+      sass-loader: 10.1.1
+      script-ext-html-webpack-plugin: ^2.1.5
+      sirv-cli: ^1.0.11
+      swr: ^0.5.5
+      tslib: ^2.3.1
+      typedoc: ^0.20.36
+      typescript: ^4.2.4
+      yup: ^0.32.9
+    dependencies:
+      '@gnu-taler/taler-util': link:../taler-util
+      axios: 0.21.4
+      date-fns: 2.29.2
+      history: 4.10.1
+      jed: 1.1.1
+      preact: 10.6.5
+      preact-router: 3.2.1_preact@10.6.5
+      qrcode-generator: 1.4.4
+      swr: 0.5.7
+      yup: 0.32.11
+    devDependencies:
+      '@babel/core': 7.17.2
+      '@babel/plugin-transform-react-jsx-source': 7.14.5_@babel+core@7.17.2
+      '@creativebulma/bulma-tooltip': 1.2.0
+      '@gnu-taler/pogen': link:../pogen
+      '@linaria/babel-preset': 3.0.0-beta.15_@babel+core@7.17.2
+      '@linaria/core': 3.0.0-beta.15
+      '@linaria/react': 3.0.0-beta.22
+      '@linaria/rollup': 3.0.0-beta.23
+      '@linaria/shaker': 3.0.0-beta.15_@babel+core@7.17.2
+      '@linaria/webpack-loader': 3.0.0-beta.23
+      '@rollup/plugin-alias': 3.1.9_rollup@2.79.0
+      '@rollup/plugin-babel': 5.3.0_lubkdqoa5gexe4rox23cswxwm4
+      '@rollup/plugin-commonjs': 20.0.0_rollup@2.79.0
+      '@rollup/plugin-html': 0.2.4_rollup@2.79.0
+      '@rollup/plugin-image': 2.1.1_rollup@2.79.0
+      '@rollup/plugin-json': 4.1.0_rollup@2.79.0
+      '@rollup/plugin-replace': 3.1.0_rollup@2.79.0
+      '@rollup/plugin-typescript': 8.5.0_jnsxykt6ocebvgsxrxe2hsbo6y
+      '@storybook/addon-a11y': 6.5.13
+      '@storybook/addon-actions': 6.5.13
+      '@storybook/addon-essentials': 6.5.13_t6isvk4c5wetct53pn5ufojx2u
+      '@storybook/addon-links': 6.5.13
+      '@storybook/preact': 6.5.13_rv7hwuimljxvhghl3f4jocbf4q
+      '@storybook/preset-scss': 1.0.3_sass-loader@10.1.1
+      '@testing-library/preact': 2.0.1_preact@10.6.5
+      '@testing-library/preact-hooks': 1.1.0_vfcmu6iy7nffpurikpgxo6gwxi
+      '@types/enzyme': 3.10.12
+      '@types/history': 4.7.9
+      '@types/jest': 26.0.24
+      '@types/mocha': 8.2.3
+      '@types/mustache': 4.2.1
+      '@typescript-eslint/eslint-plugin': 4.33.0_k4l66av2tbo6kxzw52jzgbfzii
+      '@typescript-eslint/parser': 4.33.0_3rubbgt5ekhqrcgx4uwls3neim
+      babel-loader: 8.2.3_@babel+core@7.17.2
+      base64-inline-loader: 1.1.1
+      bulma: 0.9.3
+      bulma-checkbox: 1.2.1
+      bulma-radio: 1.2.0
+      bulma-responsive-tables: 1.2.5
+      bulma-switch-control: 1.2.2
+      bulma-timeline: 3.0.5
+      bulma-upload-control: 1.2.0
+      dotenv: 8.6.0
+      enzyme: 3.11.0
+      enzyme-adapter-preact-pure: 3.4.0_fh4cerfcdrs5uit63qwkqtrfyi
+      eslint: 7.32.0
+      eslint-config-preact: 1.3.0_nxlzr75jbqkso2fds5zjovs2ii
+      eslint-plugin-header: 3.1.1_eslint@7.32.0
+      html-webpack-inline-chunk-plugin: 1.1.1
+      html-webpack-inline-source-plugin: 0.0.10
+      html-webpack-skip-assets-plugin: 1.0.3
+      inline-chunk-html-plugin: 1.1.1
+      jest: 26.6.3
+      jest-preset-preact: 4.0.5_ewndwes2ovzexxcig72sj2dfke
+      mustache: 4.2.0
+      po2json: 0.4.5
+      preact-cli: 3.3.5_p6ocopta3zc4zccdbpyllaobd4
+      preact-render-to-json: 3.6.6_preact@10.6.5
+      preact-render-to-string: 5.1.19_preact@10.6.5
+      rimraf: 3.0.2
+      rollup: 2.79.0
+      rollup-plugin-bundle-html: 0.2.2
+      rollup-plugin-css-only: 3.1.0_rollup@2.79.0
+      sass: 1.32.13
+      sass-loader: 10.1.1_sass@1.32.13
+      script-ext-html-webpack-plugin: 2.1.5
+      sirv-cli: 1.0.14
+      tslib: 2.4.0
+      typedoc: 0.20.37_typescript@4.8.4
+      typescript: 4.8.4
+
+  packages/merchant-backoffice-ui:
+    specifiers:
+      '@babel/core': ^7.13.16
+      '@babel/plugin-transform-react-jsx-source': ^7.12.13
+      '@creativebulma/bulma-tooltip': ^1.2.0
+      '@gnu-taler/pogen': ^0.0.5
+      '@gnu-taler/taler-util': workspace:*
+      '@storybook/addon-a11y': ^6.2.9
+      '@storybook/addon-actions': ^6.2.9
+      '@storybook/addon-essentials': ^6.2.9
+      '@storybook/addon-links': ^6.2.9
+      '@storybook/preact': ^6.2.9
+      '@storybook/preset-scss': ^1.0.3
+      '@testing-library/preact': ^2.0.1
+      '@testing-library/preact-hooks': ^1.1.0
+      '@types/history': ^4.7.8
+      '@types/jest': ^26.0.23
+      '@types/mocha': ^8.2.2
+      '@typescript-eslint/eslint-plugin': ^4.22.0
+      '@typescript-eslint/parser': ^4.22.0
+      axios: ^0.21.1
+      babel-loader: ^8.2.2
+      base64-inline-loader: ^1.1.1
+      bulma: ^0.9.2
+      bulma-checkbox: ^1.1.1
+      bulma-radio: ^1.1.1
+      bulma-responsive-tables: ^1.2.3
+      bulma-switch-control: ^1.1.1
+      bulma-timeline: ^3.0.4
+      bulma-upload-control: ^1.2.0
+      date-fns: ^2.21.1
+      dotenv: ^8.2.0
+      eslint: ^7.25.0
+      eslint-config-preact: ^1.1.4
+      eslint-plugin-header: ^3.1.1
+      history: 4.10.1
+      html-webpack-inline-chunk-plugin: ^1.1.1
+      html-webpack-inline-source-plugin: 0.0.10
+      html-webpack-skip-assets-plugin: ^1.0.1
+      inline-chunk-html-plugin: ^1.1.1
+      jed: ^1.1.1
+      jest: ^26.6.3
+      jest-preset-preact: ^4.0.2
+      po2json: ^0.4.5
+      preact: 10.6.1
+      preact-cli: ^3.0.5
+      preact-render-to-json: ^3.6.6
+      preact-render-to-string: ^5.1.19
+      preact-router: ^3.2.1
+      qrcode-generator: ^1.4.4
+      rimraf: ^3.0.2
+      sass: ^1.32.13
+      sass-loader: 10.1.1
+      script-ext-html-webpack-plugin: ^2.1.5
+      sirv-cli: ^1.0.11
+      swr: 1.1.0
+      typedoc: ^0.20.36
+      typescript: ^4.2.4
+      yup: ^0.32.9
+    dependencies:
+      '@gnu-taler/taler-util': link:../taler-util
+      axios: 0.21.4
+      date-fns: 2.29.2
+      history: 4.10.1
+      jed: 1.1.1
+      preact: 10.6.1
+      preact-router: 3.2.1_preact@10.6.1
+      qrcode-generator: 1.4.4
+      swr: 1.1.0
+      yup: 0.32.11
+    devDependencies:
+      '@babel/core': 7.17.2
+      '@babel/plugin-transform-react-jsx-source': 7.14.5_@babel+core@7.17.2
+      '@creativebulma/bulma-tooltip': 1.2.0
+      '@gnu-taler/pogen': link:../pogen
+      '@storybook/addon-a11y': 6.5.13
+      '@storybook/addon-actions': 6.5.13
+      '@storybook/addon-essentials': 6.5.13_t6isvk4c5wetct53pn5ufojx2u
+      '@storybook/addon-links': 6.5.13
+      '@storybook/preact': 6.5.13_pzutvqtg2sm6mgs5je6xwivarm
+      '@storybook/preset-scss': 1.0.3_sass-loader@10.1.1
+      '@testing-library/preact': 2.0.1_preact@10.6.1
+      '@testing-library/preact-hooks': 1.1.0_p7poi7nh2j5v3fg73wd3em3ise
+      '@types/history': 4.7.9
+      '@types/jest': 26.0.24
+      '@types/mocha': 8.2.3
+      '@typescript-eslint/eslint-plugin': 4.33.0_k4l66av2tbo6kxzw52jzgbfzii
+      '@typescript-eslint/parser': 4.33.0_3rubbgt5ekhqrcgx4uwls3neim
+      babel-loader: 8.2.3_@babel+core@7.17.2
+      base64-inline-loader: 1.1.1
+      bulma: 0.9.3
+      bulma-checkbox: 1.2.1
+      bulma-radio: 1.2.0
+      bulma-responsive-tables: 1.2.5
+      bulma-switch-control: 1.2.2
+      bulma-timeline: 3.0.5
+      bulma-upload-control: 1.2.0
+      dotenv: 8.6.0
+      eslint: 7.32.0
+      eslint-config-preact: 1.3.0_nxlzr75jbqkso2fds5zjovs2ii
+      eslint-plugin-header: 3.1.1_eslint@7.32.0
+      html-webpack-inline-chunk-plugin: 1.1.1
+      html-webpack-inline-source-plugin: 0.0.10
+      html-webpack-skip-assets-plugin: 1.0.3
+      inline-chunk-html-plugin: 1.1.1
+      jest: 26.6.3
+      jest-preset-preact: 4.0.5_5pwcttm7mk4uq46yrrfyt2sdyu
+      po2json: 0.4.5
+      preact-cli: 3.3.5_4lrkxlnsyltikzdya2zqvxqmyq
+      preact-render-to-json: 3.6.6_preact@10.6.1
+      preact-render-to-string: 5.1.19_preact@10.6.1
+      rimraf: 3.0.2
+      sass: 1.32.13
+      sass-loader: 10.1.1_sass@1.32.13
+      script-ext-html-webpack-plugin: 2.1.5
+      sirv-cli: 1.0.14
+      typedoc: 0.20.37_typescript@4.8.4
+      typescript: 4.8.4
+
   packages/pogen:
     specifiers:
       '@types/node': ^18.8.5
@@ -361,11 +754,15 @@ importers:
 
 packages:
 
+  /@adobe/css-tools/4.0.1:
+    resolution: {integrity: 
sha512-+u76oB43nOHrF4DDWRLWDCtci7f3QJoEBigemIdIeTi1ODqjx6Tad9NCVnPRwewWlKkVab5PlK8DCtPTyX7S8g==}
+    dev: true
+
   /@ampproject/remapping/2.1.0:
     resolution: {integrity: 
sha512-d5RysTlJ7hmw5Tw4UxgxcY3lkMe92n8sXCcuLPAyIAHK6j8DefDwtGnVVDgOnv+RnEosulDJ9NPKQL27bDId0g==}
     engines: {node: '>=6.0.0'}
     dependencies:
-      '@jridgewell/trace-mapping': 0.3.4
+      '@jridgewell/trace-mapping': 0.3.13
     dev: true
 
   /@apideck/better-ajv-errors/0.3.3_ajv@8.10.0:
@@ -388,6 +785,18 @@ packages:
       execa: 5.1.1
     dev: true
 
+  /@babel/code-frame/7.10.4:
+    resolution: {integrity: 
sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==}
+    dependencies:
+      '@babel/highlight': 7.18.6
+    dev: true
+
+  /@babel/code-frame/7.12.11:
+    resolution: {integrity: 
sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==}
+    dependencies:
+      '@babel/highlight': 7.16.10
+    dev: true
+
   /@babel/code-frame/7.16.7:
     resolution: {integrity: 
sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==}
     engines: {node: '>=6.9.0'}
@@ -395,11 +804,47 @@ packages:
       '@babel/highlight': 7.16.10
     dev: true
 
+  /@babel/code-frame/7.18.6:
+    resolution: {integrity: 
sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/highlight': 7.18.6
+    dev: true
+
   /@babel/compat-data/7.17.0:
     resolution: {integrity: 
sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==}
     engines: {node: '>=6.9.0'}
     dev: true
 
+  /@babel/compat-data/7.19.4:
+    resolution: {integrity: 
sha512-CHIGpJcUQ5lU9KrPHTjBMhVwQG6CQjxfg36fGXl3qk/Gik1WwWachaXFuo0uCWJT/mStOKtcbFJCaVLihC1CMw==}
+    engines: {node: '>=6.9.0'}
+    dev: true
+
+  /@babel/core/7.12.9:
+    resolution: {integrity: 
sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/code-frame': 7.18.6
+      '@babel/generator': 7.19.6
+      '@babel/helper-module-transforms': 7.19.6
+      '@babel/helpers': 7.19.4
+      '@babel/parser': 7.19.6
+      '@babel/template': 7.18.10
+      '@babel/traverse': 7.19.6
+      '@babel/types': 7.19.4
+      convert-source-map: 1.8.0
+      debug: 4.3.4
+      gensync: 1.0.0-beta.2
+      json5: 2.2.1
+      lodash: 4.17.21
+      resolve: 1.22.1
+      semver: 5.7.1
+      source-map: 0.5.7
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /@babel/core/7.13.16:
     resolution: {integrity: 
sha512-sXHpixBiWWFti0AV2Zq7avpTasr6sIAu7Y396c608541qAU2ui4a193m0KSQmfPSKFZLnQ3cvlKDOm3XkuXm3Q==}
     engines: {node: '>=6.9.0'}
@@ -423,57 +868,85 @@ packages:
       - supports-color
     dev: true
 
-  /@babel/core/7.16.7:
-    resolution: {integrity: 
sha512-aeLaqcqThRNZYmbMqtulsetOQZ/5gbR/dWruUCJcpas4Qoyy+QeagfDsPdMrqwsPRDNxJvBlRiZxxX7THO7qtA==}
+  /@babel/core/7.17.2:
+    resolution: {integrity: 
sha512-R3VH5G42VSDolRHyUO4V2cfag8WHcZyxdq5Z/m8Xyb92lW/Erm/6kM+XtRFGf3Mulre3mveni2NHfEUws8wSvw==}
     engines: {node: '>=6.9.0'}
     dependencies:
+      '@ampproject/remapping': 2.1.0
       '@babel/code-frame': 7.16.7
-      '@babel/generator': 7.17.0
-      '@babel/helper-compilation-targets': 7.16.7_@babel+core@7.16.7
+      '@babel/generator': 7.18.2
+      '@babel/helper-compilation-targets': 7.16.7_@babel+core@7.17.2
       '@babel/helper-module-transforms': 7.18.0
-      '@babel/helpers': 7.16.7
-      '@babel/parser': 7.17.0
+      '@babel/helpers': 7.17.2
+      '@babel/parser': 7.18.4
       '@babel/template': 7.16.7
-      '@babel/traverse': 7.16.7
-      '@babel/types': 7.16.7
+      '@babel/traverse': 7.18.2
+      '@babel/types': 7.18.4
       convert-source-map: 1.8.0
-      debug: 4.3.3
+      debug: 4.3.4
       gensync: 1.0.0-beta.2
       json5: 2.2.0
       semver: 6.3.0
-      source-map: 0.5.7
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@babel/core/7.17.2:
-    resolution: {integrity: 
sha512-R3VH5G42VSDolRHyUO4V2cfag8WHcZyxdq5Z/m8Xyb92lW/Erm/6kM+XtRFGf3Mulre3mveni2NHfEUws8wSvw==}
+  /@babel/core/7.19.6:
+    resolution: {integrity: 
sha512-D2Ue4KHpc6Ys2+AxpIx1BZ8+UegLLLE2p3KJEuJRKmokHOtl49jQ5ny1773KsGLZs8MQvBidAF6yWUJxRqtKtg==}
     engines: {node: '>=6.9.0'}
     dependencies:
       '@ampproject/remapping': 2.1.0
-      '@babel/code-frame': 7.16.7
-      '@babel/generator': 7.17.0
-      '@babel/helper-compilation-targets': 7.16.7_@babel+core@7.17.2
-      '@babel/helper-module-transforms': 7.16.7
-      '@babel/helpers': 7.17.2
-      '@babel/parser': 7.17.0
-      '@babel/template': 7.16.7
-      '@babel/traverse': 7.17.0
-      '@babel/types': 7.17.0
+      '@babel/code-frame': 7.18.6
+      '@babel/generator': 7.19.6
+      '@babel/helper-compilation-targets': 7.19.3_@babel+core@7.19.6
+      '@babel/helper-module-transforms': 7.19.6
+      '@babel/helpers': 7.19.4
+      '@babel/parser': 7.19.6
+      '@babel/template': 7.18.10
+      '@babel/traverse': 7.19.6
+      '@babel/types': 7.19.4
       convert-source-map: 1.8.0
-      debug: 4.3.3
+      debug: 4.3.4
       gensync: 1.0.0-beta.2
-      json5: 2.2.0
+      json5: 2.2.1
       semver: 6.3.0
     transitivePeerDependencies:
       - supports-color
     dev: true
 
+  /@babel/eslint-parser/7.19.1_ifghgpypvdmamphfg2ieta34qe:
+    resolution: {integrity: 
sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ==}
+    engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0}
+    peerDependencies:
+      '@babel/core': '>=7.11.0'
+      eslint: ^7.5.0 || ^8.0.0
+    dependencies:
+      '@babel/core': 7.17.2
+      '@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1
+      eslint: 7.32.0
+      eslint-visitor-keys: 2.1.0
+      semver: 6.3.0
+    dev: true
+
+  /@babel/eslint-parser/7.19.1_rakzipanemow5i3hc6etgvncsm:
+    resolution: {integrity: 
sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ==}
+    engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0}
+    peerDependencies:
+      '@babel/core': '>=7.11.0'
+      eslint: ^7.5.0 || ^8.0.0
+    dependencies:
+      '@babel/core': 7.17.2
+      '@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1
+      eslint: 8.8.0
+      eslint-visitor-keys: 2.1.0
+      semver: 6.3.0
+    dev: true
+
   /@babel/generator/7.15.0:
     resolution: {integrity: 
sha512-eKl4XdMrbpYvuB505KTta4AV9g+wWzmVBW69tX0H2NwKVKd2YJbKgyK6M8j/rgLbmHOYJn6rUklV677nOyJrEQ==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.15.0
+      '@babel/types': 7.18.4
       jsesc: 2.5.2
       source-map: 0.5.7
     dev: true
@@ -482,7 +955,7 @@ packages:
     resolution: {integrity: 
sha512-I3Omiv6FGOC29dtlZhkfXO6pgkmukJSlT26QjVvS1DGZe/NzSVCPG41X0tS21oZkJYlovfj9qDWgKP+Cn4bXxw==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.17.0
+      '@babel/types': 7.18.4
       jsesc: 2.5.2
       source-map: 0.5.7
     dev: true
@@ -496,18 +969,27 @@ packages:
       jsesc: 2.5.2
     dev: true
 
-  /@babel/helper-annotate-as-pure/7.14.5:
-    resolution: {integrity: 
sha512-EivH9EgBIb+G8ij1B2jAwSH36WnGvkQSEC6CkX/6v6ZFlw5fVOHvsgGF4uiEHO2GzMvunZb6tDLQEQSdrdocrA==}
+  /@babel/generator/7.19.6:
+    resolution: {integrity: 
sha512-oHGRUQeoX1QrKeJIKVe0hwjGqNnVYsM5Nep5zo0uE0m42sLH+Fsd2pStJ5sRM1bNyTUUoz0pe2lTeMJrb/taTA==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.18.4
+      '@babel/types': 7.19.4
+      '@jridgewell/gen-mapping': 0.3.2
+      jsesc: 2.5.2
     dev: true
 
   /@babel/helper-annotate-as-pure/7.16.7:
     resolution: {integrity: 
sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.17.0
+      '@babel/types': 7.18.4
+    dev: true
+
+  /@babel/helper-annotate-as-pure/7.18.6:
+    resolution: {integrity: 
sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/types': 7.19.4
     dev: true
 
   /@babel/helper-builder-binary-assignment-operator-visitor/7.16.7:
@@ -531,32 +1013,58 @@ packages:
       semver: 6.3.0
     dev: true
 
-  /@babel/helper-compilation-targets/7.16.7_@babel+core@7.16.7:
+  /@babel/helper-compilation-targets/7.16.7_@babel+core@7.17.2:
     resolution: {integrity: 
sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0
     dependencies:
       '@babel/compat-data': 7.17.0
-      '@babel/core': 7.16.7
+      '@babel/core': 7.17.2
       '@babel/helper-validator-option': 7.16.7
       browserslist: 4.19.1
       semver: 6.3.0
     dev: true
 
-  /@babel/helper-compilation-targets/7.16.7_@babel+core@7.17.2:
+  /@babel/helper-compilation-targets/7.16.7_@babel+core@7.19.6:
     resolution: {integrity: 
sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0
     dependencies:
       '@babel/compat-data': 7.17.0
-      '@babel/core': 7.17.2
+      '@babel/core': 7.19.6
       '@babel/helper-validator-option': 7.16.7
       browserslist: 4.19.1
       semver: 6.3.0
     dev: true
 
+  /@babel/helper-compilation-targets/7.19.3_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/compat-data': 7.19.4
+      '@babel/core': 7.17.2
+      '@babel/helper-validator-option': 7.18.6
+      browserslist: 4.21.4
+      semver: 6.3.0
+    dev: true
+
+  /@babel/helper-compilation-targets/7.19.3_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/compat-data': 7.19.4
+      '@babel/core': 7.19.6
+      '@babel/helper-validator-option': 7.18.6
+      browserslist: 4.21.4
+      semver: 6.3.0
+    dev: true
+
   /@babel/helper-create-class-features-plugin/7.15.0_@babel+core@7.13.16:
     resolution: {integrity: 
sha512-MdmDXgvTIi4heDVX/e9EFfeGpugqm9fobBVg/iioE8kueXrOHdRDe36FAY7SnE9xXLVeYCoJR/gdrBEIHRC83Q==}
     engines: {node: '>=6.9.0'}
@@ -564,12 +1072,12 @@ packages:
       '@babel/core': ^7.0.0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-annotate-as-pure': 7.14.5
-      '@babel/helper-function-name': 7.14.5
+      '@babel/helper-annotate-as-pure': 7.16.7
+      '@babel/helper-function-name': 7.17.9
       '@babel/helper-member-expression-to-functions': 7.15.0
-      '@babel/helper-optimise-call-expression': 7.14.5
-      '@babel/helper-replace-supers': 7.15.0
-      '@babel/helper-split-export-declaration': 7.14.5
+      '@babel/helper-optimise-call-expression': 7.16.7
+      '@babel/helper-replace-supers': 7.16.7
+      '@babel/helper-split-export-declaration': 7.16.7
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -582,8 +1090,8 @@ packages:
     dependencies:
       '@babel/core': 7.13.16
       '@babel/helper-annotate-as-pure': 7.16.7
-      '@babel/helper-environment-visitor': 7.16.7
-      '@babel/helper-function-name': 7.16.7
+      '@babel/helper-environment-visitor': 7.18.2
+      '@babel/helper-function-name': 7.17.9
       '@babel/helper-member-expression-to-functions': 7.16.7
       '@babel/helper-optimise-call-expression': 7.16.7
       '@babel/helper-replace-supers': 7.16.7
@@ -600,8 +1108,8 @@ packages:
     dependencies:
       '@babel/core': 7.17.2
       '@babel/helper-annotate-as-pure': 7.16.7
-      '@babel/helper-environment-visitor': 7.16.7
-      '@babel/helper-function-name': 7.16.7
+      '@babel/helper-environment-visitor': 7.18.2
+      '@babel/helper-function-name': 7.17.9
       '@babel/helper-member-expression-to-functions': 7.16.7
       '@babel/helper-optimise-call-expression': 7.16.7
       '@babel/helper-replace-supers': 7.16.7
@@ -610,18 +1118,36 @@ packages:
       - supports-color
     dev: true
 
-  /@babel/helper-create-regexp-features-plugin/7.17.0_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA==}
+  /@babel/helper-create-class-features-plugin/7.17.1_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-JBdSr/LtyYIno/pNnJ75lBcqc3Z1XXujzPanHqjvvrhOA+DTceTFuJi8XjmWTZh4r3fsdfqaCMN0iZemdkxZHQ==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0
     dependencies:
-      '@babel/core': 7.13.16
+      '@babel/core': 7.19.6
       '@babel/helper-annotate-as-pure': 7.16.7
-      regexpu-core: 5.0.1
+      '@babel/helper-environment-visitor': 7.18.2
+      '@babel/helper-function-name': 7.17.9
+      '@babel/helper-member-expression-to-functions': 7.16.7
+      '@babel/helper-optimise-call-expression': 7.16.7
+      '@babel/helper-replace-supers': 7.16.7
+      '@babel/helper-split-export-declaration': 7.16.7
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /@babel/helper-create-regexp-features-plugin/7.17.0_@babel+core@7.17.2:
+  /@babel/helper-create-regexp-features-plugin/7.17.0_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.13.16
+      '@babel/helper-annotate-as-pure': 7.16.7
+      regexpu-core: 5.0.1
+    dev: true
+
+  /@babel/helper-create-regexp-features-plugin/7.17.0_@babel+core@7.17.2:
     resolution: {integrity: 
sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
@@ -632,6 +1158,53 @@ packages:
       regexpu-core: 5.0.1
     dev: true
 
+  /@babel/helper-create-regexp-features-plugin/7.17.0_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-annotate-as-pure': 7.16.7
+      regexpu-core: 5.0.1
+    dev: true
+
+  /@babel/helper-define-polyfill-provider/0.1.5_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-nXuzCSwlJ/WKr8qxzW816gwyT6VZgiJG17zR40fou70yfAcqjoNyTLl/DQ+FExw5Hx5KNqshmN8Ldl/r2N7cTg==}
+    peerDependencies:
+      '@babel/core': ^7.4.0-0
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/helper-compilation-targets': 7.19.3_@babel+core@7.17.2
+      '@babel/helper-module-imports': 7.16.7
+      '@babel/helper-plugin-utils': 7.19.0
+      '@babel/traverse': 7.19.6
+      debug: 4.3.4
+      lodash.debounce: 4.0.8
+      resolve: 1.22.1
+      semver: 6.3.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@babel/helper-define-polyfill-provider/0.1.5_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-nXuzCSwlJ/WKr8qxzW816gwyT6VZgiJG17zR40fou70yfAcqjoNyTLl/DQ+FExw5Hx5KNqshmN8Ldl/r2N7cTg==}
+    peerDependencies:
+      '@babel/core': ^7.4.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-compilation-targets': 7.19.3_@babel+core@7.19.6
+      '@babel/helper-module-imports': 7.16.7
+      '@babel/helper-plugin-utils': 7.19.0
+      '@babel/traverse': 7.19.6
+      debug: 4.3.4
+      lodash.debounce: 4.0.8
+      resolve: 1.22.1
+      semver: 6.3.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /@babel/helper-define-polyfill-provider/0.3.1_@babel+core@7.13.16:
     resolution: {integrity: 
sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA==}
     peerDependencies:
@@ -640,9 +1213,9 @@ packages:
       '@babel/core': 7.13.16
       '@babel/helper-compilation-targets': 7.16.7_@babel+core@7.13.16
       '@babel/helper-module-imports': 7.16.7
-      '@babel/helper-plugin-utils': 7.16.7
-      '@babel/traverse': 7.17.0
-      debug: 4.3.3
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/traverse': 7.18.2
+      debug: 4.3.4
       lodash.debounce: 4.0.8
       resolve: 1.22.1
       semver: 6.3.0
@@ -658,9 +1231,27 @@ packages:
       '@babel/core': 7.17.2
       '@babel/helper-compilation-targets': 7.16.7_@babel+core@7.17.2
       '@babel/helper-module-imports': 7.16.7
-      '@babel/helper-plugin-utils': 7.16.7
-      '@babel/traverse': 7.17.0
-      debug: 4.3.3
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/traverse': 7.18.2
+      debug: 4.3.4
+      lodash.debounce: 4.0.8
+      resolve: 1.22.1
+      semver: 6.3.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@babel/helper-define-polyfill-provider/0.3.1_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA==}
+    peerDependencies:
+      '@babel/core': ^7.4.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-compilation-targets': 7.16.7_@babel+core@7.19.6
+      '@babel/helper-module-imports': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/traverse': 7.18.2
+      debug: 4.3.4
       lodash.debounce: 4.0.8
       resolve: 1.22.1
       semver: 6.3.0
@@ -672,7 +1263,7 @@ packages:
     resolution: {integrity: 
sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.17.0
+      '@babel/types': 7.19.4
     dev: true
 
   /@babel/helper-environment-visitor/7.18.2:
@@ -680,20 +1271,16 @@ packages:
     engines: {node: '>=6.9.0'}
     dev: true
 
-  /@babel/helper-explode-assignable-expression/7.16.7:
-    resolution: {integrity: 
sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ==}
+  /@babel/helper-environment-visitor/7.18.9:
+    resolution: {integrity: 
sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==}
     engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/types': 7.18.4
     dev: true
 
-  /@babel/helper-function-name/7.14.5:
-    resolution: {integrity: 
sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==}
+  /@babel/helper-explode-assignable-expression/7.16.7:
+    resolution: {integrity: 
sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/helper-get-function-arity': 7.14.5
-      '@babel/template': 7.16.7
-      '@babel/types': 7.18.4
+      '@babel/types': 7.19.4
     dev: true
 
   /@babel/helper-function-name/7.16.7:
@@ -701,8 +1288,8 @@ packages:
     engines: {node: '>=6.9.0'}
     dependencies:
       '@babel/helper-get-function-arity': 7.16.7
-      '@babel/template': 7.16.7
-      '@babel/types': 7.17.0
+      '@babel/template': 7.18.10
+      '@babel/types': 7.19.4
     dev: true
 
   /@babel/helper-function-name/7.17.9:
@@ -713,46 +1300,61 @@ packages:
       '@babel/types': 7.18.4
     dev: true
 
-  /@babel/helper-get-function-arity/7.14.5:
-    resolution: {integrity: 
sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==}
+  /@babel/helper-function-name/7.19.0:
+    resolution: {integrity: 
sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.18.4
+      '@babel/template': 7.18.10
+      '@babel/types': 7.19.4
     dev: true
 
   /@babel/helper-get-function-arity/7.16.7:
     resolution: {integrity: 
sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.18.4
+      '@babel/types': 7.19.4
     dev: true
 
   /@babel/helper-hoist-variables/7.16.7:
     resolution: {integrity: 
sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.17.0
+      '@babel/types': 7.18.4
+    dev: true
+
+  /@babel/helper-hoist-variables/7.18.6:
+    resolution: {integrity: 
sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/types': 7.19.4
     dev: true
 
   /@babel/helper-member-expression-to-functions/7.15.0:
     resolution: {integrity: 
sha512-Jq8H8U2kYiafuj2xMTPQwkTBnEEdGKpT35lJEQsRRjnG0LW3neucsaMWLgKcwu3OHKNeYugfw+Z20BXBSEs2Lg==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.18.4
+      '@babel/types': 7.19.4
     dev: true
 
   /@babel/helper-member-expression-to-functions/7.16.7:
     resolution: {integrity: 
sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.18.4
+      '@babel/types': 7.19.4
     dev: true
 
   /@babel/helper-module-imports/7.16.7:
     resolution: {integrity: 
sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.17.0
+      '@babel/types': 7.18.4
+    dev: true
+
+  /@babel/helper-module-imports/7.18.6:
+    resolution: {integrity: 
sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/types': 7.19.4
     dev: true
 
   /@babel/helper-module-transforms/7.16.7:
@@ -765,8 +1367,8 @@ packages:
       '@babel/helper-split-export-declaration': 7.16.7
       '@babel/helper-validator-identifier': 7.16.7
       '@babel/template': 7.16.7
-      '@babel/traverse': 7.17.0
-      '@babel/types': 7.17.0
+      '@babel/traverse': 7.18.2
+      '@babel/types': 7.18.4
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -775,7 +1377,7 @@ packages:
     resolution: {integrity: 
sha512-kclUYSUBIjlvnzN2++K9f2qzYKFgjmnmjwL4zlmU5f8ZtzgWe8s0rUPSTGy2HmK4P8T52MQsS+HTQAgZd3dMEA==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/helper-environment-visitor': 7.16.7
+      '@babel/helper-environment-visitor': 7.18.2
       '@babel/helper-module-imports': 7.16.7
       '@babel/helper-simple-access': 7.18.2
       '@babel/helper-split-export-declaration': 7.16.7
@@ -787,11 +1389,20 @@ packages:
       - supports-color
     dev: true
 
-  /@babel/helper-optimise-call-expression/7.14.5:
-    resolution: {integrity: 
sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==}
+  /@babel/helper-module-transforms/7.19.6:
+    resolution: {integrity: 
sha512-fCmcfQo/KYr/VXXDIyd3CBGZ6AFhPFy1TfSEJ+PilGVlQT6jcbqtHAM4C1EciRqMza7/TpOUZliuSH+U6HAhJw==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.18.4
+      '@babel/helper-environment-visitor': 7.18.9
+      '@babel/helper-module-imports': 7.18.6
+      '@babel/helper-simple-access': 7.19.4
+      '@babel/helper-split-export-declaration': 7.18.6
+      '@babel/helper-validator-identifier': 7.19.1
+      '@babel/template': 7.18.10
+      '@babel/traverse': 7.19.6
+      '@babel/types': 7.19.4
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
   /@babel/helper-optimise-call-expression/7.16.7:
@@ -801,18 +1412,22 @@ packages:
       '@babel/types': 7.18.4
     dev: true
 
+  /@babel/helper-plugin-utils/7.10.4:
+    resolution: {integrity: 
sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==}
+    dev: true
+
   /@babel/helper-plugin-utils/7.14.5:
     resolution: {integrity: 
sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==}
     engines: {node: '>=6.9.0'}
     dev: true
 
-  /@babel/helper-plugin-utils/7.16.7:
-    resolution: {integrity: 
sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==}
+  /@babel/helper-plugin-utils/7.17.12:
+    resolution: {integrity: 
sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA==}
     engines: {node: '>=6.9.0'}
     dev: true
 
-  /@babel/helper-plugin-utils/7.17.12:
-    resolution: {integrity: 
sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA==}
+  /@babel/helper-plugin-utils/7.19.0:
+    resolution: {integrity: 
sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==}
     engines: {node: '>=6.9.0'}
     dev: true
 
@@ -827,27 +1442,15 @@ packages:
       - supports-color
     dev: true
 
-  /@babel/helper-replace-supers/7.15.0:
-    resolution: {integrity: 
sha512-6O+eWrhx+HEra/uJnifCwhwMd6Bp5+ZfZeJwbqUTuqkhIT6YcRhiZCOOFChRypOIe0cV46kFrRBlm+t5vHCEaA==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/helper-member-expression-to-functions': 7.15.0
-      '@babel/helper-optimise-call-expression': 7.14.5
-      '@babel/traverse': 7.18.2
-      '@babel/types': 7.18.4
-    transitivePeerDependencies:
-      - supports-color
-    dev: true
-
   /@babel/helper-replace-supers/7.16.7:
     resolution: {integrity: 
sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/helper-environment-visitor': 7.16.7
+      '@babel/helper-environment-visitor': 7.18.2
       '@babel/helper-member-expression-to-functions': 7.16.7
       '@babel/helper-optimise-call-expression': 7.16.7
-      '@babel/traverse': 7.17.0
-      '@babel/types': 7.17.0
+      '@babel/traverse': 7.18.2
+      '@babel/types': 7.18.4
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -856,7 +1459,7 @@ packages:
     resolution: {integrity: 
sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.17.0
+      '@babel/types': 7.19.4
     dev: true
 
   /@babel/helper-simple-access/7.18.2:
@@ -866,6 +1469,13 @@ packages:
       '@babel/types': 7.18.4
     dev: true
 
+  /@babel/helper-simple-access/7.19.4:
+    resolution: {integrity: 
sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      '@babel/types': 7.19.4
+    dev: true
+
   /@babel/helper-skip-transparent-expression-wrappers/7.16.0:
     resolution: {integrity: 
sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==}
     engines: {node: '>=6.9.0'}
@@ -873,22 +1483,22 @@ packages:
       '@babel/types': 7.18.4
     dev: true
 
-  /@babel/helper-split-export-declaration/7.14.5:
-    resolution: {integrity: 
sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==}
+  /@babel/helper-split-export-declaration/7.16.7:
+    resolution: {integrity: 
sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==}
     engines: {node: '>=6.9.0'}
     dependencies:
       '@babel/types': 7.18.4
     dev: true
 
-  /@babel/helper-split-export-declaration/7.16.7:
-    resolution: {integrity: 
sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==}
+  /@babel/helper-split-export-declaration/7.18.6:
+    resolution: {integrity: 
sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.17.0
+      '@babel/types': 7.19.4
     dev: true
 
-  /@babel/helper-validator-identifier/7.14.9:
-    resolution: {integrity: 
sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==}
+  /@babel/helper-string-parser/7.19.4:
+    resolution: {integrity: 
sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==}
     engines: {node: '>=6.9.0'}
     dev: true
 
@@ -897,6 +1507,11 @@ packages:
     engines: {node: '>=6.9.0'}
     dev: true
 
+  /@babel/helper-validator-identifier/7.19.1:
+    resolution: {integrity: 
sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==}
+    engines: {node: '>=6.9.0'}
+    dev: true
+
   /@babel/helper-validator-option/7.14.5:
     resolution: {integrity: 
sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==}
     engines: {node: '>=6.9.0'}
@@ -907,36 +1522,41 @@ packages:
     engines: {node: '>=6.9.0'}
     dev: true
 
+  /@babel/helper-validator-option/7.18.6:
+    resolution: {integrity: 
sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==}
+    engines: {node: '>=6.9.0'}
+    dev: true
+
   /@babel/helper-wrap-function/7.16.8:
     resolution: {integrity: 
sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/helper-function-name': 7.16.7
-      '@babel/template': 7.16.7
-      '@babel/traverse': 7.18.2
-      '@babel/types': 7.18.4
+      '@babel/helper-function-name': 7.17.9
+      '@babel/template': 7.18.10
+      '@babel/traverse': 7.19.6
+      '@babel/types': 7.19.4
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@babel/helpers/7.16.7:
-    resolution: {integrity: 
sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw==}
+  /@babel/helpers/7.17.2:
+    resolution: {integrity: 
sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==}
     engines: {node: '>=6.9.0'}
     dependencies:
       '@babel/template': 7.16.7
-      '@babel/traverse': 7.17.0
+      '@babel/traverse': 7.18.2
       '@babel/types': 7.18.4
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@babel/helpers/7.17.2:
-    resolution: {integrity: 
sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==}
+  /@babel/helpers/7.19.4:
+    resolution: {integrity: 
sha512-G+z3aOx2nfDHwX/kyVii5fJq+bgscg89/dJNWpYeKeBv3v9xX8EIabmx1k6u9LS04H7nROFVRVK+e3k0VHp+sw==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/template': 7.16.7
-      '@babel/traverse': 7.17.0
-      '@babel/types': 7.17.0
+      '@babel/template': 7.18.10
+      '@babel/traverse': 7.19.6
+      '@babel/types': 7.19.4
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -950,12 +1570,13 @@ packages:
       js-tokens: 4.0.0
     dev: true
 
-  /@babel/parser/7.15.3:
-    resolution: {integrity: 
sha512-O0L6v/HvqbdJawj0iBEfVQMc3/6WP+AeOsovsIgBFyJaG+W2w7eqvZB7puddATmWuARlm1SX7DwxJ/JJUnDpEA==}
-    engines: {node: '>=6.0.0'}
-    hasBin: true
+  /@babel/highlight/7.18.6:
+    resolution: {integrity: 
sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==}
+    engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.17.0
+      '@babel/helper-validator-identifier': 7.19.1
+      chalk: 2.4.2
+      js-tokens: 4.0.0
     dev: true
 
   /@babel/parser/7.17.0:
@@ -963,7 +1584,7 @@ packages:
     engines: {node: '>=6.0.0'}
     hasBin: true
     dependencies:
-      '@babel/types': 7.17.0
+      '@babel/types': 7.18.4
     dev: true
 
   /@babel/parser/7.18.4:
@@ -974,6 +1595,14 @@ packages:
       '@babel/types': 7.18.4
     dev: true
 
+  /@babel/parser/7.19.6:
+    resolution: {integrity: 
sha512-h1IUp81s2JYJ3mRkdxJgs4UvmSsRvDrx5ICSJbPvtWYv5i1nTBGcBpnog+89rAFMwvvru6E5NUHdBe01UeSzYA==}
+    engines: {node: '>=6.0.0'}
+    hasBin: true
+    dependencies:
+      '@babel/types': 7.19.4
+    dev: true
+
   
/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/7.16.7_@babel+core@7.13.16:
     resolution: {integrity: 
sha512-anv/DObl7waiGEnC24O9zqL0pSuI9hljihqiDuFHC8d7/bjr/4RLGPWuc8rYOff/QPzbEPSkzG8wGG9aDuhHRg==}
     engines: {node: '>=6.9.0'}
@@ -981,7 +1610,7 @@ packages:
       '@babel/core': ^7.0.0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   
/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/7.16.7_@babel+core@7.17.2:
@@ -991,7 +1620,17 @@ packages:
       '@babel/core': ^7.0.0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  
/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-anv/DObl7waiGEnC24O9zqL0pSuI9hljihqiDuFHC8d7/bjr/4RLGPWuc8rYOff/QPzbEPSkzG8wGG9aDuhHRg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   
/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/7.16.7_@babel+core@7.13.16:
@@ -1001,7 +1640,7 @@ packages:
       '@babel/core': ^7.13.0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/helper-skip-transparent-expression-wrappers': 7.16.0
       '@babel/plugin-proposal-optional-chaining': 7.16.7_@babel+core@7.13.16
     dev: true
@@ -1013,11 +1652,23 @@ packages:
       '@babel/core': ^7.13.0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/helper-skip-transparent-expression-wrappers': 7.16.0
       '@babel/plugin-proposal-optional-chaining': 7.16.7_@babel+core@7.17.2
     dev: true
 
+  
/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-di8vUHRdf+4aJ7ltXhaDbPoszdkh59AQtJM5soLsuHpQJdFQZOA4uGj0V2u/CZ8bJ/u8ULDL5yq6FO/bCXnKHw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.13.0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/helper-skip-transparent-expression-wrappers': 7.16.0
+      '@babel/plugin-proposal-optional-chaining': 7.16.7_@babel+core@7.19.6
+    dev: true
+
   /@babel/plugin-proposal-async-generator-functions/7.16.8_@babel+core@7.13.16:
     resolution: {integrity: 
sha512-71YHIvMuiuqWJQkebWJtdhQTfd4Q4mF76q2IX37uZPkG9+olBxsX+rH1vkhFto4UeJZ9dPY2s+mDvhDm1u2BGQ==}
     engines: {node: '>=6.9.0'}
@@ -1025,7 +1676,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/helper-remap-async-to-generator': 7.16.8
       '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.13.16
     transitivePeerDependencies:
@@ -1039,13 +1690,27 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/helper-remap-async-to-generator': 7.16.8
       '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.17.2
     transitivePeerDependencies:
       - supports-color
     dev: true
 
+  /@babel/plugin-proposal-async-generator-functions/7.16.8_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-71YHIvMuiuqWJQkebWJtdhQTfd4Q4mF76q2IX37uZPkG9+olBxsX+rH1vkhFto4UeJZ9dPY2s+mDvhDm1u2BGQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/helper-remap-async-to-generator': 7.16.8
+      '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.19.6
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /@babel/plugin-proposal-class-properties/7.16.7_@babel+core@7.13.16:
     resolution: {integrity: 
sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww==}
     engines: {node: '>=6.9.0'}
@@ -1054,7 +1719,7 @@ packages:
     dependencies:
       '@babel/core': 7.13.16
       '@babel/helper-create-class-features-plugin': 7.17.1_@babel+core@7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -1067,7 +1732,20 @@ packages:
     dependencies:
       '@babel/core': 7.17.2
       '@babel/helper-create-class-features-plugin': 7.17.1_@babel+core@7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@babel/plugin-proposal-class-properties/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-create-class-features-plugin': 7.17.1_@babel+core@7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -1080,7 +1758,7 @@ packages:
     dependencies:
       '@babel/core': 7.13.16
       '@babel/helper-create-class-features-plugin': 7.17.1_@babel+core@7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.13.16
     transitivePeerDependencies:
       - supports-color
@@ -1094,12 +1772,26 @@ packages:
     dependencies:
       '@babel/core': 7.17.2
       '@babel/helper-create-class-features-plugin': 7.17.1_@babel+core@7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.17.2
     transitivePeerDependencies:
       - supports-color
     dev: true
 
+  /@babel/plugin-proposal-class-static-block/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-dgqJJrcZoG/4CkMopzhPJjGxsIe9A8RlkQLnL/Vhhx8AA9ZuaRwGSlscSh42hazc7WSrya/IK7mTeoF0DP9tEw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.12.0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-create-class-features-plugin': 7.17.1_@babel+core@7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.19.6
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /@babel/plugin-proposal-decorators/7.17.2_@babel+core@7.17.2:
     resolution: {integrity: 
sha512-WH8Z95CwTq/W8rFbMqb9p3hicpt4RX4f0K659ax2VHxgOyT6qQmUaEVEjIh4WR9Eh9NymkVn5vwsrE68fAQNUw==}
     engines: {node: '>=6.9.0'}
@@ -1108,7 +1800,7 @@ packages:
     dependencies:
       '@babel/core': 7.17.2
       '@babel/helper-create-class-features-plugin': 7.17.1_@babel+core@7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/helper-replace-supers': 7.16.7
       '@babel/plugin-syntax-decorators': 7.17.0_@babel+core@7.17.2
       charcodes: 0.2.0
@@ -1116,6 +1808,22 @@ packages:
       - supports-color
     dev: true
 
+  /@babel/plugin-proposal-decorators/7.17.2_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-WH8Z95CwTq/W8rFbMqb9p3hicpt4RX4f0K659ax2VHxgOyT6qQmUaEVEjIh4WR9Eh9NymkVn5vwsrE68fAQNUw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-create-class-features-plugin': 7.17.1_@babel+core@7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/helper-replace-supers': 7.16.7
+      '@babel/plugin-syntax-decorators': 7.17.0_@babel+core@7.19.6
+      charcodes: 0.2.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /@babel/plugin-proposal-dynamic-import/7.16.7_@babel+core@7.13.16:
     resolution: {integrity: 
sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg==}
     engines: {node: '>=6.9.0'}
@@ -1123,7 +1831,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.13.16
     dev: true
 
@@ -1134,41 +1842,85 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.17.2
     dev: true
 
-  /@babel/plugin-proposal-export-namespace-from/7.16.7_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA==}
+  /@babel/plugin-proposal-dynamic-import/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
-      '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.13.16
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.19.6
     dev: true
 
-  /@babel/plugin-proposal-export-namespace-from/7.16.7_@babel+core@7.17.2:
-    resolution: {integrity: 
sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA==}
+  /@babel/plugin-proposal-export-default-from/7.18.10_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-5H2N3R2aQFxkV4PIBUR/i7PUSwgTZjouJKzI8eKswfIjT0PhvzkPn0t0wIS5zn6maQuvtT0t1oHtMUz61LOuow==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
-      '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.17.2
+      '@babel/helper-plugin-utils': 7.19.0
+      '@babel/plugin-syntax-export-default-from': 7.18.6_@babel+core@7.17.2
     dev: true
 
-  /@babel/plugin-proposal-json-strings/7.16.7_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ==}
+  /@babel/plugin-proposal-export-default-from/7.18.10_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-5H2N3R2aQFxkV4PIBUR/i7PUSwgTZjouJKzI8eKswfIjT0PhvzkPn0t0wIS5zn6maQuvtT0t1oHtMUz61LOuow==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
-      '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.13.16
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.19.0
+      '@babel/plugin-syntax-export-default-from': 7.18.6_@babel+core@7.19.6
+    dev: true
+
+  /@babel/plugin-proposal-export-namespace-from/7.16.7_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.13.16
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.13.16
+    dev: true
+
+  /@babel/plugin-proposal-export-namespace-from/7.16.7_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.17.2
+    dev: true
+
+  /@babel/plugin-proposal-export-namespace-from/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.19.6
+    dev: true
+
+  /@babel/plugin-proposal-json-strings/7.16.7_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.13.16
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.13.16
     dev: true
 
   /@babel/plugin-proposal-json-strings/7.16.7_@babel+core@7.17.2:
@@ -1178,10 +1930,21 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.17.2
     dev: true
 
+  /@babel/plugin-proposal-json-strings/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.19.6
+    dev: true
+
   
/@babel/plugin-proposal-logical-assignment-operators/7.16.7_@babel+core@7.13.16:
     resolution: {integrity: 
sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg==}
     engines: {node: '>=6.9.0'}
@@ -1189,7 +1952,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/plugin-syntax-logical-assignment-operators': 
7.10.4_@babel+core@7.13.16
     dev: true
 
@@ -1200,10 +1963,21 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/plugin-syntax-logical-assignment-operators': 
7.10.4_@babel+core@7.17.2
     dev: true
 
+  
/@babel/plugin-proposal-logical-assignment-operators/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/plugin-syntax-logical-assignment-operators': 
7.10.4_@babel+core@7.19.6
+    dev: true
+
   
/@babel/plugin-proposal-nullish-coalescing-operator/7.16.7_@babel+core@7.13.16:
     resolution: {integrity: 
sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ==}
     engines: {node: '>=6.9.0'}
@@ -1211,7 +1985,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/plugin-syntax-nullish-coalescing-operator': 
7.8.3_@babel+core@7.13.16
     dev: true
 
@@ -1222,10 +1996,21 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/plugin-syntax-nullish-coalescing-operator': 
7.8.3_@babel+core@7.17.2
     dev: true
 
+  
/@babel/plugin-proposal-nullish-coalescing-operator/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/plugin-syntax-nullish-coalescing-operator': 
7.8.3_@babel+core@7.19.6
+    dev: true
+
   /@babel/plugin-proposal-numeric-separator/7.16.7_@babel+core@7.13.16:
     resolution: {integrity: 
sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw==}
     engines: {node: '>=6.9.0'}
@@ -1233,7 +2018,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.13.16
     dev: true
 
@@ -1244,10 +2029,32 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.17.2
     dev: true
 
+  /@babel/plugin-proposal-numeric-separator/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.19.6
+    dev: true
+
+  /@babel/plugin-proposal-object-rest-spread/7.12.1_@babel+core@7.12.9:
+    resolution: {integrity: 
sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.12.9
+      '@babel/helper-plugin-utils': 7.19.0
+      '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.12.9
+      '@babel/plugin-transform-parameters': 7.16.7_@babel+core@7.12.9
+    dev: true
+
   /@babel/plugin-proposal-object-rest-spread/7.16.7_@babel+core@7.13.16:
     resolution: {integrity: 
sha512-3O0Y4+dw94HA86qSg9IHfyPktgR7q3gpNVAeiKQd+8jBKFaU5NQS1Yatgo4wY+UFNuLjvxcSmzcsHqrhgTyBUA==}
     engines: {node: '>=6.9.0'}
@@ -1257,7 +2064,7 @@ packages:
       '@babel/compat-data': 7.17.0
       '@babel/core': 7.13.16
       '@babel/helper-compilation-targets': 7.16.7_@babel+core@7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.13.16
       '@babel/plugin-transform-parameters': 7.16.7_@babel+core@7.13.16
     dev: true
@@ -1271,11 +2078,25 @@ packages:
       '@babel/compat-data': 7.17.0
       '@babel/core': 7.17.2
       '@babel/helper-compilation-targets': 7.16.7_@babel+core@7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.17.2
       '@babel/plugin-transform-parameters': 7.16.7_@babel+core@7.17.2
     dev: true
 
+  /@babel/plugin-proposal-object-rest-spread/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-3O0Y4+dw94HA86qSg9IHfyPktgR7q3gpNVAeiKQd+8jBKFaU5NQS1Yatgo4wY+UFNuLjvxcSmzcsHqrhgTyBUA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/compat-data': 7.17.0
+      '@babel/core': 7.19.6
+      '@babel/helper-compilation-targets': 7.16.7_@babel+core@7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.19.6
+      '@babel/plugin-transform-parameters': 7.16.7_@babel+core@7.19.6
+    dev: true
+
   /@babel/plugin-proposal-optional-catch-binding/7.16.7_@babel+core@7.13.16:
     resolution: {integrity: 
sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA==}
     engines: {node: '>=6.9.0'}
@@ -1283,7 +2104,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.13.16
     dev: true
 
@@ -1294,10 +2115,21 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.17.2
     dev: true
 
+  /@babel/plugin-proposal-optional-catch-binding/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.19.6
+    dev: true
+
   /@babel/plugin-proposal-optional-chaining/7.16.7_@babel+core@7.13.16:
     resolution: {integrity: 
sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA==}
     engines: {node: '>=6.9.0'}
@@ -1305,7 +2137,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/helper-skip-transparent-expression-wrappers': 7.16.0
       '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.13.16
     dev: true
@@ -1317,11 +2149,23 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/helper-skip-transparent-expression-wrappers': 7.16.0
       '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.17.2
     dev: true
 
+  /@babel/plugin-proposal-optional-chaining/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/helper-skip-transparent-expression-wrappers': 7.16.0
+      '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.19.6
+    dev: true
+
   /@babel/plugin-proposal-private-methods/7.16.11_@babel+core@7.13.16:
     resolution: {integrity: 
sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw==}
     engines: {node: '>=6.9.0'}
@@ -1330,7 +2174,7 @@ packages:
     dependencies:
       '@babel/core': 7.13.16
       '@babel/helper-create-class-features-plugin': 7.17.1_@babel+core@7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -1343,7 +2187,20 @@ packages:
     dependencies:
       '@babel/core': 7.17.2
       '@babel/helper-create-class-features-plugin': 7.17.1_@babel+core@7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@babel/plugin-proposal-private-methods/7.16.11_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-create-class-features-plugin': 7.17.1_@babel+core@7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -1357,7 +2214,7 @@ packages:
       '@babel/core': 7.13.16
       '@babel/helper-annotate-as-pure': 7.16.7
       '@babel/helper-create-class-features-plugin': 7.17.1_@babel+core@7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/plugin-syntax-private-property-in-object': 
7.14.5_@babel+core@7.13.16
     transitivePeerDependencies:
       - supports-color
@@ -1372,12 +2229,27 @@ packages:
       '@babel/core': 7.17.2
       '@babel/helper-annotate-as-pure': 7.16.7
       '@babel/helper-create-class-features-plugin': 7.17.1_@babel+core@7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/plugin-syntax-private-property-in-object': 
7.14.5_@babel+core@7.17.2
     transitivePeerDependencies:
       - supports-color
     dev: true
 
+  /@babel/plugin-proposal-private-property-in-object/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-rMQkjcOFbm+ufe3bTZLyOfsOUOxyvLXZJCTARhJr+8UMSoZmqTe1K1BgkFcrW37rAchWg57yI69ORxiWvUINuQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-annotate-as-pure': 7.16.7
+      '@babel/helper-create-class-features-plugin': 7.17.1_@babel+core@7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/plugin-syntax-private-property-in-object': 
7.14.5_@babel+core@7.19.6
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /@babel/plugin-proposal-unicode-property-regex/7.16.7_@babel+core@7.13.16:
     resolution: {integrity: 
sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg==}
     engines: {node: '>=4'}
@@ -1386,7 +2258,7 @@ packages:
     dependencies:
       '@babel/core': 7.13.16
       '@babel/helper-create-regexp-features-plugin': 7.17.0_@babel+core@7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-proposal-unicode-property-regex/7.16.7_@babel+core@7.17.2:
@@ -1397,7 +2269,18 @@ packages:
     dependencies:
       '@babel/core': 7.17.2
       '@babel/helper-create-regexp-features-plugin': 7.17.0_@babel+core@7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-proposal-unicode-property-regex/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg==}
+    engines: {node: '>=4'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-create-regexp-features-plugin': 7.17.0_@babel+core@7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.13.16:
@@ -1406,7 +2289,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.17.2:
@@ -1415,7 +2298,34 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-syntax-bigint/7.8.3_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/helper-plugin-utils': 7.19.0
+    dev: true
+
+  /@babel/plugin-syntax-bigint/7.8.3_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.19.0
     dev: true
 
   /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.13.16:
@@ -1424,7 +2334,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.17.2:
@@ -1433,7 +2343,16 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-syntax-class-static-block/7.14.5_@babel+core@7.13.16:
@@ -1443,7 +2362,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-syntax-class-static-block/7.14.5_@babel+core@7.17.2:
@@ -1453,7 +2372,17 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-syntax-class-static-block/7.14.5_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-syntax-decorators/7.17.0_@babel+core@7.17.2:
@@ -1466,13 +2395,23 @@ packages:
       '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
+  /@babel/plugin-syntax-decorators/7.17.0_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-qWe85yCXsvDEluNP0OyeQjH63DlhAR3W7K9BxxU1MvbDb48tgBG+Ao6IJJ6smPDrrVzSQZrbF6donpkFBMcs3A==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
   /@babel/plugin-syntax-dynamic-import/7.8.3_@babel+core@7.13.16:
     resolution: {integrity: 
sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-syntax-dynamic-import/7.8.3_@babel+core@7.17.2:
@@ -1481,48 +2420,49 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
-  /@babel/plugin-syntax-export-namespace-from/7.8.3_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==}
+  /@babel/plugin-syntax-dynamic-import/7.8.3_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
-  /@babel/plugin-syntax-export-namespace-from/7.8.3_@babel+core@7.17.2:
-    resolution: {integrity: 
sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==}
+  /@babel/plugin-syntax-export-default-from/7.18.6_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-Kr//z3ujSVNx6E9z9ih5xXXMqK07VVTuqPmqGe6Mss/zW5XPeLZeSDZoP9ab/hT4wPKqAgjl2PnhPrcpk8Seew==}
+    engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.19.0
     dev: true
 
-  /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==}
+  /@babel/plugin-syntax-export-default-from/7.18.6_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-Kr//z3ujSVNx6E9z9ih5xXXMqK07VVTuqPmqGe6Mss/zW5XPeLZeSDZoP9ab/hT4wPKqAgjl2PnhPrcpk8Seew==}
+    engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.19.0
     dev: true
 
-  /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.17.2:
-    resolution: {integrity: 
sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==}
+  /@babel/plugin-syntax-export-namespace-from/7.8.3_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/core': 7.13.16
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
-  /@babel/plugin-syntax-jsx/7.16.7_@babel+core@7.17.2:
-    resolution: {integrity: 
sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q==}
-    engines: {node: '>=6.9.0'}
+  /@babel/plugin-syntax-export-namespace-from/7.8.3_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
@@ -1530,67 +2470,196 @@ packages:
       '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
-  
/@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==}
+  /@babel/plugin-syntax-export-namespace-from/7.8.3_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
-  /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.17.2:
-    resolution: {integrity: 
sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==}
+  /@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.19.0
     dev: true
 
-  /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==}
+  /@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.19.0
     dev: true
 
-  /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.17.2:
-    resolution: {integrity: 
sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==}
+  /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/core': 7.13.16
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
-  /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==}
+  /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/core': 7.17.2
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
-  /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.17.2:
-    resolution: {integrity: 
sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==}
+  /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
-  /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==}
+  /@babel/plugin-syntax-jsx/7.12.1_@babel+core@7.12.9:
+    resolution: {integrity: 
sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.12.9
+      '@babel/helper-plugin-utils': 7.19.0
+    dev: true
+
+  /@babel/plugin-syntax-jsx/7.16.7_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/helper-plugin-utils': 7.19.0
+    dev: true
+
+  /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.19.0
+    dev: true
+
+  
/@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.13.16
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.13.16
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.13.16
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.12.9:
+    resolution: {integrity: 
sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.12.9
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.17.2:
@@ -1599,7 +2668,16 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.13.16:
@@ -1608,7 +2686,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.17.2:
@@ -1617,7 +2695,16 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.13.16:
@@ -1626,7 +2713,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.17.2:
@@ -1635,7 +2722,16 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-syntax-private-property-in-object/7.14.5_@babel+core@7.13.16:
@@ -1645,7 +2741,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-syntax-private-property-in-object/7.14.5_@babel+core@7.17.2:
@@ -1655,7 +2751,17 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-syntax-private-property-in-object/7.14.5_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.13.16:
@@ -1665,7 +2771,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.17.2:
@@ -1675,7 +2781,17 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-syntax-typescript/7.14.5_@babel+core@7.13.16:
@@ -1685,7 +2801,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/helper-plugin-utils': 7.19.0
     dev: true
 
   /@babel/plugin-syntax-typescript/7.16.7_@babel+core@7.17.2:
@@ -1695,7 +2811,17 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/helper-plugin-utils': 7.19.0
+    dev: true
+
+  /@babel/plugin-syntax-typescript/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.19.0
     dev: true
 
   /@babel/plugin-transform-arrow-functions/7.16.7_@babel+core@7.13.16:
@@ -1705,7 +2831,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-arrow-functions/7.16.7_@babel+core@7.17.2:
@@ -1715,7 +2841,17 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-transform-arrow-functions/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-async-to-generator/7.16.8_@babel+core@7.13.16:
@@ -1726,7 +2862,7 @@ packages:
     dependencies:
       '@babel/core': 7.13.16
       '@babel/helper-module-imports': 7.16.7
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/helper-remap-async-to-generator': 7.16.8
     transitivePeerDependencies:
       - supports-color
@@ -1740,7 +2876,21 @@ packages:
     dependencies:
       '@babel/core': 7.17.2
       '@babel/helper-module-imports': 7.16.7
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/helper-remap-async-to-generator': 7.16.8
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@babel/plugin-transform-async-to-generator/7.16.8_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-MtmUmTJQHCnyJVrScNzNlofQJ3dLFuobYn3mwOTKHnSCMtbNsqvF71GQmJfFjdrXSsAA7iysFmYWw4bXZ20hOg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-module-imports': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/helper-remap-async-to-generator': 7.16.8
     transitivePeerDependencies:
       - supports-color
@@ -1753,7 +2903,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-block-scoped-functions/7.16.7_@babel+core@7.17.2:
@@ -1763,7 +2913,17 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-transform-block-scoped-functions/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-JUuzlzmF40Z9cXyytcbZEZKckgrQzChbQJw/5PuEHYeqzCsvebDx0K0jWnIIVcmmDOAVctCgnYs0pMcrYj2zJg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-block-scoping/7.16.7_@babel+core@7.13.16:
@@ -1773,7 +2933,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-block-scoping/7.16.7_@babel+core@7.17.2:
@@ -1783,7 +2943,17 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-transform-block-scoping/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-classes/7.16.7_@babel+core@7.13.16:
@@ -1794,10 +2964,10 @@ packages:
     dependencies:
       '@babel/core': 7.13.16
       '@babel/helper-annotate-as-pure': 7.16.7
-      '@babel/helper-environment-visitor': 7.16.7
-      '@babel/helper-function-name': 7.16.7
+      '@babel/helper-environment-visitor': 7.18.2
+      '@babel/helper-function-name': 7.17.9
       '@babel/helper-optimise-call-expression': 7.16.7
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/helper-replace-supers': 7.16.7
       '@babel/helper-split-export-declaration': 7.16.7
       globals: 11.12.0
@@ -1813,10 +2983,29 @@ packages:
     dependencies:
       '@babel/core': 7.17.2
       '@babel/helper-annotate-as-pure': 7.16.7
-      '@babel/helper-environment-visitor': 7.16.7
-      '@babel/helper-function-name': 7.16.7
+      '@babel/helper-environment-visitor': 7.18.2
+      '@babel/helper-function-name': 7.17.9
+      '@babel/helper-optimise-call-expression': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/helper-replace-supers': 7.16.7
+      '@babel/helper-split-export-declaration': 7.16.7
+      globals: 11.12.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@babel/plugin-transform-classes/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-annotate-as-pure': 7.16.7
+      '@babel/helper-environment-visitor': 7.18.2
+      '@babel/helper-function-name': 7.17.9
       '@babel/helper-optimise-call-expression': 7.16.7
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/helper-replace-supers': 7.16.7
       '@babel/helper-split-export-declaration': 7.16.7
       globals: 11.12.0
@@ -1831,7 +3020,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-computed-properties/7.16.7_@babel+core@7.17.2:
@@ -1841,7 +3030,17 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-transform-computed-properties/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-destructuring/7.16.7_@babel+core@7.13.16:
@@ -1851,7 +3050,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-destructuring/7.16.7_@babel+core@7.17.2:
@@ -1861,18 +3060,28 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
-  /@babel/plugin-transform-dotall-regex/7.16.7_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ==}
+  /@babel/plugin-transform-destructuring/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-VqAwhTHBnu5xBVDCvrvqJbtLUa++qZaWC0Fgr2mqokBlulZARGyIvZDoqbPlPaKImQ9dKAcCzbv+ul//uqu70A==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.13.16
-      '@babel/helper-create-regexp-features-plugin': 7.17.0_@babel+core@7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-transform-dotall-regex/7.16.7_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.13.16
+      '@babel/helper-create-regexp-features-plugin': 7.17.0_@babel+core@7.13.16
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-dotall-regex/7.16.7_@babel+core@7.17.2:
@@ -1883,7 +3092,18 @@ packages:
     dependencies:
       '@babel/core': 7.17.2
       '@babel/helper-create-regexp-features-plugin': 7.17.0_@babel+core@7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-transform-dotall-regex/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-create-regexp-features-plugin': 7.17.0_@babel+core@7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-duplicate-keys/7.16.7_@babel+core@7.13.16:
@@ -1893,7 +3113,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-duplicate-keys/7.16.7_@babel+core@7.17.2:
@@ -1903,7 +3123,17 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-transform-duplicate-keys/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-03DvpbRfvWIXyK0/6QiR1KMTWeT6OcQ7tbhjrXyFS02kjuX/mu5Bvnh5SDSWHxyawit2g5aWhKwI86EE7GUnTw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-exponentiation-operator/7.16.7_@babel+core@7.13.16:
@@ -1914,7 +3144,7 @@ packages:
     dependencies:
       '@babel/core': 7.13.16
       '@babel/helper-builder-binary-assignment-operator-visitor': 7.16.7
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-exponentiation-operator/7.16.7_@babel+core@7.17.2:
@@ -1925,7 +3155,18 @@ packages:
     dependencies:
       '@babel/core': 7.17.2
       '@babel/helper-builder-binary-assignment-operator-visitor': 7.16.7
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-transform-exponentiation-operator/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-8UYLSlyLgRixQvlYH3J2ekXFHDFLQutdy7FfFAMm3CPZ6q9wHCwnUyiXpQCe3gVVnQlHc5nsuiEVziteRNTXEA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-builder-binary-assignment-operator-visitor': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-for-of/7.16.7_@babel+core@7.13.16:
@@ -1935,7 +3176,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-for-of/7.16.7_@babel+core@7.17.2:
@@ -1945,7 +3186,17 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-transform-for-of/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-function-name/7.16.7_@babel+core@7.13.16:
@@ -1956,8 +3207,8 @@ packages:
     dependencies:
       '@babel/core': 7.13.16
       '@babel/helper-compilation-targets': 7.16.7_@babel+core@7.13.16
-      '@babel/helper-function-name': 7.16.7
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-function-name': 7.17.9
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-function-name/7.16.7_@babel+core@7.17.2:
@@ -1968,8 +3219,20 @@ packages:
     dependencies:
       '@babel/core': 7.17.2
       '@babel/helper-compilation-targets': 7.16.7_@babel+core@7.17.2
-      '@babel/helper-function-name': 7.16.7
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-function-name': 7.17.9
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-transform-function-name/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-SU/C68YVwTRxqWj5kgsbKINakGag0KTgq9f2iZEXdStoAbOzLHEBRYzImmA6yFo8YZhJVflvXmIHUO7GWHmxxA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-compilation-targets': 7.16.7_@babel+core@7.19.6
+      '@babel/helper-function-name': 7.17.9
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-literals/7.16.7_@babel+core@7.13.16:
@@ -1979,7 +3242,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-literals/7.16.7_@babel+core@7.17.2:
@@ -1989,7 +3252,17 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-transform-literals/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   
/@babel/plugin-transform-member-expression-literals/7.16.7_@babel+core@7.13.16:
@@ -1999,7 +3272,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   
/@babel/plugin-transform-member-expression-literals/7.16.7_@babel+core@7.17.2:
@@ -2009,7 +3282,17 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  
/@babel/plugin-transform-member-expression-literals/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-mBruRMbktKQwbxaJof32LT9KLy2f3gH+27a5XSuXo6h7R3vqltl0PgZ80C8ZMKw98Bf8bqt6BEVi3svOh2PzMw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-modules-amd/7.16.7_@babel+core@7.13.16:
@@ -2019,8 +3302,8 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-module-transforms': 7.16.7
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-module-transforms': 7.18.0
+      '@babel/helper-plugin-utils': 7.17.12
       babel-plugin-dynamic-import-node: 2.3.3
     transitivePeerDependencies:
       - supports-color
@@ -2033,50 +3316,64 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-module-transforms': 7.16.7
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-module-transforms': 7.18.0
+      '@babel/helper-plugin-utils': 7.17.12
+      babel-plugin-dynamic-import-node: 2.3.3
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@babel/plugin-transform-modules-amd/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-KaaEtgBL7FKYwjJ/teH63oAmE3lP34N3kshz8mm4VMAw7U3PxjVwwUmxEFksbgsNUaO3wId9R2AVQYSEGRa2+g==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-module-transforms': 7.18.0
+      '@babel/helper-plugin-utils': 7.17.12
       babel-plugin-dynamic-import-node: 2.3.3
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@babel/plugin-transform-modules-commonjs/7.16.8_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-oflKPvsLT2+uKQopesJt3ApiaIS2HW+hzHFcwRNtyDGieAeC/dIHZX8buJQ2J2X1rxGPy4eRcUijm3qcSPjYcA==}
+  /@babel/plugin-transform-modules-commonjs/7.18.2_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-f5A865gFPAJAEE0K7F/+nm5CmAE3y8AWlMBG9unu5j9+tk50UQVK0QS8RNxSp7MJf0wh97uYyLWt3Zvu71zyOQ==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-module-transforms': 7.16.7
-      '@babel/helper-plugin-utils': 7.16.7
-      '@babel/helper-simple-access': 7.16.7
+      '@babel/helper-module-transforms': 7.18.0
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/helper-simple-access': 7.18.2
       babel-plugin-dynamic-import-node: 2.3.3
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@babel/plugin-transform-modules-commonjs/7.16.8_@babel+core@7.17.2:
-    resolution: {integrity: 
sha512-oflKPvsLT2+uKQopesJt3ApiaIS2HW+hzHFcwRNtyDGieAeC/dIHZX8buJQ2J2X1rxGPy4eRcUijm3qcSPjYcA==}
+  /@babel/plugin-transform-modules-commonjs/7.18.2_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-f5A865gFPAJAEE0K7F/+nm5CmAE3y8AWlMBG9unu5j9+tk50UQVK0QS8RNxSp7MJf0wh97uYyLWt3Zvu71zyOQ==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-module-transforms': 7.16.7
-      '@babel/helper-plugin-utils': 7.16.7
-      '@babel/helper-simple-access': 7.16.7
+      '@babel/helper-module-transforms': 7.18.0
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/helper-simple-access': 7.18.2
       babel-plugin-dynamic-import-node: 2.3.3
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@babel/plugin-transform-modules-commonjs/7.18.2_@babel+core@7.13.16:
+  /@babel/plugin-transform-modules-commonjs/7.18.2_@babel+core@7.19.6:
     resolution: {integrity: 
sha512-f5A865gFPAJAEE0K7F/+nm5CmAE3y8AWlMBG9unu5j9+tk50UQVK0QS8RNxSp7MJf0wh97uYyLWt3Zvu71zyOQ==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.13.16
+      '@babel/core': 7.19.6
       '@babel/helper-module-transforms': 7.18.0
       '@babel/helper-plugin-utils': 7.17.12
       '@babel/helper-simple-access': 7.18.2
@@ -2093,8 +3390,8 @@ packages:
     dependencies:
       '@babel/core': 7.13.16
       '@babel/helper-hoist-variables': 7.16.7
-      '@babel/helper-module-transforms': 7.16.7
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-module-transforms': 7.18.0
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/helper-validator-identifier': 7.16.7
       babel-plugin-dynamic-import-node: 2.3.3
     transitivePeerDependencies:
@@ -2109,8 +3406,24 @@ packages:
     dependencies:
       '@babel/core': 7.17.2
       '@babel/helper-hoist-variables': 7.16.7
-      '@babel/helper-module-transforms': 7.16.7
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-module-transforms': 7.18.0
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/helper-validator-identifier': 7.16.7
+      babel-plugin-dynamic-import-node: 2.3.3
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@babel/plugin-transform-modules-systemjs/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-DuK5E3k+QQmnOqBR9UkusByy5WZWGRxfzV529s9nPra1GE7olmxfqO2FHobEOYSPIjPBTr4p66YDcjQnt8cBmw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-hoist-variables': 7.16.7
+      '@babel/helper-module-transforms': 7.18.0
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/helper-validator-identifier': 7.16.7
       babel-plugin-dynamic-import-node: 2.3.3
     transitivePeerDependencies:
@@ -2124,8 +3437,8 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-module-transforms': 7.16.7
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-module-transforms': 7.18.0
+      '@babel/helper-plugin-utils': 7.17.12
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -2137,8 +3450,21 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-module-transforms': 7.16.7
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-module-transforms': 7.18.0
+      '@babel/helper-plugin-utils': 7.17.12
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@babel/plugin-transform-modules-umd/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-EMh7uolsC8O4xhudF2F6wedbSHm1HHZ0C6aJ7K67zcDNidMzVcxWdGr+htW9n21klm+bOn+Rx4CBsAntZd3rEQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-module-transforms': 7.18.0
+      '@babel/helper-plugin-utils': 7.17.12
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -2163,6 +3489,16 @@ packages:
       '@babel/helper-create-regexp-features-plugin': 7.17.0_@babel+core@7.17.2
     dev: true
 
+  
/@babel/plugin-transform-named-capturing-groups-regex/7.16.8_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-j3Jw+n5PvpmhRR+mrgIh04puSANCk/T/UA3m3P1MjJkhlK906+ApHhDIqBQDdOgL/r1UYpz4GNclTXxyZrYGSw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-create-regexp-features-plugin': 7.17.0_@babel+core@7.19.6
+    dev: true
+
   /@babel/plugin-transform-new-target/7.16.7_@babel+core@7.13.16:
     resolution: {integrity: 
sha512-xiLDzWNMfKoGOpc6t3U+etCE2yRnn3SM09BXqWPIZOBpL2gvVrBWUKnsJx0K/ADi5F5YC5f8APFfWrz25TdlGg==}
     engines: {node: '>=6.9.0'}
@@ -2170,7 +3506,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-new-target/7.16.7_@babel+core@7.17.2:
@@ -2180,7 +3516,17 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-transform-new-target/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-xiLDzWNMfKoGOpc6t3U+etCE2yRnn3SM09BXqWPIZOBpL2gvVrBWUKnsJx0K/ADi5F5YC5f8APFfWrz25TdlGg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-object-assign/7.16.7_@babel+core@7.17.2:
@@ -2190,7 +3536,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-object-super/7.16.7_@babel+core@7.13.16:
@@ -2200,7 +3546,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/helper-replace-supers': 7.16.7
     transitivePeerDependencies:
       - supports-color
@@ -2213,161 +3559,351 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/helper-replace-supers': 7.16.7
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@babel/plugin-transform-parameters/7.16.7_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw==}
+  /@babel/plugin-transform-object-super/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-14J1feiQVWaGvRxj2WjyMuXS2jsBkgB3MdSN5HuC2G5nRspa5RK9COcs82Pwy5BuGcjb+fYaUj94mYcOj7rCvw==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/helper-replace-supers': 7.16.7
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /@babel/plugin-transform-parameters/7.16.7_@babel+core@7.17.2:
+  /@babel/plugin-transform-parameters/7.16.7_@babel+core@7.12.9:
     resolution: {integrity: 
sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/core': 7.12.9
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
-  /@babel/plugin-transform-property-literals/7.16.7_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw==}
+  /@babel/plugin-transform-parameters/7.16.7_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
-  /@babel/plugin-transform-property-literals/7.16.7_@babel+core@7.17.2:
-    resolution: {integrity: 
sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw==}
+  /@babel/plugin-transform-parameters/7.16.7_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
-  /@babel/plugin-transform-react-jsx-source/7.14.5_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-1TpSDnD9XR/rQ2tzunBVPThF5poaYT9GqP+of8fAtguYuI/dm2RkrMBDemsxtY0XBzvW7nXjYM0hRyKX9QYj7Q==}
+  /@babel/plugin-transform-parameters/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-transform-property-literals/7.16.7_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.14.5
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
-  /@babel/plugin-transform-react-jsx/7.16.7_@babel+core@7.17.2:
-    resolution: {integrity: 
sha512-8D16ye66fxiE8m890w0BpPpngG9o9OVBBy0gH2E+2AR7qMR2ZpTYJEqLxAsoroenMId0p/wMW+Blc0meDgu0Ag==}
+  /@babel/plugin-transform-property-literals/7.16.7_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-annotate-as-pure': 7.16.7
-      '@babel/helper-module-imports': 7.16.7
-      '@babel/helper-plugin-utils': 7.16.7
-      '@babel/plugin-syntax-jsx': 7.16.7_@babel+core@7.17.2
-      '@babel/types': 7.17.0
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
-  /@babel/plugin-transform-regenerator/7.16.7_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-mF7jOgGYCkSJagJ6XCujSQg+6xC1M77/03K2oBmVJWoFGNUtnVJO4WHKJk3dnPC8HCcj4xBQP1Egm8DWh3Pb3Q==}
+  /@babel/plugin-transform-property-literals/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.13.16
-      regenerator-transform: 0.14.5
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
-  /@babel/plugin-transform-regenerator/7.16.7_@babel+core@7.17.2:
-    resolution: {integrity: 
sha512-mF7jOgGYCkSJagJ6XCujSQg+6xC1M77/03K2oBmVJWoFGNUtnVJO4WHKJk3dnPC8HCcj4xBQP1Egm8DWh3Pb3Q==}
+  /@babel/plugin-transform-react-display-name/7.18.6_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      regenerator-transform: 0.14.5
+      '@babel/helper-plugin-utils': 7.19.0
     dev: true
 
-  /@babel/plugin-transform-reserved-words/7.16.7_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg==}
+  /@babel/plugin-transform-react-display-name/7.18.6_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.19.0
     dev: true
 
-  /@babel/plugin-transform-reserved-words/7.16.7_@babel+core@7.17.2:
-    resolution: {integrity: 
sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg==}
+  /@babel/plugin-transform-react-jsx-development/7.18.6_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.17.2
     dev: true
 
-  /@babel/plugin-transform-runtime/7.17.0_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-fr7zPWnKXNc1xoHfrIU9mN/4XKX4VLZ45Q+oMhfsYIaHvg7mHgmhfOy/ckRWqDK7XF3QDigRpkh5DKq6+clE8A==}
+  /@babel/plugin-transform-react-jsx-development/7.18.6_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.13.16
-      '@babel/helper-module-imports': 7.16.7
-      '@babel/helper-plugin-utils': 7.16.7
-      babel-plugin-polyfill-corejs2: 0.3.1_@babel+core@7.13.16
-      babel-plugin-polyfill-corejs3: 0.5.2_@babel+core@7.13.16
-      babel-plugin-polyfill-regenerator: 0.3.1_@babel+core@7.13.16
-      semver: 6.3.0
-    transitivePeerDependencies:
-      - supports-color
+      '@babel/core': 7.19.6
+      '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.19.6
     dev: true
 
-  /@babel/plugin-transform-shorthand-properties/7.16.7_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg==}
+  /@babel/plugin-transform-react-jsx-source/7.14.5_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-1TpSDnD9XR/rQ2tzunBVPThF5poaYT9GqP+of8fAtguYuI/dm2RkrMBDemsxtY0XBzvW7nXjYM0hRyKX9QYj7Q==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
-  /@babel/plugin-transform-shorthand-properties/7.16.7_@babel+core@7.17.2:
-    resolution: {integrity: 
sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg==}
+  /@babel/plugin-transform-react-jsx-source/7.14.5_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-1TpSDnD9XR/rQ2tzunBVPThF5poaYT9GqP+of8fAtguYuI/dm2RkrMBDemsxtY0XBzvW7nXjYM0hRyKX9QYj7Q==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
-  /@babel/plugin-transform-spread/7.16.7_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg==}
+  /@babel/plugin-transform-react-jsx/7.16.7_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-8D16ye66fxiE8m890w0BpPpngG9o9OVBBy0gH2E+2AR7qMR2ZpTYJEqLxAsoroenMId0p/wMW+Blc0meDgu0Ag==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/helper-annotate-as-pure': 7.16.7
+      '@babel/helper-module-imports': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/plugin-syntax-jsx': 7.16.7_@babel+core@7.17.2
+      '@babel/types': 7.18.4
+    dev: true
+
+  /@babel/plugin-transform-react-jsx/7.19.0_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/helper-annotate-as-pure': 7.18.6
+      '@babel/helper-module-imports': 7.18.6
+      '@babel/helper-plugin-utils': 7.19.0
+      '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.17.2
+      '@babel/types': 7.19.4
+    dev: true
+
+  /@babel/plugin-transform-react-jsx/7.19.0_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-annotate-as-pure': 7.18.6
+      '@babel/helper-module-imports': 7.18.6
+      '@babel/helper-plugin-utils': 7.19.0
+      '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.19.6
+      '@babel/types': 7.19.4
+    dev: true
+
+  /@babel/plugin-transform-react-pure-annotations/7.18.6_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/helper-annotate-as-pure': 7.18.6
+      '@babel/helper-plugin-utils': 7.19.0
+    dev: true
+
+  /@babel/plugin-transform-react-pure-annotations/7.18.6_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-annotate-as-pure': 7.18.6
+      '@babel/helper-plugin-utils': 7.19.0
+    dev: true
+
+  /@babel/plugin-transform-regenerator/7.16.7_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-mF7jOgGYCkSJagJ6XCujSQg+6xC1M77/03K2oBmVJWoFGNUtnVJO4WHKJk3dnPC8HCcj4xBQP1Egm8DWh3Pb3Q==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.13.16
+      regenerator-transform: 0.14.5
+    dev: true
+
+  /@babel/plugin-transform-regenerator/7.16.7_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-mF7jOgGYCkSJagJ6XCujSQg+6xC1M77/03K2oBmVJWoFGNUtnVJO4WHKJk3dnPC8HCcj4xBQP1Egm8DWh3Pb3Q==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.17.2
+      regenerator-transform: 0.14.5
+    dev: true
+
+  /@babel/plugin-transform-regenerator/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-mF7jOgGYCkSJagJ6XCujSQg+6xC1M77/03K2oBmVJWoFGNUtnVJO4WHKJk3dnPC8HCcj4xBQP1Egm8DWh3Pb3Q==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      regenerator-transform: 0.14.5
+    dev: true
+
+  /@babel/plugin-transform-reserved-words/7.16.7_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.13.16
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-transform-reserved-words/7.16.7_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-transform-reserved-words/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-transform-runtime/7.17.0_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-fr7zPWnKXNc1xoHfrIU9mN/4XKX4VLZ45Q+oMhfsYIaHvg7mHgmhfOy/ckRWqDK7XF3QDigRpkh5DKq6+clE8A==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.13.16
+      '@babel/helper-module-imports': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+      babel-plugin-polyfill-corejs2: 0.3.1_@babel+core@7.13.16
+      babel-plugin-polyfill-corejs3: 0.5.2_@babel+core@7.13.16
+      babel-plugin-polyfill-regenerator: 0.3.1_@babel+core@7.13.16
+      semver: 6.3.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@babel/plugin-transform-runtime/7.17.0_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-fr7zPWnKXNc1xoHfrIU9mN/4XKX4VLZ45Q+oMhfsYIaHvg7mHgmhfOy/ckRWqDK7XF3QDigRpkh5DKq6+clE8A==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/helper-module-imports': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+      babel-plugin-polyfill-corejs2: 0.3.1_@babel+core@7.17.2
+      babel-plugin-polyfill-corejs3: 0.5.2_@babel+core@7.17.2
+      babel-plugin-polyfill-regenerator: 0.3.1_@babel+core@7.17.2
+      semver: 6.3.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@babel/plugin-transform-shorthand-properties/7.16.7_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.13.16
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-transform-shorthand-properties/7.16.7_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-transform-shorthand-properties/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-transform-spread/7.16.7_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/helper-skip-transparent-expression-wrappers': 7.16.0
     dev: true
 
@@ -2378,7 +3914,18 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/helper-skip-transparent-expression-wrappers': 7.16.0
+    dev: true
+
+  /@babel/plugin-transform-spread/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/helper-skip-transparent-expression-wrappers': 7.16.0
     dev: true
 
@@ -2389,7 +3936,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-sticky-regex/7.16.7_@babel+core@7.17.2:
@@ -2399,7 +3946,17 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-transform-sticky-regex/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-NJa0Bd/87QV5NZZzTuZG5BPJjLYadeSZ9fO6oOUoL4iQx+9EEuw/eEM92SrsT19Yc2jgB1u1hsjqDtH02c3Drw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-template-literals/7.16.7_@babel+core@7.13.16:
@@ -2409,7 +3966,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-template-literals/7.16.7_@babel+core@7.17.2:
@@ -2419,7 +3976,17 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-transform-template-literals/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-typeof-symbol/7.16.7_@babel+core@7.13.16:
@@ -2429,7 +3996,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-typeof-symbol/7.16.7_@babel+core@7.17.2:
@@ -2439,7 +4006,17 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-transform-typeof-symbol/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-p2rOixCKRJzpg9JB4gjnG4gjWkWa89ZoYUnl9snJ1cWIcTH/hvxZqfO+WjG6T8DRBpctEol5jw1O5rA8gkCokQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-typescript/7.15.0_@babel+core@7.13.16:
@@ -2450,7 +4027,7 @@ packages:
     dependencies:
       '@babel/core': 7.13.16
       '@babel/helper-create-class-features-plugin': 7.15.0_@babel+core@7.13.16
-      '@babel/helper-plugin-utils': 7.14.5
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/plugin-syntax-typescript': 7.14.5_@babel+core@7.13.16
     transitivePeerDependencies:
       - supports-color
@@ -2464,12 +4041,26 @@ packages:
     dependencies:
       '@babel/core': 7.17.2
       '@babel/helper-create-class-features-plugin': 7.17.1_@babel+core@7.17.2
-      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/helper-plugin-utils': 7.19.0
       '@babel/plugin-syntax-typescript': 7.16.7_@babel+core@7.17.2
     transitivePeerDependencies:
       - supports-color
     dev: true
 
+  /@babel/plugin-transform-typescript/7.16.8_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-bHdQ9k7YpBDO2d0NVfkj51DpQcvwIzIusJ7mEUaMlbZq3Kt/U47j24inXZHQ5MDiYpCs+oZiwnXyKedE8+q7AQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-create-class-features-plugin': 7.17.1_@babel+core@7.19.6
+      '@babel/helper-plugin-utils': 7.19.0
+      '@babel/plugin-syntax-typescript': 7.16.7_@babel+core@7.19.6
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /@babel/plugin-transform-unicode-escapes/7.16.7_@babel+core@7.13.16:
     resolution: {integrity: 
sha512-TAV5IGahIz3yZ9/Hfv35TV2xEm+kaBDaZQCn2S/hG9/CZ0DktxJv9eKfPc7yYCvOYR4JGx1h8C+jcSOvgaaI/Q==}
     engines: {node: '>=6.9.0'}
@@ -2477,7 +4068,7 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-unicode-escapes/7.16.7_@babel+core@7.17.2:
@@ -2487,7 +4078,17 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-transform-unicode-escapes/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-TAV5IGahIz3yZ9/Hfv35TV2xEm+kaBDaZQCn2S/hG9/CZ0DktxJv9eKfPc7yYCvOYR4JGx1h8C+jcSOvgaaI/Q==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-unicode-regex/7.16.7_@babel+core@7.13.16:
@@ -2498,7 +4099,7 @@ packages:
     dependencies:
       '@babel/core': 7.13.16
       '@babel/helper-create-regexp-features-plugin': 7.17.0_@babel+core@7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/plugin-transform-unicode-regex/7.16.7_@babel+core@7.17.2:
@@ -2509,7 +4110,18 @@ packages:
     dependencies:
       '@babel/core': 7.17.2
       '@babel/helper-create-regexp-features-plugin': 7.17.0_@babel+core@7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
+    dev: true
+
+  /@babel/plugin-transform-unicode-regex/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-oC5tYYKw56HO75KZVLQ+R/Nl3Hro9kf8iG0hXoaHP7tjAyCpvqBiSNe6vGrZni1Z6MggmUOC6A7VP7AVmw225Q==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-create-regexp-features-plugin': 7.17.0_@babel+core@7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
     dev: true
 
   /@babel/preset-env/7.16.11_@babel+core@7.13.16:
@@ -2521,7 +4133,7 @@ packages:
       '@babel/compat-data': 7.17.0
       '@babel/core': 7.13.16
       '@babel/helper-compilation-targets': 7.16.7_@babel+core@7.13.16
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/helper-validator-option': 7.16.7
       
'@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression':
 7.16.7_@babel+core@7.13.16
       '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 
7.16.7_@babel+core@7.13.16
@@ -2569,7 +4181,7 @@ packages:
       '@babel/plugin-transform-literals': 7.16.7_@babel+core@7.13.16
       '@babel/plugin-transform-member-expression-literals': 
7.16.7_@babel+core@7.13.16
       '@babel/plugin-transform-modules-amd': 7.16.7_@babel+core@7.13.16
-      '@babel/plugin-transform-modules-commonjs': 7.16.8_@babel+core@7.13.16
+      '@babel/plugin-transform-modules-commonjs': 7.18.2_@babel+core@7.13.16
       '@babel/plugin-transform-modules-systemjs': 7.16.7_@babel+core@7.13.16
       '@babel/plugin-transform-modules-umd': 7.16.7_@babel+core@7.13.16
       '@babel/plugin-transform-named-capturing-groups-regex': 
7.16.8_@babel+core@7.13.16
@@ -2587,7 +4199,7 @@ packages:
       '@babel/plugin-transform-unicode-escapes': 7.16.7_@babel+core@7.13.16
       '@babel/plugin-transform-unicode-regex': 7.16.7_@babel+core@7.13.16
       '@babel/preset-modules': 0.1.5_@babel+core@7.13.16
-      '@babel/types': 7.17.0
+      '@babel/types': 7.18.4
       babel-plugin-polyfill-corejs2: 0.3.1_@babel+core@7.13.16
       babel-plugin-polyfill-corejs3: 0.5.2_@babel+core@7.13.16
       babel-plugin-polyfill-regenerator: 0.3.1_@babel+core@7.13.16
@@ -2606,7 +4218,7 @@ packages:
       '@babel/compat-data': 7.17.0
       '@babel/core': 7.17.2
       '@babel/helper-compilation-targets': 7.16.7_@babel+core@7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/helper-validator-option': 7.16.7
       
'@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression':
 7.16.7_@babel+core@7.17.2
       '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 
7.16.7_@babel+core@7.17.2
@@ -2654,7 +4266,7 @@ packages:
       '@babel/plugin-transform-literals': 7.16.7_@babel+core@7.17.2
       '@babel/plugin-transform-member-expression-literals': 
7.16.7_@babel+core@7.17.2
       '@babel/plugin-transform-modules-amd': 7.16.7_@babel+core@7.17.2
-      '@babel/plugin-transform-modules-commonjs': 7.16.8_@babel+core@7.17.2
+      '@babel/plugin-transform-modules-commonjs': 7.18.2_@babel+core@7.17.2
       '@babel/plugin-transform-modules-systemjs': 7.16.7_@babel+core@7.17.2
       '@babel/plugin-transform-modules-umd': 7.16.7_@babel+core@7.17.2
       '@babel/plugin-transform-named-capturing-groups-regex': 
7.16.8_@babel+core@7.17.2
@@ -2672,7 +4284,7 @@ packages:
       '@babel/plugin-transform-unicode-escapes': 7.16.7_@babel+core@7.17.2
       '@babel/plugin-transform-unicode-regex': 7.16.7_@babel+core@7.17.2
       '@babel/preset-modules': 0.1.5_@babel+core@7.17.2
-      '@babel/types': 7.17.0
+      '@babel/types': 7.18.4
       babel-plugin-polyfill-corejs2: 0.3.1_@babel+core@7.17.2
       babel-plugin-polyfill-corejs3: 0.5.2_@babel+core@7.17.2
       babel-plugin-polyfill-regenerator: 0.3.1_@babel+core@7.17.2
@@ -2682,16 +4294,101 @@ packages:
       - supports-color
     dev: true
 
+  /@babel/preset-env/7.16.11_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-qcmWG8R7ZW6WBRPZK//y+E3Cli151B20W1Rv7ln27vuPaXU/8TKms6jFdiJtF7UDTxcrb7mZd88tAeK9LjdT8g==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/compat-data': 7.17.0
+      '@babel/core': 7.19.6
+      '@babel/helper-compilation-targets': 7.16.7_@babel+core@7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/helper-validator-option': 7.16.7
+      
'@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression':
 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 
7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-async-generator-functions': 
7.16.8_@babel+core@7.19.6
+      '@babel/plugin-proposal-class-properties': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-class-static-block': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-dynamic-import': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-export-namespace-from': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-json-strings': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-logical-assignment-operators': 
7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-nullish-coalescing-operator': 
7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-numeric-separator': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-object-rest-spread': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-optional-catch-binding': 
7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-optional-chaining': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-private-methods': 7.16.11_@babel+core@7.19.6
+      '@babel/plugin-proposal-private-property-in-object': 
7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-unicode-property-regex': 
7.16.7_@babel+core@7.19.6
+      '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.19.6
+      '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.19.6
+      '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.19.6
+      '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.19.6
+      '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.19.6
+      '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.19.6
+      '@babel/plugin-syntax-logical-assignment-operators': 
7.10.4_@babel+core@7.19.6
+      '@babel/plugin-syntax-nullish-coalescing-operator': 
7.8.3_@babel+core@7.19.6
+      '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.19.6
+      '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.19.6
+      '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.19.6
+      '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.19.6
+      '@babel/plugin-syntax-private-property-in-object': 
7.14.5_@babel+core@7.19.6
+      '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.19.6
+      '@babel/plugin-transform-arrow-functions': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-async-to-generator': 7.16.8_@babel+core@7.19.6
+      '@babel/plugin-transform-block-scoped-functions': 
7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-block-scoping': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-classes': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-computed-properties': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-destructuring': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-dotall-regex': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-duplicate-keys': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-exponentiation-operator': 
7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-for-of': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-function-name': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-literals': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-member-expression-literals': 
7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-modules-amd': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-modules-commonjs': 7.18.2_@babel+core@7.19.6
+      '@babel/plugin-transform-modules-systemjs': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-modules-umd': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-named-capturing-groups-regex': 
7.16.8_@babel+core@7.19.6
+      '@babel/plugin-transform-new-target': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-object-super': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-parameters': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-property-literals': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-regenerator': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-reserved-words': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-shorthand-properties': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-spread': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-sticky-regex': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-template-literals': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-typeof-symbol': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-unicode-escapes': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-unicode-regex': 7.16.7_@babel+core@7.19.6
+      '@babel/preset-modules': 0.1.5_@babel+core@7.19.6
+      '@babel/types': 7.18.4
+      babel-plugin-polyfill-corejs2: 0.3.1_@babel+core@7.19.6
+      babel-plugin-polyfill-corejs3: 0.5.2_@babel+core@7.19.6
+      babel-plugin-polyfill-regenerator: 0.3.1_@babel+core@7.19.6
+      core-js-compat: 3.21.0
+      semver: 6.3.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /@babel/preset-modules/0.1.5_@babel+core@7.13.16:
     resolution: {integrity: 
sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.13.16
-      '@babel/helper-plugin-utils': 7.14.5
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/plugin-proposal-unicode-property-regex': 
7.16.7_@babel+core@7.13.16
       '@babel/plugin-transform-dotall-regex': 7.16.7_@babel+core@7.13.16
-      '@babel/types': 7.17.0
+      '@babel/types': 7.18.4
       esutils: 2.0.3
     dev: true
 
@@ -2701,13 +4398,56 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.14.5
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/plugin-proposal-unicode-property-regex': 
7.16.7_@babel+core@7.17.2
       '@babel/plugin-transform-dotall-regex': 7.16.7_@babel+core@7.17.2
-      '@babel/types': 7.17.0
+      '@babel/types': 7.18.4
+      esutils: 2.0.3
+    dev: true
+
+  /@babel/preset-modules/0.1.5_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/plugin-proposal-unicode-property-regex': 
7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-dotall-regex': 7.16.7_@babel+core@7.19.6
+      '@babel/types': 7.18.4
       esutils: 2.0.3
     dev: true
 
+  /@babel/preset-react/7.18.6_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/helper-plugin-utils': 7.19.0
+      '@babel/helper-validator-option': 7.18.6
+      '@babel/plugin-transform-react-display-name': 7.18.6_@babel+core@7.17.2
+      '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.17.2
+      '@babel/plugin-transform-react-jsx-development': 
7.18.6_@babel+core@7.17.2
+      '@babel/plugin-transform-react-pure-annotations': 
7.18.6_@babel+core@7.17.2
+    dev: true
+
+  /@babel/preset-react/7.18.6_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.19.0
+      '@babel/helper-validator-option': 7.18.6
+      '@babel/plugin-transform-react-display-name': 7.18.6_@babel+core@7.19.6
+      '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.19.6
+      '@babel/plugin-transform-react-jsx-development': 
7.18.6_@babel+core@7.19.6
+      '@babel/plugin-transform-react-pure-annotations': 
7.18.6_@babel+core@7.19.6
+    dev: true
+
   /@babel/preset-typescript/7.15.0_@babel+core@7.13.16:
     resolution: {integrity: 
sha512-lt0Y/8V3y06Wq/8H/u0WakrqciZ7Fz7mwPDHWUJAXlABL5hiUG42BNlRXiELNjeWjO5rWmnNKlx+yzJvxezHow==}
     engines: {node: '>=6.9.0'}
@@ -2729,13 +4469,55 @@ packages:
       '@babel/core': ^7.0.0-0
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-plugin-utils': 7.16.7
+      '@babel/helper-plugin-utils': 7.17.12
       '@babel/helper-validator-option': 7.16.7
       '@babel/plugin-transform-typescript': 7.16.8_@babel+core@7.17.2
     transitivePeerDependencies:
       - supports-color
     dev: true
 
+  /@babel/preset-typescript/7.16.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-WbVEmgXdIyvzB77AQjGBEyYPZx+8tTsO50XtfozQrkW8QB2rLJpH2lgx0TRw5EJrBxOZQ+wCcyPVQvS8tjEHpQ==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-plugin-utils': 7.17.12
+      '@babel/helper-validator-option': 7.16.7
+      '@babel/plugin-transform-typescript': 7.16.8_@babel+core@7.19.6
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@babel/register/7.18.9_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-ZlbnXDcNYHMR25ITwwNKT88JiaukkdVj/nG7r3wnuXkOTHc60Uy05PwMCPre0hSkY68E6zK3xz+vUJSP2jWmcw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.17.2
+      clone-deep: 4.0.1
+      find-cache-dir: 2.1.0
+      make-dir: 2.1.0
+      pirates: 4.0.5
+      source-map-support: 0.5.21
+    dev: true
+
+  /@babel/register/7.18.9_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-ZlbnXDcNYHMR25ITwwNKT88JiaukkdVj/nG7r3wnuXkOTHc60Uy05PwMCPre0hSkY68E6zK3xz+vUJSP2jWmcw==}
+    engines: {node: '>=6.9.0'}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      clone-deep: 4.0.1
+      find-cache-dir: 2.1.0
+      make-dir: 2.1.0
+      pirates: 4.0.5
+      source-map-support: 0.5.21
+    dev: true
+
   /@babel/runtime-corejs3/7.16.7:
     resolution: {integrity: 
sha512-MiYR1yk8+TW/CpOD0CyX7ve9ffWTKqLk/L6pk8TPl0R8pNi+1pFY8fH9yET55KlvukQ4PAWfXsGr2YHVjcI4Pw==}
     engines: {node: '>=6.9.0'}
@@ -2751,13 +4533,6 @@ packages:
       regenerator-runtime: 0.13.9
     dev: false
 
-  /@babel/runtime/7.16.3:
-    resolution: {integrity: 
sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      regenerator-runtime: 0.13.9
-    dev: true
-
   /@babel/runtime/7.16.7:
     resolution: {integrity: 
sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ==}
     engines: {node: '>=6.9.0'}
@@ -2777,15 +4552,14 @@ packages:
     engines: {node: '>=6.9.0'}
     dependencies:
       regenerator-runtime: 0.13.9
-    dev: true
 
   /@babel/template/7.14.5:
     resolution: {integrity: 
sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==}
     engines: {node: '>=6.9.0'}
     dependencies:
       '@babel/code-frame': 7.16.7
-      '@babel/parser': 7.15.3
-      '@babel/types': 7.15.0
+      '@babel/parser': 7.18.4
+      '@babel/types': 7.18.4
     dev: true
 
   /@babel/template/7.16.7:
@@ -2793,26 +4567,17 @@ packages:
     engines: {node: '>=6.9.0'}
     dependencies:
       '@babel/code-frame': 7.16.7
-      '@babel/parser': 7.17.0
-      '@babel/types': 7.17.0
+      '@babel/parser': 7.18.4
+      '@babel/types': 7.18.4
     dev: true
 
-  /@babel/traverse/7.16.7:
-    resolution: {integrity: 
sha512-8KWJPIb8c2VvY8AJrydh6+fVRo2ODx1wYBU2398xJVq0JomuLBZmVQzLPBblJgHIGYG4znCpUZUZ0Pt2vdmVYQ==}
+  /@babel/template/7.18.10:
+    resolution: {integrity: 
sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/code-frame': 7.16.7
-      '@babel/generator': 7.17.0
-      '@babel/helper-environment-visitor': 7.16.7
-      '@babel/helper-function-name': 7.16.7
-      '@babel/helper-hoist-variables': 7.16.7
-      '@babel/helper-split-export-declaration': 7.16.7
-      '@babel/parser': 7.17.0
-      '@babel/types': 7.18.4
-      debug: 4.3.3
-      globals: 11.12.0
-    transitivePeerDependencies:
-      - supports-color
+      '@babel/code-frame': 7.18.6
+      '@babel/parser': 7.19.6
+      '@babel/types': 7.19.4
     dev: true
 
   /@babel/traverse/7.17.0:
@@ -2820,14 +4585,14 @@ packages:
     engines: {node: '>=6.9.0'}
     dependencies:
       '@babel/code-frame': 7.16.7
-      '@babel/generator': 7.17.0
+      '@babel/generator': 7.18.2
       '@babel/helper-environment-visitor': 7.16.7
       '@babel/helper-function-name': 7.16.7
       '@babel/helper-hoist-variables': 7.16.7
       '@babel/helper-split-export-declaration': 7.16.7
-      '@babel/parser': 7.17.0
-      '@babel/types': 7.17.0
-      debug: 4.3.3
+      '@babel/parser': 7.18.4
+      '@babel/types': 7.18.4
+      debug: 4.3.4
       globals: 11.12.0
     transitivePeerDependencies:
       - supports-color
@@ -2845,52 +4610,136 @@ packages:
       '@babel/helper-split-export-declaration': 7.16.7
       '@babel/parser': 7.18.4
       '@babel/types': 7.18.4
-      debug: 4.3.3
+      debug: 4.3.4
       globals: 11.12.0
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@babel/types/7.15.0:
-    resolution: {integrity: 
sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ==}
+  /@babel/traverse/7.19.6:
+    resolution: {integrity: 
sha512-6l5HrUCzFM04mfbG09AagtYyR2P0B71B1wN7PfSPiksDPz2k5H9CBC1tcZpz2M8OxbKTPccByoOJ22rUKbpmQQ==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/helper-validator-identifier': 7.14.9
-      to-fast-properties: 2.0.0
+      '@babel/code-frame': 7.18.6
+      '@babel/generator': 7.19.6
+      '@babel/helper-environment-visitor': 7.18.9
+      '@babel/helper-function-name': 7.19.0
+      '@babel/helper-hoist-variables': 7.18.6
+      '@babel/helper-split-export-declaration': 7.18.6
+      '@babel/parser': 7.19.6
+      '@babel/types': 7.19.4
+      debug: 4.3.4
+      globals: 11.12.0
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /@babel/types/7.16.7:
-    resolution: {integrity: 
sha512-E8HuV7FO9qLpx6OtoGfUQ2cjIYnbFwvZWYBS+87EwtdMvmUPJSwykpovFB+8insbpF0uJcpr8KMUi64XZntZcg==}
+  /@babel/types/7.17.0:
+    resolution: {integrity: 
sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==}
     engines: {node: '>=6.9.0'}
     dependencies:
       '@babel/helper-validator-identifier': 7.16.7
       to-fast-properties: 2.0.0
     dev: true
 
-  /@babel/types/7.17.0:
-    resolution: {integrity: 
sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==}
+  /@babel/types/7.18.4:
+    resolution: {integrity: 
sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw==}
     engines: {node: '>=6.9.0'}
     dependencies:
       '@babel/helper-validator-identifier': 7.16.7
       to-fast-properties: 2.0.0
     dev: true
 
-  /@babel/types/7.18.4:
-    resolution: {integrity: 
sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw==}
+  /@babel/types/7.19.4:
+    resolution: {integrity: 
sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/helper-validator-identifier': 7.16.7
+      '@babel/helper-string-parser': 7.19.4
+      '@babel/helper-validator-identifier': 7.19.1
       to-fast-properties: 2.0.0
     dev: true
 
+  /@base2/pretty-print-object/1.0.1:
+    resolution: {integrity: 
sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA==}
+    dev: true
+
   /@bcoe/v8-coverage/0.2.3:
     resolution: {integrity: 
sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
     dev: true
 
+  /@cnakazawa/watch/1.0.4:
+    resolution: {integrity: 
sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==}
+    engines: {node: '>=0.1.95'}
+    hasBin: true
+    dependencies:
+      exec-sh: 0.3.6
+      minimist: 1.2.5
+    dev: true
+
+  /@colors/colors/1.5.0:
+    resolution: {integrity: 
sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==}
+    engines: {node: '>=0.1.90'}
+    requiresBuild: true
+    dev: true
+    optional: true
+
   /@creativebulma/bulma-tooltip/1.2.0:
     resolution: {integrity: 
sha512-ooImbeXEBxf77cttbzA7X5rC5aAWm9UsXIGViFOnsqB+6M944GkB28S5R4UWRqjFd2iW4zGEkEifAU+q43pt2w==}
     dev: true
 
+  /@discoveryjs/json-ext/0.5.7:
+    resolution: {integrity: 
sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==}
+    engines: {node: '>=10.0.0'}
+    dev: true
+
+  /@emotion/cache/10.0.29:
+    resolution: {integrity: 
sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ==}
+    dependencies:
+      '@emotion/sheet': 0.9.4
+      '@emotion/stylis': 0.8.5
+      '@emotion/utils': 0.11.3
+      '@emotion/weak-memoize': 0.2.5
+    dev: true
+
+  /@emotion/core/10.3.1:
+    resolution: {integrity: 
sha512-447aUEjPIm0MnE6QYIaFz9VQOHSXf4Iu6EWOIqq11EAPqinkSZmfymPTmlOE3QjLv846lH4JVZBUOtwGbuQoww==}
+    peerDependencies:
+      react: '>=16.3.0'
+    dependencies:
+      '@babel/runtime': 7.17.8
+      '@emotion/cache': 10.0.29
+      '@emotion/css': 10.0.27
+      '@emotion/serialize': 0.11.16
+      '@emotion/sheet': 0.9.4
+      '@emotion/utils': 0.11.3
+    dev: true
+
+  /@emotion/core/10.3.1_react@16.14.0:
+    resolution: {integrity: 
sha512-447aUEjPIm0MnE6QYIaFz9VQOHSXf4Iu6EWOIqq11EAPqinkSZmfymPTmlOE3QjLv846lH4JVZBUOtwGbuQoww==}
+    peerDependencies:
+      react: '>=16.3.0'
+    dependencies:
+      '@babel/runtime': 7.17.8
+      '@emotion/cache': 10.0.29
+      '@emotion/css': 10.0.27
+      '@emotion/serialize': 0.11.16
+      '@emotion/sheet': 0.9.4
+      '@emotion/utils': 0.11.3
+      react: 16.14.0
+    dev: true
+
+  /@emotion/css/10.0.27:
+    resolution: {integrity: 
sha512-6wZjsvYeBhyZQYNrGoR5yPMYbMBNEnanDrqmsqS1mzDm1cOTu12shvl2j4QHNS36UaTE0USIJawCH9C8oW34Zw==}
+    dependencies:
+      '@emotion/serialize': 0.11.16
+      '@emotion/utils': 0.11.3
+      babel-plugin-emotion: 10.2.2
+    dev: true
+
+  /@emotion/hash/0.8.0:
+    resolution: {integrity: 
sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==}
+    dev: true
+
   /@emotion/is-prop-valid/0.8.8:
     resolution: {integrity: 
sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==}
     dependencies:
@@ -2901,18 +4750,115 @@ packages:
     resolution: {integrity: 
sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==}
     dev: true
 
+  /@emotion/serialize/0.11.16:
+    resolution: {integrity: 
sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg==}
+    dependencies:
+      '@emotion/hash': 0.8.0
+      '@emotion/memoize': 0.7.4
+      '@emotion/unitless': 0.7.5
+      '@emotion/utils': 0.11.3
+      csstype: 2.6.21
+    dev: true
+
+  /@emotion/sheet/0.9.4:
+    resolution: {integrity: 
sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA==}
+    dev: true
+
+  /@emotion/styled-base/10.3.0_@emotion+core@10.3.1:
+    resolution: {integrity: 
sha512-PBRqsVKR7QRNkmfH78hTSSwHWcwDpecH9W6heujWAcyp2wdz/64PP73s7fWS1dIPm8/Exc8JAzYS8dEWXjv60w==}
+    peerDependencies:
+      '@emotion/core': ^10.0.28
+      react: '>=16.3.0'
+    dependencies:
+      '@babel/runtime': 7.17.8
+      '@emotion/core': 10.3.1
+      '@emotion/is-prop-valid': 0.8.8
+      '@emotion/serialize': 0.11.16
+      '@emotion/utils': 0.11.3
+    dev: true
+
+  /@emotion/styled-base/10.3.0_qzeatvug73zaio2r3dlvejynye:
+    resolution: {integrity: 
sha512-PBRqsVKR7QRNkmfH78hTSSwHWcwDpecH9W6heujWAcyp2wdz/64PP73s7fWS1dIPm8/Exc8JAzYS8dEWXjv60w==}
+    peerDependencies:
+      '@emotion/core': ^10.0.28
+      react: '>=16.3.0'
+    dependencies:
+      '@babel/runtime': 7.17.8
+      '@emotion/core': 10.3.1_react@16.14.0
+      '@emotion/is-prop-valid': 0.8.8
+      '@emotion/serialize': 0.11.16
+      '@emotion/utils': 0.11.3
+      react: 16.14.0
+    dev: true
+
+  /@emotion/styled/10.3.0_@emotion+core@10.3.1:
+    resolution: {integrity: 
sha512-GgcUpXBBEU5ido+/p/mCT2/Xx+Oqmp9JzQRuC+a4lYM4i4LBBn/dWvc0rQ19N9ObA8/T4NWMrPNe79kMBDJqoQ==}
+    peerDependencies:
+      '@emotion/core': ^10.0.27
+      react: '>=16.3.0'
+    dependencies:
+      '@emotion/core': 10.3.1
+      '@emotion/styled-base': 10.3.0_@emotion+core@10.3.1
+      babel-plugin-emotion: 10.2.2
+    dev: true
+
+  /@emotion/styled/10.3.0_qzeatvug73zaio2r3dlvejynye:
+    resolution: {integrity: 
sha512-GgcUpXBBEU5ido+/p/mCT2/Xx+Oqmp9JzQRuC+a4lYM4i4LBBn/dWvc0rQ19N9ObA8/T4NWMrPNe79kMBDJqoQ==}
+    peerDependencies:
+      '@emotion/core': ^10.0.27
+      react: '>=16.3.0'
+    dependencies:
+      '@emotion/core': 10.3.1_react@16.14.0
+      '@emotion/styled-base': 10.3.0_qzeatvug73zaio2r3dlvejynye
+      babel-plugin-emotion: 10.2.2
+      react: 16.14.0
+    dev: true
+
+  /@emotion/stylis/0.8.5:
+    resolution: {integrity: 
sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==}
+    dev: true
+
+  /@emotion/unitless/0.7.5:
+    resolution: {integrity: 
sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==}
+    dev: true
+
+  /@emotion/utils/0.11.3:
+    resolution: {integrity: 
sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw==}
+    dev: true
+
+  /@emotion/weak-memoize/0.2.5:
+    resolution: {integrity: 
sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==}
+    dev: true
+
+  /@eslint/eslintrc/0.4.3:
+    resolution: {integrity: 
sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==}
+    engines: {node: ^10.12.0 || >=12.0.0}
+    dependencies:
+      ajv: 6.12.6
+      debug: 4.3.4
+      espree: 7.3.1
+      globals: 13.12.1
+      ignore: 4.0.6
+      import-fresh: 3.3.0
+      js-yaml: 3.14.1
+      minimatch: 3.1.2
+      strip-json-comments: 3.1.1
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /@eslint/eslintrc/1.0.5:
     resolution: {integrity: 
sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dependencies:
       ajv: 6.12.6
-      debug: 4.3.3
+      debug: 4.3.4
       espree: 9.3.0
       globals: 13.12.1
       ignore: 4.0.6
       import-fresh: 3.3.0
       js-yaml: 4.1.0
-      minimatch: 3.0.5
+      minimatch: 3.1.2
       strip-json-comments: 3.1.1
     transitivePeerDependencies:
       - supports-color
@@ -2922,13 +4868,56 @@ packages:
     resolution: {integrity: 
sha512-82cpyJyKRoQoRi+14ibCeGPu0CwypgtBAdBhq1WfvagpCZNKqwXbKwXllYSMG91DhmG4jt9gN8eP6lGOtozuaw==}
     dev: true
 
+  /@hapi/address/2.1.4:
+    resolution: {integrity: 
sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==}
+    deprecated: Moved to 'npm install @sideway/address'
+    dev: true
+
+  /@hapi/bourne/1.3.2:
+    resolution: {integrity: 
sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==}
+    deprecated: This version has been deprecated and is no longer supported or 
maintained
+    dev: true
+
+  /@hapi/hoek/8.5.1:
+    resolution: {integrity: 
sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==}
+    deprecated: This version has been deprecated and is no longer supported or 
maintained
+    dev: true
+
+  /@hapi/joi/15.1.1:
+    resolution: {integrity: 
sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==}
+    deprecated: Switch to 'npm install joi'
+    dependencies:
+      '@hapi/address': 2.1.4
+      '@hapi/bourne': 1.3.2
+      '@hapi/hoek': 8.5.1
+      '@hapi/topo': 3.1.6
+    dev: true
+
+  /@hapi/topo/3.1.6:
+    resolution: {integrity: 
sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==}
+    deprecated: This version has been deprecated and is no longer supported or 
maintained
+    dependencies:
+      '@hapi/hoek': 8.5.1
+    dev: true
+
+  /@humanwhocodes/config-array/0.5.0:
+    resolution: {integrity: 
sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==}
+    engines: {node: '>=10.10.0'}
+    dependencies:
+      '@humanwhocodes/object-schema': 1.2.1
+      debug: 4.3.4
+      minimatch: 3.1.2
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /@humanwhocodes/config-array/0.9.3:
     resolution: {integrity: 
sha512-3xSMlXHh03hCcCmFc0rbKp3Ivt2PFEJnQUJDDMTJQ2wkECZWdq4GePs2ctc5H8zV+cHPaq8k2vU8mrQjA6iHdQ==}
     engines: {node: '>=10.10.0'}
     dependencies:
       '@humanwhocodes/object-schema': 1.2.1
-      debug: 4.3.3
-      minimatch: 3.0.5
+      debug: 4.3.4
+      minimatch: 3.1.2
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -2953,6019 +4942,14306 @@ packages:
     engines: {node: '>=8'}
     dev: true
 
-  /@jest/types/26.6.2:
-    resolution: {integrity: 
sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==}
+  /@jest/console/26.6.2:
+    resolution: {integrity: 
sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==}
     engines: {node: '>= 10.14.2'}
     dependencies:
-      '@types/istanbul-lib-coverage': 2.0.4
-      '@types/istanbul-reports': 3.0.1
+      '@jest/types': 26.6.2
       '@types/node': 18.8.5
-      '@types/yargs': 15.0.14
       chalk: 4.1.2
+      jest-message-util: 26.6.2
+      jest-util: 26.6.2
+      slash: 3.0.0
     dev: true
 
-  /@jridgewell/gen-mapping/0.3.1:
-    resolution: {integrity: 
sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==}
-    engines: {node: '>=6.0.0'}
+  /@jest/console/27.5.1:
+    resolution: {integrity: 
sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dependencies:
-      '@jridgewell/set-array': 1.1.1
-      '@jridgewell/sourcemap-codec': 1.4.10
-      '@jridgewell/trace-mapping': 0.3.13
-    dev: true
-
-  /@jridgewell/resolve-uri/3.0.4:
-    resolution: {integrity: 
sha512-cz8HFjOFfUBtvN+NXYSFMHYRdxZMaEl0XypVrhzxBgadKIXhIkRd8aMeHhmF56Sl7SuS8OnUpQ73/k9LE4VnLg==}
-    engines: {node: '>=6.0.0'}
-    dev: true
-
-  /@jridgewell/set-array/1.1.1:
-    resolution: {integrity: 
sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==}
-    engines: {node: '>=6.0.0'}
-    dev: true
-
-  /@jridgewell/sourcemap-codec/1.4.10:
-    resolution: {integrity: 
sha512-Ht8wIW5v165atIX1p+JvKR5ONzUyF4Ac8DZIQ5kZs9zrb6M8SJNXpx1zn04rn65VjBMygRoMXcyYwNK0fT7bEg==}
+      '@jest/types': 27.5.1
+      '@types/node': 18.8.5
+      chalk: 4.1.2
+      jest-message-util: 27.5.1
+      jest-util: 27.5.1
+      slash: 3.0.0
     dev: true
 
-  /@jridgewell/trace-mapping/0.3.13:
-    resolution: {integrity: 
sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==}
+  /@jest/console/28.1.3:
+    resolution: {integrity: 
sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==}
+    engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
     dependencies:
-      '@jridgewell/resolve-uri': 3.0.4
-      '@jridgewell/sourcemap-codec': 1.4.10
+      '@jest/types': 28.1.3
+      '@types/node': 18.8.5
+      chalk: 4.1.2
+      jest-message-util: 28.1.3
+      jest-util: 28.1.3
+      slash: 3.0.0
     dev: true
 
-  /@jridgewell/trace-mapping/0.3.4:
-    resolution: {integrity: 
sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==}
+  /@jest/core/26.6.3:
+    resolution: {integrity: 
sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==}
+    engines: {node: '>= 10.14.2'}
     dependencies:
-      '@jridgewell/resolve-uri': 3.0.4
-      '@jridgewell/sourcemap-codec': 1.4.10
+      '@jest/console': 26.6.2
+      '@jest/reporters': 26.6.2
+      '@jest/test-result': 26.6.2
+      '@jest/transform': 26.6.2
+      '@jest/types': 26.6.2
+      '@types/node': 18.8.5
+      ansi-escapes: 4.3.2
+      chalk: 4.1.2
+      exit: 0.1.2
+      graceful-fs: 4.2.10
+      jest-changed-files: 26.6.2
+      jest-config: 26.6.3
+      jest-haste-map: 26.6.2
+      jest-message-util: 26.6.2
+      jest-regex-util: 26.0.0
+      jest-resolve: 26.6.2
+      jest-resolve-dependencies: 26.6.3
+      jest-runner: 26.6.3
+      jest-runtime: 26.6.3
+      jest-snapshot: 26.6.2
+      jest-util: 26.6.2
+      jest-validate: 26.6.2
+      jest-watcher: 26.6.2
+      micromatch: 4.0.5
+      p-each-series: 2.2.0
+      rimraf: 3.0.2
+      slash: 3.0.0
+      strip-ansi: 6.0.1
+    transitivePeerDependencies:
+      - bufferutil
+      - canvas
+      - supports-color
+      - ts-node
+      - utf-8-validate
     dev: true
 
-  /@linaria/babel-preset/3.0.0-beta.15_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-oJIyUn2SCIH4vW1vBxOsN2BTU6Y0mq4ywkqxwQ1py4HgtEnYlvpq4Ca0ba7vXvMWk1pMCgd/V+VpMjbr19uXgQ==}
+  /@jest/core/27.5.1:
+    resolution: {integrity: 
sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     peerDependencies:
-      '@babel/core': '>=7'
+      node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
+    peerDependenciesMeta:
+      node-notifier:
+        optional: true
     dependencies:
-      '@babel/core': 7.13.16
-      '@babel/generator': 7.17.0
-      '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.13.16
-      '@babel/template': 7.16.7
-      '@linaria/core': 3.0.0-beta.15
-      '@linaria/logger': 3.0.0-beta.15
-      '@linaria/utils': 3.0.0-beta.15
-      cosmiconfig: 5.2.1
-      source-map: 0.7.3
-      stylis: 3.5.4
+      '@jest/console': 27.5.1
+      '@jest/reporters': 27.5.1
+      '@jest/test-result': 27.5.1
+      '@jest/transform': 27.5.1
+      '@jest/types': 27.5.1
+      '@types/node': 18.8.5
+      ansi-escapes: 4.3.2
+      chalk: 4.1.2
+      emittery: 0.8.1
+      exit: 0.1.2
+      graceful-fs: 4.2.10
+      jest-changed-files: 27.5.1
+      jest-config: 27.5.1
+      jest-haste-map: 27.5.1
+      jest-message-util: 27.5.1
+      jest-regex-util: 27.5.1
+      jest-resolve: 27.5.1
+      jest-resolve-dependencies: 27.5.1
+      jest-runner: 27.5.1
+      jest-runtime: 27.5.1
+      jest-snapshot: 27.5.1
+      jest-util: 27.5.1
+      jest-validate: 27.5.1
+      jest-watcher: 27.5.1
+      micromatch: 4.0.5
+      rimraf: 3.0.2
+      slash: 3.0.0
+      strip-ansi: 6.0.1
     transitivePeerDependencies:
+      - bufferutil
+      - canvas
       - supports-color
+      - ts-node
+      - utf-8-validate
     dev: true
 
-  /@linaria/babel-preset/3.0.0-beta.4_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-Bjsk4VZUQXK3u04MuLlyP/+/tDd7bWeLXYCOnq4US9H2QFRdka97fm6hH34SRinoHm9fSPCHrj9d+KtY8ge2wg==}
-    peerDependencies:
-      '@babel/core': '>=7'
+  /@jest/environment/26.6.2:
+    resolution: {integrity: 
sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==}
+    engines: {node: '>= 10.14.2'}
     dependencies:
-      '@babel/core': 7.13.16
-      '@babel/generator': 7.15.0
-      '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.13.16
-      '@babel/template': 7.14.5
-      '@linaria/core': 3.0.0-beta.4
-      '@linaria/logger': 3.0.0-beta.3
-      cosmiconfig: 5.2.1
-      source-map: 0.6.1
-      stylis: 3.5.4
-    transitivePeerDependencies:
-      - supports-color
+      '@jest/fake-timers': 26.6.2
+      '@jest/types': 26.6.2
+      '@types/node': 18.8.5
+      jest-mock: 26.6.2
     dev: true
 
-  /@linaria/babel-preset/3.0.0-beta.7_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-NE5f//T9ywXZA+W+Pw1YjWKdzskUpaV7GVkxXhkxLM2la1+S4xOoZR1rzW77bR1C9GFFwzZTeb8XP85whb2ZqQ==}
-    peerDependencies:
-      '@babel/core': '>=7'
+  /@jest/environment/27.5.1:
+    resolution: {integrity: 
sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dependencies:
-      '@babel/core': 7.13.16
-      '@babel/generator': 7.15.0
-      '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.13.16
-      '@babel/template': 7.14.5
-      '@linaria/core': 3.0.0-beta.4
-      '@linaria/logger': 3.0.0-beta.3
-      cosmiconfig: 5.2.1
-      source-map: 0.7.3
-      stylis: 3.5.4
-    transitivePeerDependencies:
-      - supports-color
+      '@jest/fake-timers': 27.5.1
+      '@jest/types': 27.5.1
+      '@types/node': 18.8.5
+      jest-mock: 27.5.1
     dev: true
 
-  /@linaria/core/3.0.0-beta.15:
-    resolution: {integrity: 
sha512-9sqPCcWIlA1zTck45uNGqrjtnWj5HGa7Lxbaw1ZsCcm6K6WcMVyOqW3OQkMBHuf3OzC50Mzb8z7d7d6Rpg8uFw==}
+  /@jest/fake-timers/26.6.2:
+    resolution: {integrity: 
sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==}
+    engines: {node: '>= 10.14.2'}
     dependencies:
-      '@linaria/utils': 3.0.0-beta.15
+      '@jest/types': 26.6.2
+      '@sinonjs/fake-timers': 6.0.1
+      '@types/node': 18.8.5
+      jest-message-util: 26.6.2
+      jest-mock: 26.6.2
+      jest-util: 26.6.2
     dev: true
 
-  /@linaria/core/3.0.0-beta.4:
-    resolution: {integrity: 
sha512-NzxeMDxRt57nR6tLFZ8xIstp5ld9JQPIyp9+TKtQZhoX3oJuUru+S4vXPr1Gach6VaqKKKT5T6fmJgJl9MMprw==}
+  /@jest/fake-timers/27.5.1:
+    resolution: {integrity: 
sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    dependencies:
+      '@jest/types': 27.5.1
+      '@sinonjs/fake-timers': 8.1.0
+      '@types/node': 18.8.5
+      jest-message-util: 27.5.1
+      jest-mock: 27.5.1
+      jest-util: 27.5.1
     dev: true
 
-  /@linaria/esbuild/3.0.0-beta.15_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-fhTLGMRBN2wCmApCzhC/hv+qGcJkmB/yaZCM3Ijj4mR6VgYbZG71HEUBrOMM70/mHzSzDR1C5wb7NRtG0K1Z3g==}
-    peerDependencies:
-      '@babel/core': '>=7'
+  /@jest/globals/26.6.2:
+    resolution: {integrity: 
sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==}
+    engines: {node: '>= 10.14.2'}
     dependencies:
-      '@babel/core': 7.13.16
-      '@linaria/babel-preset': 3.0.0-beta.15_@babel+core@7.13.16
-      esbuild: 0.12.29
-    transitivePeerDependencies:
-      - supports-color
+      '@jest/environment': 26.6.2
+      '@jest/types': 26.6.2
+      expect: 26.6.2
     dev: true
 
-  /@linaria/logger/3.0.0-beta.15:
-    resolution: {integrity: 
sha512-tKytEEus47CZ4/7pbgRYD+Por4tH7/5Um2Quof6Qamd7Xj7brhmAPRRoZzYu4pht+S7V9oNL0X4IBSmNIOYRZw==}
+  /@jest/globals/27.5.1:
+    resolution: {integrity: 
sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dependencies:
-      debug: 4.3.3
-      picocolors: 1.0.0
-    transitivePeerDependencies:
-      - supports-color
+      '@jest/environment': 27.5.1
+      '@jest/types': 27.5.1
+      expect: 27.5.1
     dev: true
 
-  /@linaria/logger/3.0.0-beta.3:
-    resolution: {integrity: 
sha512-Z2k0RJuA4PffcZcwBN1By8FmcCvcFUe9GHc846B6hNP09zDVhHSFLKJN9NfXJCzJ/9PifOxSUKyOjLtpv3EhGA==}
+  /@jest/reporters/26.6.2:
+    resolution: {integrity: 
sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==}
+    engines: {node: '>= 10.14.2'}
     dependencies:
-      debug: 4.3.2
+      '@bcoe/v8-coverage': 0.2.3
+      '@jest/console': 26.6.2
+      '@jest/test-result': 26.6.2
+      '@jest/transform': 26.6.2
+      '@jest/types': 26.6.2
+      chalk: 4.1.2
+      collect-v8-coverage: 1.0.1
+      exit: 0.1.2
+      glob: 7.2.3
+      graceful-fs: 4.2.10
+      istanbul-lib-coverage: 3.2.0
+      istanbul-lib-instrument: 4.0.3
+      istanbul-lib-report: 3.0.0
+      istanbul-lib-source-maps: 4.0.1
+      istanbul-reports: 3.1.3
+      jest-haste-map: 26.6.2
+      jest-resolve: 26.6.2
+      jest-util: 26.6.2
+      jest-worker: 26.6.2
+      slash: 3.0.0
+      source-map: 0.6.1
+      string-length: 4.0.2
+      terminal-link: 2.1.1
+      v8-to-istanbul: 7.1.2
+    optionalDependencies:
+      node-notifier: 8.0.2
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@linaria/preeval/3.0.0-beta.15_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-621wPHry4L4YFRdMXE0wxVKsocFL2KC+RECSdc6Oy4MVtMMeTyps671pV27+kQldWIRvp1ZsdhknNMEug+rKdg==}
+  /@jest/reporters/27.5.1:
+    resolution: {integrity: 
sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     peerDependencies:
-      '@babel/core': '>=7'
+      node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
+    peerDependenciesMeta:
+      node-notifier:
+        optional: true
     dependencies:
-      '@babel/core': 7.13.16
-      '@linaria/babel-preset': 3.0.0-beta.15_@babel+core@7.13.16
+      '@bcoe/v8-coverage': 0.2.3
+      '@jest/console': 27.5.1
+      '@jest/test-result': 27.5.1
+      '@jest/transform': 27.5.1
+      '@jest/types': 27.5.1
+      '@types/node': 18.8.5
+      chalk: 4.1.2
+      collect-v8-coverage: 1.0.1
+      exit: 0.1.2
+      glob: 7.2.3
+      graceful-fs: 4.2.10
+      istanbul-lib-coverage: 3.2.0
+      istanbul-lib-instrument: 5.2.1
+      istanbul-lib-report: 3.0.0
+      istanbul-lib-source-maps: 4.0.1
+      istanbul-reports: 3.1.3
+      jest-haste-map: 27.5.1
+      jest-resolve: 27.5.1
+      jest-util: 27.5.1
+      jest-worker: 27.5.1
+      slash: 3.0.0
+      source-map: 0.6.1
+      string-length: 4.0.2
+      terminal-link: 2.1.1
+      v8-to-istanbul: 8.1.1
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@linaria/react/3.0.0-beta.4:
-    resolution: {integrity: 
sha512-RSlFO3W+77PCtFnDFKVdITLUdBude+zICtumticDU76l5Xc5i0lEUXPDvYjD7s9+uk70K4GSNvgh7bqhkGgxKA==}
-    peerDependencies:
-      react: '>=16'
+  /@jest/schemas/28.1.3:
+    resolution: {integrity: 
sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==}
+    engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
     dependencies:
-      '@emotion/is-prop-valid': 0.8.8
-      '@linaria/core': 3.0.0-beta.4
+      '@sinclair/typebox': 0.24.50
     dev: true
 
-  /@linaria/shaker/3.0.0-beta.15_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-+PZRf8hM7fO4RiNpVVYUhIXQPPKYxowXYMaiILq/9zGcy2tQ6onqsKaQ71SCXvVrL+gVo6A/R13njOCJRZRTew==}
-    peerDependencies:
-      '@babel/core': '>=7'
+  /@jest/source-map/26.6.2:
+    resolution: {integrity: 
sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==}
+    engines: {node: '>= 10.14.2'}
     dependencies:
-      '@babel/core': 7.13.16
-      '@babel/generator': 7.17.0
-      '@babel/plugin-transform-runtime': 7.17.0_@babel+core@7.13.16
-      '@babel/plugin-transform-template-literals': 7.16.7_@babel+core@7.13.16
-      '@babel/preset-env': 7.16.11_@babel+core@7.13.16
-      '@linaria/babel-preset': 3.0.0-beta.15_@babel+core@7.13.16
-      '@linaria/logger': 3.0.0-beta.15
-      '@linaria/preeval': 3.0.0-beta.15_@babel+core@7.13.16
-      babel-plugin-transform-react-remove-prop-types: 0.4.24
-      ts-invariant: 0.9.4
-    transitivePeerDependencies:
-      - supports-color
+      callsites: 3.1.0
+      graceful-fs: 4.2.10
+      source-map: 0.6.1
     dev: true
 
-  /@linaria/utils/3.0.0-beta.15:
-    resolution: {integrity: 
sha512-CF0T8ueWjHK8zJT0oqdAq8JgL9a40WCyE5/t6q8WPvC7xRdsrfyUKA7Z8qEsQse2LKESVWJ5cvkkn8J80B6c+A==}
+  /@jest/source-map/27.5.1:
+    resolution: {integrity: 
sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    dependencies:
+      callsites: 3.1.0
+      graceful-fs: 4.2.10
+      source-map: 0.6.1
     dev: true
 
-  /@linaria/webpack-loader/3.0.0-beta.4_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-v2Z4QgkBwddKwS/M0ISkLKQBPBNfoyw4AGCBFsjFO5ov/icNrmIy8BKUFCi/yqWu8mk/krmvzPyOBSp4DpFsIA==}
+  /@jest/test-result/26.6.2:
+    resolution: {integrity: 
sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==}
+    engines: {node: '>= 10.14.2'}
     dependencies:
-      '@linaria/webpack4-loader': 3.0.0-beta.7_@babel+core@7.13.16
-      '@linaria/webpack5-loader': 3.0.0-beta.7_@babel+core@7.13.16
+      '@jest/console': 26.6.2
+      '@jest/types': 26.6.2
+      '@types/istanbul-lib-coverage': 2.0.4
+      collect-v8-coverage: 1.0.1
+    dev: true
+
+  /@jest/test-result/27.5.1:
+    resolution: {integrity: 
sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    dependencies:
+      '@jest/console': 27.5.1
+      '@jest/types': 27.5.1
+      '@types/istanbul-lib-coverage': 2.0.4
+      collect-v8-coverage: 1.0.1
+    dev: true
+
+  /@jest/test-result/28.1.3:
+    resolution: {integrity: 
sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==}
+    engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
+    dependencies:
+      '@jest/console': 28.1.3
+      '@jest/types': 28.1.3
+      '@types/istanbul-lib-coverage': 2.0.4
+      collect-v8-coverage: 1.0.1
+    dev: true
+
+  /@jest/test-sequencer/26.6.3:
+    resolution: {integrity: 
sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==}
+    engines: {node: '>= 10.14.2'}
+    dependencies:
+      '@jest/test-result': 26.6.2
+      graceful-fs: 4.2.10
+      jest-haste-map: 26.6.2
+      jest-runner: 26.6.3
+      jest-runtime: 26.6.3
     transitivePeerDependencies:
-      - '@babel/core'
+      - bufferutil
+      - canvas
       - supports-color
-      - webpack
+      - ts-node
+      - utf-8-validate
     dev: true
 
-  /@linaria/webpack4-loader/3.0.0-beta.7_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-B2c5vr9b8igcILM/ZcxE9Vu0J2w7NS9xERTvGD7Kp4TdLnFRpALMTJgYqlk3Gxq4T7RlAEi1vu8kHx65mXqA6g==}
-    peerDependencies:
-      '@babel/core': '>=7'
+  /@jest/test-sequencer/27.5.1:
+    resolution: {integrity: 
sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dependencies:
-      '@babel/core': 7.13.16
-      '@linaria/babel-preset': 3.0.0-beta.7_@babel+core@7.13.16
-      '@linaria/logger': 3.0.0-beta.3
-      cosmiconfig: 5.2.1
-      enhanced-resolve: 4.5.0
-      find-yarn-workspace-root: 1.2.1
-      loader-utils: 1.4.0
-      mkdirp: 0.5.5
-      normalize-path: 3.0.0
+      '@jest/test-result': 27.5.1
+      graceful-fs: 4.2.10
+      jest-haste-map: 27.5.1
+      jest-runtime: 27.5.1
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@linaria/webpack5-loader/3.0.0-beta.7_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-s2C44ml1fjDFjEJS1PFXjgCklOd3KWiG4Z3l+nUuCidncn9abnv18rDkiukUcKGwwAGJ3NhgfhU9SwXPIYFfMw==}
-    peerDependencies:
-      '@babel/core': '>=7'
-      webpack: '>=5'
+  /@jest/transform/26.6.2:
+    resolution: {integrity: 
sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==}
+    engines: {node: '>= 10.14.2'}
     dependencies:
-      '@babel/core': 7.13.16
-      '@linaria/babel-preset': 3.0.0-beta.7_@babel+core@7.13.16
-      '@linaria/logger': 3.0.0-beta.3
-      cosmiconfig: 5.2.1
-      enhanced-resolve: 5.8.2
-      find-yarn-workspace-root: 1.2.1
-      loader-utils: 2.0.0
-      mkdirp: 0.5.5
-      normalize-path: 3.0.0
+      '@babel/core': 7.19.6
+      '@jest/types': 26.6.2
+      babel-plugin-istanbul: 6.1.1
+      chalk: 4.1.2
+      convert-source-map: 1.8.0
+      fast-json-stable-stringify: 2.1.0
+      graceful-fs: 4.2.10
+      jest-haste-map: 26.6.2
+      jest-regex-util: 26.0.0
+      jest-util: 26.6.2
+      micromatch: 4.0.5
+      pirates: 4.0.5
+      slash: 3.0.0
+      source-map: 0.6.1
+      write-file-atomic: 3.0.3
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@nodelib/fs.scandir/2.1.5:
-    resolution: {integrity: 
sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
-    engines: {node: '>= 8'}
+  /@jest/transform/27.5.1:
+    resolution: {integrity: 
sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dependencies:
-      '@nodelib/fs.stat': 2.0.5
-      run-parallel: 1.2.0
+      '@babel/core': 7.19.6
+      '@jest/types': 27.5.1
+      babel-plugin-istanbul: 6.1.1
+      chalk: 4.1.2
+      convert-source-map: 1.8.0
+      fast-json-stable-stringify: 2.1.0
+      graceful-fs: 4.2.10
+      jest-haste-map: 27.5.1
+      jest-regex-util: 27.5.1
+      jest-util: 27.5.1
+      micromatch: 4.0.5
+      pirates: 4.0.5
+      slash: 3.0.0
+      source-map: 0.6.1
+      write-file-atomic: 3.0.3
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /@nodelib/fs.stat/2.0.5:
-    resolution: {integrity: 
sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
-    engines: {node: '>= 8'}
+  /@jest/types/26.6.2:
+    resolution: {integrity: 
sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==}
+    engines: {node: '>= 10.14.2'}
+    dependencies:
+      '@types/istanbul-lib-coverage': 2.0.4
+      '@types/istanbul-reports': 3.0.1
+      '@types/node': 18.8.5
+      '@types/yargs': 15.0.14
+      chalk: 4.1.2
     dev: true
 
-  /@nodelib/fs.walk/1.2.8:
-    resolution: {integrity: 
sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
-    engines: {node: '>= 8'}
+  /@jest/types/27.5.1:
+    resolution: {integrity: 
sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dependencies:
-      '@nodelib/fs.scandir': 2.1.5
-      fastq: 1.13.0
+      '@types/istanbul-lib-coverage': 2.0.4
+      '@types/istanbul-reports': 3.0.1
+      '@types/node': 18.8.5
+      '@types/yargs': 16.0.4
+      chalk: 4.1.2
     dev: true
 
-  /@npmcli/fs/1.1.0:
-    resolution: {integrity: 
sha512-VhP1qZLXcrXRIaPoqb4YA55JQxLNF3jNR4T55IdOJa3+IFJKNYHtPvtXx8slmeMavj37vCzCfrqQM1vWLsYKLA==}
-    engines: {node: ^12.13.0 || ^14.15.0 || >=16}
+  /@jest/types/28.1.3:
+    resolution: {integrity: 
sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==}
+    engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
     dependencies:
-      '@gar/promisify': 1.1.2
-      semver: 7.3.5
+      '@jest/schemas': 28.1.3
+      '@types/istanbul-lib-coverage': 2.0.4
+      '@types/istanbul-reports': 3.0.1
+      '@types/node': 18.8.5
+      '@types/yargs': 17.0.13
+      chalk: 4.1.2
     dev: true
 
-  /@npmcli/move-file/1.1.2:
-    resolution: {integrity: 
sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==}
-    engines: {node: '>=10'}
+  /@jridgewell/gen-mapping/0.3.1:
+    resolution: {integrity: 
sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==}
+    engines: {node: '>=6.0.0'}
     dependencies:
-      mkdirp: 1.0.4
-      rimraf: 3.0.2
-    dev: true
-
-  /@polka/url/1.0.0-next.21:
-    resolution: {integrity: 
sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==}
+      '@jridgewell/set-array': 1.1.1
+      '@jridgewell/sourcemap-codec': 1.4.10
+      '@jridgewell/trace-mapping': 0.3.13
     dev: true
 
-  /@preact/async-loader/3.0.1_preact@10.6.5:
-    resolution: {integrity: 
sha512-BoUN24hxEfAQYnWjliAmkZLuliv+ONQi7AWn+/+VOJHTIHmbFiXrvmSxITf7PDkKiK0a5xy4OErZtVVLlk96Tg==}
-    engines: {node: '>=8'}
-    peerDependencies:
-      preact: '>= 10.0.0'
+  /@jridgewell/gen-mapping/0.3.2:
+    resolution: {integrity: 
sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==}
+    engines: {node: '>=6.0.0'}
     dependencies:
-      kleur: 4.1.4
-      loader-utils: 2.0.2
-      preact: 10.6.5
+      '@jridgewell/set-array': 1.1.1
+      '@jridgewell/sourcemap-codec': 1.4.10
+      '@jridgewell/trace-mapping': 0.3.13
     dev: true
 
-  /@prefresh/babel-plugin/0.4.1:
-    resolution: {integrity: 
sha512-gj3ekiYtHlZNz0zFI1z6a9mcYX80Qacw84+2++7V1skvO7kQoV2ux56r8bJkTBbKMVxwAgaYrxxIdUCYlclE7Q==}
+  /@jridgewell/resolve-uri/3.0.4:
+    resolution: {integrity: 
sha512-cz8HFjOFfUBtvN+NXYSFMHYRdxZMaEl0XypVrhzxBgadKIXhIkRd8aMeHhmF56Sl7SuS8OnUpQ73/k9LE4VnLg==}
+    engines: {node: '>=6.0.0'}
     dev: true
 
-  /@prefresh/core/1.3.2_preact@10.6.5:
-    resolution: {integrity: 
sha512-Iv+uI698KDgWsrKpLvOgN3hmAMyvhVgn09mcnhZ98BUNdg/qrxE7tcUf5yFCImkgqED5/Dcn8G5hFy4IikEDvg==}
-    peerDependencies:
-      preact: ^10.0.0
-    dependencies:
-      preact: 10.6.5
+  /@jridgewell/set-array/1.1.1:
+    resolution: {integrity: 
sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==}
+    engines: {node: '>=6.0.0'}
     dev: true
 
-  /@prefresh/utils/1.1.1:
-    resolution: {integrity: 
sha512-MUhT5m2XNN5NsZl4GnpuvlzLo6VSTa/+wBfBd3fiWUvHGhv0GF9hnA1pd//v0uJaKwUnVRQ1hYElxCV7DtYsCQ==}
+  /@jridgewell/sourcemap-codec/1.4.10:
+    resolution: {integrity: 
sha512-Ht8wIW5v165atIX1p+JvKR5ONzUyF4Ac8DZIQ5kZs9zrb6M8SJNXpx1zn04rn65VjBMygRoMXcyYwNK0fT7bEg==}
     dev: true
 
-  /@prefresh/webpack/3.3.2_dveknyjmyxkzkf4ybureeu5fae:
-    resolution: {integrity: 
sha512-1cX0t5G7IXWO2164sl2O32G02BzDl6C4UUZWfDb0x1CQM1g3It9PSLWd+rIlHfSg4MEU9YHM8e6/OK8uavRJhA==}
-    peerDependencies:
-      '@prefresh/babel-plugin': ^0.4.0
-      preact: ^10.4.0
-      webpack: ^4.0.0 || ^5.0.0
+  /@jridgewell/trace-mapping/0.3.13:
+    resolution: {integrity: 
sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==}
     dependencies:
-      '@prefresh/babel-plugin': 0.4.1
-      '@prefresh/core': 1.3.2_preact@10.6.5
-      '@prefresh/utils': 1.1.1
-      preact: 10.6.5
-      webpack: 4.46.0
+      '@jridgewell/resolve-uri': 3.0.4
+      '@jridgewell/sourcemap-codec': 1.4.10
     dev: true
 
-  /@rollup/plugin-babel/5.3.0_lubkdqoa5gexe4rox23cswxwm4:
-    resolution: {integrity: 
sha512-9uIC8HZOnVLrLHxayq/PTzw+uS25E14KPUBh5ktF+18Mjo5yK0ToMMx6epY0uEgkjwJw0aBW4x2horYXh8juWw==}
-    engines: {node: '>= 10.0.0'}
+  /@linaria/babel-preset/3.0.0-beta.15_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-oJIyUn2SCIH4vW1vBxOsN2BTU6Y0mq4ywkqxwQ1py4HgtEnYlvpq4Ca0ba7vXvMWk1pMCgd/V+VpMjbr19uXgQ==}
     peerDependencies:
-      '@babel/core': ^7.0.0
-      '@types/babel__core': ^7.1.9
-      rollup: ^1.20.0||^2.0.0
-    peerDependenciesMeta:
-      '@types/babel__core':
-        optional: true
+      '@babel/core': '>=7'
     dependencies:
       '@babel/core': 7.17.2
-      '@babel/helper-module-imports': 7.16.7
-      '@rollup/pluginutils': 3.1.0_rollup@2.79.0
-      rollup: 2.79.0
+      '@babel/generator': 7.18.2
+      '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.17.2
+      '@babel/template': 7.16.7
+      '@linaria/core': 3.0.0-beta.15
+      '@linaria/logger': 3.0.0-beta.15
+      '@linaria/utils': 3.0.0-beta.15
+      cosmiconfig: 5.2.1
+      source-map: 0.7.3
+      stylis: 3.5.4
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /@rollup/plugin-commonjs/22.0.2_rollup@2.79.0:
-    resolution: {integrity: 
sha512-//NdP6iIwPbMTcazYsiBMbJW7gfmpHom33u1beiIoHDEM0Q9clvtQB1T0efvMqHeKsGohiHo97BCPCkBXdscwg==}
-    engines: {node: '>= 12.0.0'}
-    peerDependencies:
-      rollup: ^2.68.0
+  /@linaria/babel-preset/3.0.0-beta.23:
+    resolution: {integrity: 
sha512-NhxUZokEq12RLpDo4v/f59dB9A/1BbLgGLFotnrDzNBHfylm0qXSIIel68pZOXUB5lVdPJHqZWcT2zxbpGW6fA==}
+    engines: {node: ^12.16.0 || >=13.7.0}
     dependencies:
-      '@rollup/pluginutils': 3.1.0_rollup@2.79.0
-      commondir: 1.0.1
-      estree-walker: 2.0.2
-      glob: 7.2.3
-      is-reference: 1.2.1
-      magic-string: 0.25.9
-      resolve: 1.22.1
-      rollup: 2.79.0
+      '@babel/core': 7.19.6
+      '@babel/generator': 7.18.2
+      '@babel/plugin-proposal-export-namespace-from': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.19.6
+      '@babel/plugin-transform-modules-commonjs': 7.18.2_@babel+core@7.19.6
+      '@babel/template': 7.16.7
+      '@babel/traverse': 7.18.2
+      '@linaria/core': 3.0.0-beta.22
+      '@linaria/logger': 3.0.0-beta.20
+      '@linaria/utils': 3.0.0-beta.20
+      cosmiconfig: 5.2.1
+      find-up: 5.0.0
+      source-map: 0.7.3
+      stylis: 3.5.4
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /@rollup/plugin-json/4.1.0_rollup@2.79.0:
-    resolution: {integrity: 
sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==}
+  /@linaria/babel-preset/3.0.0-beta.4_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-Bjsk4VZUQXK3u04MuLlyP/+/tDd7bWeLXYCOnq4US9H2QFRdka97fm6hH34SRinoHm9fSPCHrj9d+KtY8ge2wg==}
     peerDependencies:
-      rollup: ^1.20.0 || ^2.0.0
+      '@babel/core': '>=7'
     dependencies:
-      '@rollup/pluginutils': 3.1.0_rollup@2.79.0
-      rollup: 2.79.0
+      '@babel/core': 7.13.16
+      '@babel/generator': 7.15.0
+      '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.13.16
+      '@babel/template': 7.14.5
+      '@linaria/core': 3.0.0-beta.22
+      '@linaria/logger': 3.0.0-beta.3
+      cosmiconfig: 5.2.1
+      source-map: 0.6.1
+      stylis: 3.5.4
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /@rollup/plugin-node-resolve/11.2.1_rollup@2.79.0:
-    resolution: {integrity: 
sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==}
-    engines: {node: '>= 10.0.0'}
-    peerDependencies:
-      rollup: ^1.20.0||^2.0.0
+  /@linaria/core/3.0.0-beta.15:
+    resolution: {integrity: 
sha512-9sqPCcWIlA1zTck45uNGqrjtnWj5HGa7Lxbaw1ZsCcm6K6WcMVyOqW3OQkMBHuf3OzC50Mzb8z7d7d6Rpg8uFw==}
     dependencies:
-      '@rollup/pluginutils': 3.1.0_rollup@2.79.0
-      '@types/resolve': 1.17.1
-      builtin-modules: 3.3.0
-      deepmerge: 4.2.2
-      is-module: 1.0.0
-      resolve: 1.22.1
-      rollup: 2.79.0
+      '@linaria/utils': 3.0.0-beta.15
     dev: true
 
-  /@rollup/plugin-node-resolve/13.3.0_rollup@2.79.0:
-    resolution: {integrity: 
sha512-Lus8rbUo1eEcnS4yTFKLZrVumLPY+YayBdWXgFSHYhTT2iJbMhoaaBL3xl5NCdeRytErGr8tZ0L71BMRmnlwSw==}
-    engines: {node: '>= 10.0.0'}
-    peerDependencies:
-      rollup: ^2.42.0
+  /@linaria/core/3.0.0-beta.22:
+    resolution: {integrity: 
sha512-BPSecW8QmhQ0y+5cWXEja+MTmLsuo0T1PjqRlSWsmDgjJFFObqCnPEgbR1KNtQb3Msmx1/9q3dYKpA5Zk3g8KQ==}
+    engines: {node: ^12.16.0 || >=13.7.0}
     dependencies:
-      '@rollup/pluginutils': 3.1.0_rollup@2.79.0
-      '@types/resolve': 1.17.1
-      deepmerge: 4.2.2
-      is-builtin-module: 3.2.0
-      is-module: 1.0.0
-      resolve: 1.22.1
-      rollup: 2.79.0
+      '@linaria/logger': 3.0.0-beta.20
+      '@linaria/utils': 3.0.0-beta.20
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /@rollup/plugin-replace/2.4.2_rollup@2.79.0:
-    resolution: {integrity: 
sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==}
-    peerDependencies:
-      rollup: ^1.20.0 || ^2.0.0
-    dependencies:
-      '@rollup/pluginutils': 3.1.0_rollup@2.79.0
-      magic-string: 0.25.9
-      rollup: 2.79.0
+  /@linaria/core/3.0.0-beta.4:
+    resolution: {integrity: 
sha512-NzxeMDxRt57nR6tLFZ8xIstp5ld9JQPIyp9+TKtQZhoX3oJuUru+S4vXPr1Gach6VaqKKKT5T6fmJgJl9MMprw==}
     dev: true
 
-  /@rollup/plugin-replace/4.0.0_rollup@2.79.0:
-    resolution: {integrity: 
sha512-+rumQFiaNac9y64OHtkHGmdjm7us9bo1PlbgQfdihQtuNxzjpaB064HbRnewUOggLQxVCCyINfStkgmBeQpv1g==}
+  /@linaria/esbuild/3.0.0-beta.15_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-fhTLGMRBN2wCmApCzhC/hv+qGcJkmB/yaZCM3Ijj4mR6VgYbZG71HEUBrOMM70/mHzSzDR1C5wb7NRtG0K1Z3g==}
     peerDependencies:
-      rollup: ^1.20.0 || ^2.0.0
+      '@babel/core': '>=7'
     dependencies:
-      '@rollup/pluginutils': 3.1.0_rollup@2.79.0
-      magic-string: 0.25.9
-      rollup: 2.79.0
+      '@babel/core': 7.13.16
+      '@linaria/babel-preset': 3.0.0-beta.23
+      esbuild: 0.12.29
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /@rollup/pluginutils/3.1.0_rollup@2.79.0:
-    resolution: {integrity: 
sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==}
-    engines: {node: '>= 8.0.0'}
-    peerDependencies:
-      rollup: ^1.20.0||^2.0.0
+  /@linaria/logger/3.0.0-beta.15:
+    resolution: {integrity: 
sha512-tKytEEus47CZ4/7pbgRYD+Por4tH7/5Um2Quof6Qamd7Xj7brhmAPRRoZzYu4pht+S7V9oNL0X4IBSmNIOYRZw==}
     dependencies:
-      '@types/estree': 0.0.39
-      estree-walker: 1.0.1
-      picomatch: 2.3.1
-      rollup: 2.79.0
+      debug: 4.3.4
+      picocolors: 1.0.0
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /@sindresorhus/is/0.14.0:
-    resolution: {integrity: 
sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==}
-    engines: {node: '>=6'}
+  /@linaria/logger/3.0.0-beta.20:
+    resolution: {integrity: 
sha512-wCxWnldCHf7HXdLG3QtbKyBur+z5V1qZTouSEvcVYDfd4aSRPOi/jLdwsZlsUq2PFGpA3jW6JnreZJ/vxuEl7g==}
+    engines: {node: ^12.16.0 || >=13.7.0}
+    dependencies:
+      debug: 4.3.4
+      picocolors: 1.0.0
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /@surma/rollup-plugin-off-main-thread/2.2.3:
-    resolution: {integrity: 
sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==}
+  /@linaria/logger/3.0.0-beta.3:
+    resolution: {integrity: 
sha512-Z2k0RJuA4PffcZcwBN1By8FmcCvcFUe9GHc846B6hNP09zDVhHSFLKJN9NfXJCzJ/9PifOxSUKyOjLtpv3EhGA==}
     dependencies:
-      ejs: 3.1.6
-      json5: 2.2.0
-      magic-string: 0.25.9
-      string.prototype.matchall: 4.0.6
+      debug: 4.3.4
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /@szmarczak/http-timer/1.1.2:
-    resolution: {integrity: 
sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==}
-    engines: {node: '>=6'}
+  /@linaria/preeval/3.0.0-beta.15_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-621wPHry4L4YFRdMXE0wxVKsocFL2KC+RECSdc6Oy4MVtMMeTyps671pV27+kQldWIRvp1ZsdhknNMEug+rKdg==}
+    peerDependencies:
+      '@babel/core': '>=7'
     dependencies:
-      defer-to-connect: 1.1.3
+      '@babel/core': 7.13.16
+      '@linaria/babel-preset': 3.0.0-beta.23
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /@testing-library/dom/7.31.2:
-    resolution: {integrity: 
sha512-3UqjCpey6HiTZT92vODYLPxTBWlM8ZOOjr3LX5F37/VRipW2M1kX6I/Cm4VXzteZqfGfagg8yXywpcOgQBlNsQ==}
-    engines: {node: '>=10'}
+  /@linaria/preeval/3.0.0-beta.15_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-621wPHry4L4YFRdMXE0wxVKsocFL2KC+RECSdc6Oy4MVtMMeTyps671pV27+kQldWIRvp1ZsdhknNMEug+rKdg==}
+    peerDependencies:
+      '@babel/core': '>=7'
     dependencies:
-      '@babel/code-frame': 7.16.7
-      '@babel/runtime': 7.16.3
-      '@types/aria-query': 4.2.2
-      aria-query: 4.2.2
-      chalk: 4.1.2
-      dom-accessibility-api: 0.5.7
-      lz-string: 1.4.4
-      pretty-format: 26.6.2
+      '@babel/core': 7.17.2
+      '@linaria/babel-preset': 3.0.0-beta.23
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /@testing-library/preact-hooks/1.1.0_vfcmu6iy7nffpurikpgxo6gwxi:
-    resolution: {integrity: 
sha512-+JIor+NsOHkK3oIrwMDGKGHXTN0JJi462dBJlj4FNbGaDPTlctE6eu2ranWQirh7/FJMkWfzQCP+tk7jmY8ZrQ==}
+  /@linaria/react/3.0.0-beta.22:
+    resolution: {integrity: 
sha512-14rnb/zkzhFhJM3hbBOzLLS0bu01mOg23Rv2nGQUt5CWd+HOhksmqzqBtC/ijeVlY2hRI0rJJcng9r07LGGAPA==}
+    engines: {node: ^12.16.0 || >=13.7.0}
     peerDependencies:
-      '@testing-library/preact': ^2.0.0
-      preact: ^10.4.8
+      react: '>=16'
     dependencies:
-      '@testing-library/preact': 2.0.1_preact@10.6.5
-      preact: 10.6.5
+      '@emotion/is-prop-valid': 0.8.8
+      '@linaria/core': 3.0.0-beta.22
+      ts-invariant: 0.10.3
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /@testing-library/preact/2.0.1_preact@10.6.5:
-    resolution: {integrity: 
sha512-79kwVOY+3caoLgaPbiPzikjgY0Aya7Fc7TvGtR1upCnz2wrtmPDnN2t9vO7I7vDP2zoA+feSwOH5Q0BFErhaaQ==}
-    engines: {node: '>= 10'}
+  /@linaria/react/3.0.0-beta.4:
+    resolution: {integrity: 
sha512-RSlFO3W+77PCtFnDFKVdITLUdBude+zICtumticDU76l5Xc5i0lEUXPDvYjD7s9+uk70K4GSNvgh7bqhkGgxKA==}
     peerDependencies:
-      preact: '>=10 || ^10.0.0-alpha.0 || ^10.0.0-beta.0'
+      react: '>=16'
     dependencies:
-      '@testing-library/dom': 7.31.2
-      preact: 10.6.5
-    dev: true
-
-  /@trysound/sax/0.2.0:
-    resolution: {integrity: 
sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
-    engines: {node: '>=10.13.0'}
+      '@emotion/is-prop-valid': 0.8.8
+      '@linaria/core': 3.0.0-beta.22
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /@types/aria-query/4.2.2:
-    resolution: {integrity: 
sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==}
+  /@linaria/rollup/3.0.0-beta.23:
+    resolution: {integrity: 
sha512-qi6lOsMHN3wYfBy3/4kz9bJcK1cPVTThWyfVh8OJxFOdqXi/C8ogT69VobsNVqrng/0REAXYc082m1ovxYGBgA==}
+    engines: {node: ^12.16.0 || >=13.7.0}
+    dependencies:
+      '@linaria/babel-preset': 3.0.0-beta.23
+      '@rollup/pluginutils': 4.2.1
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /@types/body-parser/1.19.2:
-    resolution: {integrity: 
sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==}
+  /@linaria/shaker/3.0.0-beta.15_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-+PZRf8hM7fO4RiNpVVYUhIXQPPKYxowXYMaiILq/9zGcy2tQ6onqsKaQ71SCXvVrL+gVo6A/R13njOCJRZRTew==}
+    peerDependencies:
+      '@babel/core': '>=7'
     dependencies:
-      '@types/connect': 3.4.35
-      '@types/node': 18.8.5
+      '@babel/core': 7.13.16
+      '@babel/generator': 7.17.0
+      '@babel/plugin-transform-runtime': 7.17.0_@babel+core@7.13.16
+      '@babel/plugin-transform-template-literals': 7.16.7_@babel+core@7.13.16
+      '@babel/preset-env': 7.16.11_@babel+core@7.13.16
+      '@linaria/babel-preset': 3.0.0-beta.23
+      '@linaria/logger': 3.0.0-beta.15
+      '@linaria/preeval': 3.0.0-beta.15_@babel+core@7.13.16
+      babel-plugin-transform-react-remove-prop-types: 0.4.24
+      ts-invariant: 0.9.4
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /@types/bonjour/3.5.10:
-    resolution: {integrity: 
sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==}
+  /@linaria/shaker/3.0.0-beta.15_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-+PZRf8hM7fO4RiNpVVYUhIXQPPKYxowXYMaiILq/9zGcy2tQ6onqsKaQ71SCXvVrL+gVo6A/R13njOCJRZRTew==}
+    peerDependencies:
+      '@babel/core': '>=7'
     dependencies:
-      '@types/node': 18.8.5
+      '@babel/core': 7.17.2
+      '@babel/generator': 7.17.0
+      '@babel/plugin-transform-runtime': 7.17.0_@babel+core@7.17.2
+      '@babel/plugin-transform-template-literals': 7.16.7_@babel+core@7.17.2
+      '@babel/preset-env': 7.16.11_@babel+core@7.17.2
+      '@linaria/babel-preset': 3.0.0-beta.23
+      '@linaria/logger': 3.0.0-beta.15
+      '@linaria/preeval': 3.0.0-beta.15_@babel+core@7.17.2
+      babel-plugin-transform-react-remove-prop-types: 0.4.24
+      ts-invariant: 0.9.4
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /@types/chai/4.3.0:
-    resolution: {integrity: 
sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw==}
-
-  /@types/chrome/0.0.197:
-    resolution: {integrity: 
sha512-m1NfS5bOjaypyqQfaX6CxmJodZVcvj5+Mt/K94EBHkflYjPNmXHAzbxfifdLMa0YM3PDyOxohoTS5ug/e6p5jA==}
-    dependencies:
-      '@types/filesystem': 0.0.32
-      '@types/har-format': 1.2.9
+  /@linaria/utils/3.0.0-beta.15:
+    resolution: {integrity: 
sha512-CF0T8ueWjHK8zJT0oqdAq8JgL9a40WCyE5/t6q8WPvC7xRdsrfyUKA7Z8qEsQse2LKESVWJ5cvkkn8J80B6c+A==}
     dev: true
 
-  /@types/connect-history-api-fallback/1.3.5:
-    resolution: {integrity: 
sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==}
-    dependencies:
-      '@types/express-serve-static-core': 4.17.28
-      '@types/node': 18.8.5
+  /@linaria/utils/3.0.0-beta.20:
+    resolution: {integrity: 
sha512-SKRC9dBApzu0kTksVtGZ7eJz1vMu7xew/JEAjQj6XTQDblzWpTPyKQHBOGXNkqXjIB8PwAqWfvKzKapzaOwQaQ==}
+    engines: {node: ^12.16.0 || >=13.7.0}
     dev: true
 
-  /@types/connect/3.4.35:
-    resolution: {integrity: 
sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==}
+  /@linaria/webpack-loader/3.0.0-beta.23:
+    resolution: {integrity: 
sha512-DC6RhGyIw/EHwwKnywty8PLpDfDVD/hdiWxECw0dnuXe6t8ye5OoPhc14gDx42PjEFrVYf6IJprPlXnX0Usp2Q==}
+    engines: {node: ^12.16.0 || >=13.7.0}
     dependencies:
-      '@types/node': 18.8.5
+      '@linaria/webpack4-loader': 3.0.0-beta.23
+      '@linaria/webpack5-loader': 3.0.0-beta.23
+    transitivePeerDependencies:
+      - supports-color
+      - webpack
     dev: true
 
-  /@types/estree/0.0.39:
-    resolution: {integrity: 
sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==}
+  /@linaria/webpack-loader/3.0.0-beta.4_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-v2Z4QgkBwddKwS/M0ISkLKQBPBNfoyw4AGCBFsjFO5ov/icNrmIy8BKUFCi/yqWu8mk/krmvzPyOBSp4DpFsIA==}
+    dependencies:
+      '@linaria/webpack4-loader': 3.0.0-beta.7_@babel+core@7.13.16
+      '@linaria/webpack5-loader': 3.0.0-beta.7_@babel+core@7.13.16
+    transitivePeerDependencies:
+      - '@babel/core'
+      - supports-color
+      - webpack
     dev: true
 
-  /@types/estree/1.0.0:
-    resolution: {integrity: 
sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==}
+  /@linaria/webpack4-loader/3.0.0-beta.23:
+    resolution: {integrity: 
sha512-I1pwrRKpGCARWbPwTFqOKLrkyxrZ+huYC3WH4pMllfoY+fv3O2dmDH6vKrZ582mQ5Uo/H3FmHBt8CLaMBv3pmg==}
+    engines: {node: ^12.16.0 || >=13.7.0}
+    peerDependencies:
+      webpack: '>=4.0.0 <5.0.0'
+    dependencies:
+      '@linaria/babel-preset': 3.0.0-beta.23
+      '@linaria/logger': 3.0.0-beta.20
+      enhanced-resolve: 4.5.0
+      loader-utils: 1.4.0
+      mkdirp: 0.5.5
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /@types/express-serve-static-core/4.17.28:
-    resolution: {integrity: 
sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==}
+  /@linaria/webpack4-loader/3.0.0-beta.7_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-B2c5vr9b8igcILM/ZcxE9Vu0J2w7NS9xERTvGD7Kp4TdLnFRpALMTJgYqlk3Gxq4T7RlAEi1vu8kHx65mXqA6g==}
+    peerDependencies:
+      '@babel/core': '>=7'
     dependencies:
-      '@types/node': 18.8.5
-      '@types/qs': 6.9.7
-      '@types/range-parser': 1.2.4
+      '@babel/core': 7.13.16
+      '@linaria/babel-preset': 3.0.0-beta.23
+      '@linaria/logger': 3.0.0-beta.20
+      cosmiconfig: 5.2.1
+      enhanced-resolve: 4.5.0
+      find-yarn-workspace-root: 1.2.1
+      loader-utils: 1.4.0
+      mkdirp: 0.5.5
+      normalize-path: 3.0.0
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /@types/express/4.17.13:
-    resolution: {integrity: 
sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==}
+  /@linaria/webpack5-loader/3.0.0-beta.23:
+    resolution: {integrity: 
sha512-yIjhnDT1otwfx6JAA9HNfDzim7N93z9++8apzXE57GXg5wRO2hlajruatclpUDcMOsodS9p2+mMXd8GGR8CGCA==}
+    engines: {node: ^12.16.0 || >=13.7.0}
+    peerDependencies:
+      webpack: ^5.0.0
     dependencies:
-      '@types/body-parser': 1.19.2
-      '@types/express-serve-static-core': 4.17.28
-      '@types/qs': 6.9.7
-      '@types/serve-static': 1.13.10
+      '@linaria/babel-preset': 3.0.0-beta.23
+      '@linaria/logger': 3.0.0-beta.20
+      enhanced-resolve: 5.8.2
+      mkdirp: 0.5.5
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /@types/filesystem/0.0.32:
-    resolution: {integrity: 
sha512-Yuf4jR5YYMR2DVgwuCiP11s0xuVRyPKmz8vo6HBY3CGdeMj8af93CFZX+T82+VD1+UqHOxTq31lO7MI7lepBtQ==}
+  /@linaria/webpack5-loader/3.0.0-beta.7_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-s2C44ml1fjDFjEJS1PFXjgCklOd3KWiG4Z3l+nUuCidncn9abnv18rDkiukUcKGwwAGJ3NhgfhU9SwXPIYFfMw==}
+    peerDependencies:
+      '@babel/core': '>=7'
+      webpack: '>=5'
     dependencies:
-      '@types/filewriter': 0.0.29
+      '@babel/core': 7.13.16
+      '@linaria/babel-preset': 3.0.0-beta.23
+      '@linaria/logger': 3.0.0-beta.20
+      cosmiconfig: 5.2.1
+      enhanced-resolve: 5.8.2
+      find-yarn-workspace-root: 1.2.1
+      loader-utils: 2.0.2
+      mkdirp: 0.5.5
+      normalize-path: 3.0.0
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /@types/filewriter/0.0.29:
-    resolution: {integrity: 
sha512-BsPXH/irW0ht0Ji6iw/jJaK8Lj3FJemon2gvEqHKpCdDCeemHa+rI3WBGq5z7cDMZgoLjY40oninGxqk+8NzNQ==}
+  /@mdn/browser-compat-data/3.3.14:
+    resolution: {integrity: 
sha512-n2RC9d6XatVbWFdHLimzzUJxJ1KY8LdjqrW6YvGPiRmsHkhOUx74/Ct10x5Yo7bC/Jvqx7cDEW8IMPv/+vwEzA==}
     dev: true
 
-  /@types/har-format/1.2.9:
-    resolution: {integrity: 
sha512-rffW6MhQ9yoa75bdNi+rjZBAvu2HhehWJXlhuWXnWdENeuKe82wUgAwxYOb7KRKKmxYN+D/iRKd2NDQMLqlUmg==}
+  /@mdn/browser-compat-data/4.2.1:
+    resolution: {integrity: 
sha512-EWUguj2kd7ldmrF9F+vI5hUOralPd+sdsUnYbRy33vZTuZkduC1shE9TtEMEjAQwyfyMb4ole5KtjF8MsnQOlA==}
     dev: true
 
-  /@types/history/4.7.9:
-    resolution: {integrity: 
sha512-MUc6zSmU3tEVnkQ78q0peeEjKWPUADMlC/t++2bI8WnAG2tvYRPIgHG8lWkXwqc8MsUF6Z2MOf+Mh5sazOmhiQ==}
+  /@mdx-js/loader/1.6.22:
+    resolution: {integrity: 
sha512-9CjGwy595NaxAYp0hF9B/A0lH6C8Rms97e2JS9d3jVUtILn6pT5i5IV965ra3lIWc7Rs1GG1tBdVF7dCowYe6Q==}
+    dependencies:
+      '@mdx-js/mdx': 1.6.22
+      '@mdx-js/react': 1.6.22
+      loader-utils: 2.0.0
+    transitivePeerDependencies:
+      - react
+      - supports-color
     dev: true
 
-  /@types/http-proxy/1.17.8:
-    resolution: {integrity: 
sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA==}
+  /@mdx-js/mdx/1.6.22:
+    resolution: {integrity: 
sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA==}
     dependencies:
-      '@types/node': 18.8.5
+      '@babel/core': 7.12.9
+      '@babel/plugin-syntax-jsx': 7.12.1_@babel+core@7.12.9
+      '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.12.9
+      '@mdx-js/util': 1.6.22
+      babel-plugin-apply-mdx-type-prop: 1.6.22_@babel+core@7.12.9
+      babel-plugin-extract-import-names: 1.6.22
+      camelcase-css: 2.0.1
+      detab: 2.0.4
+      hast-util-raw: 6.0.1
+      lodash.uniq: 4.5.0
+      mdast-util-to-hast: 10.0.1
+      remark-footnotes: 2.0.0
+      remark-mdx: 1.6.22
+      remark-parse: 8.0.3
+      remark-squeeze-paragraphs: 4.0.0
+      style-to-object: 0.3.0
+      unified: 9.2.0
+      unist-builder: 2.0.3
+      unist-util-visit: 2.0.3
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /@types/istanbul-lib-coverage/2.0.3:
-    resolution: {integrity: 
sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==}
+  /@mdx-js/react/1.6.22:
+    resolution: {integrity: 
sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==}
+    peerDependencies:
+      react: ^16.13.1 || ^17.0.0
     dev: true
 
-  /@types/istanbul-lib-coverage/2.0.4:
-    resolution: {integrity: 
sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==}
+  /@mdx-js/util/1.6.22:
+    resolution: {integrity: 
sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA==}
     dev: true
 
-  /@types/istanbul-lib-report/3.0.0:
-    resolution: {integrity: 
sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==}
+  /@mrmlnc/readdir-enhanced/2.2.1:
+    resolution: {integrity: 
sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==}
+    engines: {node: '>=4'}
     dependencies:
-      '@types/istanbul-lib-coverage': 2.0.4
+      call-me-maybe: 1.0.1
+      glob-to-regexp: 0.3.0
     dev: true
 
-  /@types/istanbul-reports/3.0.1:
-    resolution: {integrity: 
sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==}
+  /@nicolo-ribaudo/eslint-scope-5-internals/5.1.1-v1:
+    resolution: {integrity: 
sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==}
     dependencies:
-      '@types/istanbul-lib-report': 3.0.0
+      eslint-scope: 5.1.1
     dev: true
 
-  /@types/json-schema/7.0.11:
-    resolution: {integrity: 
sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==}
+  /@nodelib/fs.scandir/2.1.5:
+    resolution: {integrity: 
sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
+    engines: {node: '>= 8'}
+    dependencies:
+      '@nodelib/fs.stat': 2.0.5
+      run-parallel: 1.2.0
     dev: true
 
-  /@types/json-schema/7.0.9:
-    resolution: {integrity: 
sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==}
+  /@nodelib/fs.stat/1.1.3:
+    resolution: {integrity: 
sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==}
+    engines: {node: '>= 6'}
     dev: true
 
-  /@types/json5/0.0.29:
-    resolution: {integrity: sha1-7ihweulOEdK4J7y+UnC86n8+ce4=}
+  /@nodelib/fs.stat/2.0.5:
+    resolution: {integrity: 
sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
+    engines: {node: '>= 8'}
     dev: true
 
-  /@types/keyv/3.1.4:
-    resolution: {integrity: 
sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==}
+  /@nodelib/fs.walk/1.2.8:
+    resolution: {integrity: 
sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
+    engines: {node: '>= 8'}
     dependencies:
-      '@types/node': 18.8.5
+      '@nodelib/fs.scandir': 2.1.5
+      fastq: 1.13.0
     dev: true
 
-  /@types/mime/1.3.2:
-    resolution: {integrity: 
sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==}
+  /@npmcli/fs/1.1.0:
+    resolution: {integrity: 
sha512-VhP1qZLXcrXRIaPoqb4YA55JQxLNF3jNR4T55IdOJa3+IFJKNYHtPvtXx8slmeMavj37vCzCfrqQM1vWLsYKLA==}
+    engines: {node: ^12.13.0 || ^14.15.0 || >=16}
+    deprecated: this version had an improper engines field added, update to 
1.1.1
+    dependencies:
+      '@gar/promisify': 1.1.2
+      semver: 7.3.8
     dev: true
 
-  /@types/mocha/9.0.0:
-    resolution: {integrity: 
sha512-scN0hAWyLVAvLR9AyW7HoFF5sJZglyBsbPuHO4fv7JRvfmPBMfp1ozWqOf/e4wwPNxezBZXRfWzMb6iFLgEVRA==}
+  /@npmcli/move-file/1.1.2:
+    resolution: {integrity: 
sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==}
+    engines: {node: '>=10'}
+    dependencies:
+      mkdirp: 1.0.4
+      rimraf: 3.0.2
     dev: true
 
-  /@types/node/18.8.5:
-    resolution: {integrity: 
sha512-Bq7G3AErwe5A/Zki5fdD3O6+0zDChhg671NfPjtIcbtzDNZTv4NPKMRFr7gtYPG7y+B8uTiNK4Ngd9T0FTar6Q==}
-
-  /@types/offscreencanvas/2019.7.0:
-    resolution: {integrity: 
sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg==}
-    dev: false
+  /@polka/url/1.0.0-next.21:
+    resolution: {integrity: 
sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==}
+    dev: true
 
-  /@types/parse-json/4.0.0:
-    resolution: {integrity: 
sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==}
+  /@popperjs/core/2.11.6:
+    resolution: {integrity: 
sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==}
     dev: true
 
-  /@types/q/1.5.5:
-    resolution: {integrity: 
sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==}
+  /@preact/async-loader/3.0.1_preact@10.6.1:
+    resolution: {integrity: 
sha512-BoUN24hxEfAQYnWjliAmkZLuliv+ONQi7AWn+/+VOJHTIHmbFiXrvmSxITf7PDkKiK0a5xy4OErZtVVLlk96Tg==}
+    engines: {node: '>=8'}
+    peerDependencies:
+      preact: '>= 10.0.0'
+    dependencies:
+      kleur: 4.1.4
+      loader-utils: 2.0.2
+      preact: 10.6.1
     dev: true
 
-  /@types/qs/6.9.7:
-    resolution: {integrity: 
sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==}
+  /@preact/async-loader/3.0.1_preact@10.6.5:
+    resolution: {integrity: 
sha512-BoUN24hxEfAQYnWjliAmkZLuliv+ONQi7AWn+/+VOJHTIHmbFiXrvmSxITf7PDkKiK0a5xy4OErZtVVLlk96Tg==}
+    engines: {node: '>=8'}
+    peerDependencies:
+      preact: '>= 10.0.0'
+    dependencies:
+      kleur: 4.1.4
+      loader-utils: 2.0.2
+      preact: 10.6.5
     dev: true
 
-  /@types/range-parser/1.2.4:
-    resolution: {integrity: 
sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==}
+  /@prefresh/babel-plugin/0.4.1:
+    resolution: {integrity: 
sha512-gj3ekiYtHlZNz0zFI1z6a9mcYX80Qacw84+2++7V1skvO7kQoV2ux56r8bJkTBbKMVxwAgaYrxxIdUCYlclE7Q==}
     dev: true
 
-  /@types/resolve/1.17.1:
-    resolution: {integrity: 
sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==}
+  /@prefresh/core/0.8.1_preact@10.6.5:
+    resolution: {integrity: 
sha512-woho+Ja8w3pxnZwq68MnWzH9ffdidrpJsV6PDTNIsJOpsLYmfCNxqxGsxIqYw40d1yjg4h6HFGbb6Y9lhyTPNA==}
+    peerDependencies:
+      preact: ^10.0.0
     dependencies:
-      '@types/node': 18.8.5
+      preact: 10.6.5
     dev: true
 
-  /@types/responselike/1.0.0:
-    resolution: {integrity: 
sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==}
-    dependencies:
-      '@types/node': 18.8.5
-    dev: true
-
-  /@types/retry/0.12.1:
-    resolution: {integrity: 
sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==}
-    dev: true
-
-  /@types/serve-index/1.9.1:
-    resolution: {integrity: 
sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==}
-    dependencies:
-      '@types/express': 4.17.13
-    dev: true
-
-  /@types/serve-static/1.13.10:
-    resolution: {integrity: 
sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==}
+  /@prefresh/core/1.3.2_preact@10.6.1:
+    resolution: {integrity: 
sha512-Iv+uI698KDgWsrKpLvOgN3hmAMyvhVgn09mcnhZ98BUNdg/qrxE7tcUf5yFCImkgqED5/Dcn8G5hFy4IikEDvg==}
+    peerDependencies:
+      preact: ^10.0.0
     dependencies:
-      '@types/mime': 1.3.2
-      '@types/node': 18.8.5
+      preact: 10.6.1
     dev: true
 
-  /@types/sockjs/0.3.33:
-    resolution: {integrity: 
sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==}
+  /@prefresh/core/1.3.2_preact@10.6.5:
+    resolution: {integrity: 
sha512-Iv+uI698KDgWsrKpLvOgN3hmAMyvhVgn09mcnhZ98BUNdg/qrxE7tcUf5yFCImkgqED5/Dcn8G5hFy4IikEDvg==}
+    peerDependencies:
+      preact: ^10.0.0
     dependencies:
-      '@types/node': 18.8.5
-    dev: true
-
-  /@types/source-list-map/0.1.2:
-    resolution: {integrity: 
sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==}
+      preact: 10.6.5
     dev: true
 
-  /@types/tapable/1.0.8:
-    resolution: {integrity: 
sha512-ipixuVrh2OdNmauvtT51o3d8z12p6LtFW9in7U79der/kwejjdNchQC5UMn5u/KxNoM7VHHOs/l8KS8uHxhODQ==}
+  /@prefresh/utils/0.3.1:
+    resolution: {integrity: 
sha512-9kLzPWN4teeiKuc+Rle3SF/hyx5lzo35X4rHr+kQXnJT+BaEb1ymDWIHGkv85xjnw8+l6I1r1H7JB4BHOMJfmg==}
     dev: true
 
-  /@types/trusted-types/2.0.2:
-    resolution: {integrity: 
sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==}
+  /@prefresh/utils/1.1.1:
+    resolution: {integrity: 
sha512-MUhT5m2XNN5NsZl4GnpuvlzLo6VSTa/+wBfBd3fiWUvHGhv0GF9hnA1pd//v0uJaKwUnVRQ1hYElxCV7DtYsCQ==}
     dev: true
 
-  /@types/uglify-js/3.13.1:
-    resolution: {integrity: 
sha512-O3MmRAk6ZuAKa9CHgg0Pr0+lUOqoMLpc9AS4R8ano2auvsg7IE8syF3Xh/NPr26TWklxYcqoEEFdzLLs1fV9PQ==}
+  /@prefresh/webpack/1.1.0_iaukxvobhnxulwhqqdnbfsnwxu:
+    resolution: {integrity: 
sha512-a3JG2maH3bacDobb4WywVTuqvAyBxJ7dRNSG2Ywv1AytAdgpgNZKJpR4xUTzPTwPGpRkfNOOf4mODqoOZ7W0Sw==}
+    peerDependencies:
+      preact: ^10.4.0
+      webpack: ^4.0.0 || ^5.0.0
     dependencies:
-      source-map: 0.6.1
+      '@prefresh/core': 0.8.1_preact@10.6.5
+      '@prefresh/utils': 0.3.1
+      preact: 10.6.5
+      webpack: 4.46.0
     dev: true
 
-  /@types/webpack-sources/3.2.0:
-    resolution: {integrity: 
sha512-Ft7YH3lEVRQ6ls8k4Ff1oB4jN6oy/XmU6tQISKdhfh+1mR+viZFphS6WL0IrtDOzvefmJg5a0s7ZQoRXwqTEFg==}
+  /@prefresh/webpack/3.3.2_dveknyjmyxkzkf4ybureeu5fae:
+    resolution: {integrity: 
sha512-1cX0t5G7IXWO2164sl2O32G02BzDl6C4UUZWfDb0x1CQM1g3It9PSLWd+rIlHfSg4MEU9YHM8e6/OK8uavRJhA==}
+    peerDependencies:
+      '@prefresh/babel-plugin': ^0.4.0
+      preact: ^10.4.0
+      webpack: ^4.0.0 || ^5.0.0
     dependencies:
-      '@types/node': 18.8.5
-      '@types/source-list-map': 0.1.2
-      source-map: 0.7.3
+      '@prefresh/babel-plugin': 0.4.1
+      '@prefresh/core': 1.3.2_preact@10.6.5
+      '@prefresh/utils': 1.1.1
+      preact: 10.6.5
+      webpack: 4.46.0
     dev: true
 
-  /@types/webpack/4.41.32:
-    resolution: {integrity: 
sha512-cb+0ioil/7oz5//7tZUSwbrSAN/NWHrQylz5cW8G0dWTcF/g+/dSdMlKVZspBYuMAN1+WnwHrkxiRrLcwd0Heg==}
+  /@prefresh/webpack/3.3.2_ev3yg7augojg2gbov5lykbl5qy:
+    resolution: {integrity: 
sha512-1cX0t5G7IXWO2164sl2O32G02BzDl6C4UUZWfDb0x1CQM1g3It9PSLWd+rIlHfSg4MEU9YHM8e6/OK8uavRJhA==}
+    peerDependencies:
+      '@prefresh/babel-plugin': ^0.4.0
+      preact: ^10.4.0
+      webpack: ^4.0.0 || ^5.0.0
     dependencies:
-      '@types/node': 18.8.5
-      '@types/tapable': 1.0.8
-      '@types/uglify-js': 3.13.1
-      '@types/webpack-sources': 3.2.0
-      anymatch: 3.1.2
-      source-map: 0.6.1
+      '@prefresh/babel-plugin': 0.4.1
+      '@prefresh/core': 1.3.2_preact@10.6.1
+      '@prefresh/utils': 1.1.1
+      preact: 10.6.1
+      webpack: 4.46.0
     dev: true
 
-  /@types/ws/8.2.2:
-    resolution: {integrity: 
sha512-NOn5eIcgWLOo6qW8AcuLZ7G8PycXu0xTxxkS6Q18VWFxgPUSOwV0pBj2a/4viNZVu25i7RIB7GttdkAIUUXOOg==}
+  /@reach/router/1.3.4:
+    resolution: {integrity: 
sha512-+mtn9wjlB9NN2CNnnC/BRYtwdKBfSyyasPYraNAyvaV1occr/5NnB4CVzjEZipNHwYebQwcndGUmpFzxAUoqSA==}
+    peerDependencies:
+      react: 15.x || 16.x || 16.4.0-alpha.0911da3
+      react-dom: 15.x || 16.x || 16.4.0-alpha.0911da3
     dependencies:
-      '@types/node': 18.8.5
+      create-react-context: 0.3.0_prop-types@15.8.1
+      invariant: 2.2.4
+      prop-types: 15.8.1
+      react-lifecycles-compat: 3.0.4
     dev: true
 
-  /@types/yargs-parser/20.2.1:
-    resolution: {integrity: 
sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==}
+  /@reach/router/1.3.4_wcqkhtmu7mswc6yz4uyexck3ty:
+    resolution: {integrity: 
sha512-+mtn9wjlB9NN2CNnnC/BRYtwdKBfSyyasPYraNAyvaV1occr/5NnB4CVzjEZipNHwYebQwcndGUmpFzxAUoqSA==}
+    peerDependencies:
+      react: 15.x || 16.x || 16.4.0-alpha.0911da3
+      react-dom: 15.x || 16.x || 16.4.0-alpha.0911da3
+    dependencies:
+      create-react-context: 0.3.0_4vyaxm4rsh2mpfdenvlqy7kmya
+      invariant: 2.2.4
+      prop-types: 15.8.1
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      react-lifecycles-compat: 3.0.4
     dev: true
 
-  /@types/yargs/15.0.14:
-    resolution: {integrity: 
sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==}
+  /@rollup/plugin-alias/3.1.9_rollup@2.79.0:
+    resolution: {integrity: 
sha512-QI5fsEvm9bDzt32k39wpOwZhVzRcL5ydcffUHMyLVaVaLeC70I8TJZ17F1z1eMoLu4E/UOcH9BWVkKpIKdrfiw==}
+    engines: {node: '>=8.0.0'}
+    peerDependencies:
+      rollup: ^1.20.0||^2.0.0
     dependencies:
-      '@types/yargs-parser': 20.2.1
+      rollup: 2.79.0
+      slash: 3.0.0
     dev: true
 
-  /@typescript-eslint/eslint-plugin/5.36.1_gjcw3hhr2cxnngiu5lw4bi633m:
-    resolution: {integrity: 
sha512-iC40UK8q1tMepSDwiLbTbMXKDxzNy+4TfPWgIL661Ym0sD42vRcQU93IsZIrmi+x292DBr60UI/gSwfdVYexCA==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+  /@rollup/plugin-babel/5.3.0_lubkdqoa5gexe4rox23cswxwm4:
+    resolution: {integrity: 
sha512-9uIC8HZOnVLrLHxayq/PTzw+uS25E14KPUBh5ktF+18Mjo5yK0ToMMx6epY0uEgkjwJw0aBW4x2horYXh8juWw==}
+    engines: {node: '>= 10.0.0'}
     peerDependencies:
-      '@typescript-eslint/parser': ^5.0.0
-      eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
-      typescript: '*'
+      '@babel/core': ^7.0.0
+      '@types/babel__core': ^7.1.9
+      rollup: ^1.20.0||^2.0.0
     peerDependenciesMeta:
-      typescript:
+      '@types/babel__core':
         optional: true
     dependencies:
-      '@typescript-eslint/parser': 5.36.1_o2nrgn6wwxunlqlzzokx4es3q4
-      '@typescript-eslint/scope-manager': 5.36.1
-      '@typescript-eslint/type-utils': 5.36.1_o2nrgn6wwxunlqlzzokx4es3q4
-      '@typescript-eslint/utils': 5.36.1_o2nrgn6wwxunlqlzzokx4es3q4
-      debug: 4.3.4
-      eslint: 8.8.0
-      functional-red-black-tree: 1.0.1
-      ignore: 5.2.0
-      regexpp: 3.2.0
-      semver: 7.3.7
-      tsutils: 3.21.0_typescript@4.8.4
-      typescript: 4.8.4
-    transitivePeerDependencies:
-      - supports-color
+      '@babel/core': 7.17.2
+      '@babel/helper-module-imports': 7.16.7
+      '@rollup/pluginutils': 3.1.0_rollup@2.79.0
+      rollup: 2.79.0
     dev: true
 
-  /@typescript-eslint/parser/5.36.1_o2nrgn6wwxunlqlzzokx4es3q4:
-    resolution: {integrity: 
sha512-/IsgNGOkBi7CuDfUbwt1eOqUXF9WGVBW9dwEe1pi+L32XrTsZIgmDFIi2RxjzsvB/8i+MIf5JIoTEH8LOZ368A==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+  /@rollup/plugin-babel/5.3.0_s45mkc5s7is4owdeow33qgy2s4:
+    resolution: {integrity: 
sha512-9uIC8HZOnVLrLHxayq/PTzw+uS25E14KPUBh5ktF+18Mjo5yK0ToMMx6epY0uEgkjwJw0aBW4x2horYXh8juWw==}
+    engines: {node: '>= 10.0.0'}
     peerDependencies:
-      eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
-      typescript: '*'
+      '@babel/core': ^7.0.0
+      '@types/babel__core': ^7.1.9
+      rollup: ^1.20.0||^2.0.0
     peerDependenciesMeta:
-      typescript:
+      '@types/babel__core':
         optional: true
     dependencies:
-      '@typescript-eslint/scope-manager': 5.36.1
-      '@typescript-eslint/types': 5.36.1
-      '@typescript-eslint/typescript-estree': 5.36.1_typescript@4.8.4
-      debug: 4.3.4
-      eslint: 8.8.0
-      typescript: 4.8.4
-    transitivePeerDependencies:
-      - supports-color
+      '@babel/core': 7.19.6
+      '@babel/helper-module-imports': 7.16.7
+      '@rollup/pluginutils': 3.1.0_rollup@2.79.0
+      rollup: 2.79.0
     dev: true
 
-  /@typescript-eslint/scope-manager/5.36.1:
-    resolution: {integrity: 
sha512-pGC2SH3/tXdu9IH3ItoqciD3f3RRGCh7hb9zPdN2Drsr341zgd6VbhP5OHQO/reUqihNltfPpMpTNihFMarP2w==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+  /@rollup/plugin-commonjs/20.0.0_rollup@2.79.0:
+    resolution: {integrity: 
sha512-5K0g5W2Ol8hAcTHqcTBHiA7M58tfmYi1o9KxeJuuRNpGaTa5iLjcyemBitCBcKXaHamOBBEH2dGom6v6Unmqjg==}
+    engines: {node: '>= 8.0.0'}
+    peerDependencies:
+      rollup: ^2.38.3
     dependencies:
-      '@typescript-eslint/types': 5.36.1
-      '@typescript-eslint/visitor-keys': 5.36.1
+      '@rollup/pluginutils': 3.1.0_rollup@2.79.0
+      commondir: 1.0.1
+      estree-walker: 2.0.2
+      glob: 7.2.3
+      is-reference: 1.2.1
+      magic-string: 0.25.9
+      resolve: 1.22.1
+      rollup: 2.79.0
     dev: true
 
-  /@typescript-eslint/type-utils/5.36.1_o2nrgn6wwxunlqlzzokx4es3q4:
-    resolution: {integrity: 
sha512-xfZhfmoQT6m3lmlqDvDzv9TiCYdw22cdj06xY0obSznBsT///GK5IEZQdGliXpAOaRL34o8phEvXzEo/VJx13Q==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+  /@rollup/plugin-commonjs/22.0.2_rollup@2.79.0:
+    resolution: {integrity: 
sha512-//NdP6iIwPbMTcazYsiBMbJW7gfmpHom33u1beiIoHDEM0Q9clvtQB1T0efvMqHeKsGohiHo97BCPCkBXdscwg==}
+    engines: {node: '>= 12.0.0'}
     peerDependencies:
-      eslint: '*'
-      typescript: '*'
-    peerDependenciesMeta:
-      typescript:
-        optional: true
+      rollup: ^2.68.0
     dependencies:
-      '@typescript-eslint/typescript-estree': 5.36.1_typescript@4.8.4
-      '@typescript-eslint/utils': 5.36.1_o2nrgn6wwxunlqlzzokx4es3q4
-      debug: 4.3.4
-      eslint: 8.8.0
-      tsutils: 3.21.0_typescript@4.8.4
-      typescript: 4.8.4
-    transitivePeerDependencies:
-      - supports-color
-    dev: true
-
-  /@typescript-eslint/types/5.36.1:
-    resolution: {integrity: 
sha512-jd93ShpsIk1KgBTx9E+hCSEuLCUFwi9V/urhjOWnOaksGZFbTOxAT47OH2d4NLJnLhkVD+wDbB48BuaycZPLBg==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+      '@rollup/pluginutils': 3.1.0_rollup@2.79.0
+      commondir: 1.0.1
+      estree-walker: 2.0.2
+      glob: 7.2.3
+      is-reference: 1.2.1
+      magic-string: 0.25.9
+      resolve: 1.22.1
+      rollup: 2.79.0
     dev: true
 
-  /@typescript-eslint/typescript-estree/5.36.1_typescript@4.8.4:
-    resolution: {integrity: 
sha512-ih7V52zvHdiX6WcPjsOdmADhYMDN15SylWRZrT2OMy80wzKbc79n8wFW0xpWpU0x3VpBz/oDgTm2xwDAnFTl+g==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+  /@rollup/plugin-html/0.2.4_rollup@2.79.0:
+    resolution: {integrity: 
sha512-x0qpNXxbmGa9Jnl4OX89AORPe2T/a4DqNK69BGRnEdaPKq6MdiUXSTam/eCkF5DxkQGcRcPq0L4vzr/E3q4mVA==}
+    engines: {node: '>= 8.0.0'}
     peerDependencies:
-      typescript: '*'
-    peerDependenciesMeta:
-      typescript:
-        optional: true
+      rollup: ^1.20.0||^2.0.0
     dependencies:
-      '@typescript-eslint/types': 5.36.1
-      '@typescript-eslint/visitor-keys': 5.36.1
-      debug: 4.3.4
-      globby: 11.1.0
-      is-glob: 4.0.3
-      semver: 7.3.7
-      tsutils: 3.21.0_typescript@4.8.4
-      typescript: 4.8.4
-    transitivePeerDependencies:
-      - supports-color
+      rollup: 2.79.0
     dev: true
 
-  /@typescript-eslint/utils/5.36.1_o2nrgn6wwxunlqlzzokx4es3q4:
-    resolution: {integrity: 
sha512-lNj4FtTiXm5c+u0pUehozaUWhh7UYKnwryku0nxJlYUEWetyG92uw2pr+2Iy4M/u0ONMKzfrx7AsGBTCzORmIg==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+  /@rollup/plugin-image/2.1.1_rollup@2.79.0:
+    resolution: {integrity: 
sha512-AgP4U85zuQJdUopLUCM+hTf45RepgXeTb8EJsleExVy99dIoYpt3ZlDYJdKmAc2KLkNntCDg6BPJvgJU3uGF+g==}
+    engines: {node: '>= 8.0.0'}
     peerDependencies:
-      eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
+      rollup: ^1.20.0 || ^2.0.0
     dependencies:
-      '@types/json-schema': 7.0.11
-      '@typescript-eslint/scope-manager': 5.36.1
-      '@typescript-eslint/types': 5.36.1
-      '@typescript-eslint/typescript-estree': 5.36.1_typescript@4.8.4
-      eslint: 8.8.0
-      eslint-scope: 5.1.1
-      eslint-utils: 3.0.0_eslint@8.8.0
-    transitivePeerDependencies:
-      - supports-color
-      - typescript
+      '@rollup/pluginutils': 3.1.0_rollup@2.79.0
+      mini-svg-data-uri: 1.4.4
+      rollup: 2.79.0
     dev: true
 
-  /@typescript-eslint/visitor-keys/5.36.1:
-    resolution: {integrity: 
sha512-ojB9aRyRFzVMN3b5joSYni6FAS10BBSCAfKJhjJAV08t/a95aM6tAhz+O1jF+EtgxktuSO3wJysp2R+Def/IWQ==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+  /@rollup/plugin-json/4.1.0_rollup@2.79.0:
+    resolution: {integrity: 
sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==}
+    peerDependencies:
+      rollup: ^1.20.0 || ^2.0.0
     dependencies:
-      '@typescript-eslint/types': 5.36.1
-      eslint-visitor-keys: 3.3.0
-    dev: true
-
-  /@ungap/promise-all-settled/1.1.2:
-    resolution: {integrity: 
sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==}
+      '@rollup/pluginutils': 3.1.0_rollup@2.79.0
+      rollup: 2.79.0
     dev: true
 
-  /@webassemblyjs/ast/1.9.0:
-    resolution: {integrity: 
sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==}
+  /@rollup/plugin-node-resolve/11.2.1_rollup@2.79.0:
+    resolution: {integrity: 
sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==}
+    engines: {node: '>= 10.0.0'}
+    peerDependencies:
+      rollup: ^1.20.0||^2.0.0
     dependencies:
-      '@webassemblyjs/helper-module-context': 1.9.0
-      '@webassemblyjs/helper-wasm-bytecode': 1.9.0
-      '@webassemblyjs/wast-parser': 1.9.0
+      '@rollup/pluginutils': 3.1.0_rollup@2.79.0
+      '@types/resolve': 1.17.1
+      builtin-modules: 3.3.0
+      deepmerge: 4.2.2
+      is-module: 1.0.0
+      resolve: 1.22.1
+      rollup: 2.79.0
     dev: true
 
-  /@webassemblyjs/floating-point-hex-parser/1.9.0:
-    resolution: {integrity: 
sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==}
+  /@rollup/plugin-node-resolve/13.3.0_rollup@2.79.0:
+    resolution: {integrity: 
sha512-Lus8rbUo1eEcnS4yTFKLZrVumLPY+YayBdWXgFSHYhTT2iJbMhoaaBL3xl5NCdeRytErGr8tZ0L71BMRmnlwSw==}
+    engines: {node: '>= 10.0.0'}
+    peerDependencies:
+      rollup: ^2.42.0
+    dependencies:
+      '@rollup/pluginutils': 3.1.0_rollup@2.79.0
+      '@types/resolve': 1.17.1
+      deepmerge: 4.2.2
+      is-builtin-module: 3.2.0
+      is-module: 1.0.0
+      resolve: 1.22.1
+      rollup: 2.79.0
     dev: true
 
-  /@webassemblyjs/helper-api-error/1.9.0:
-    resolution: {integrity: 
sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==}
+  /@rollup/plugin-node-resolve/7.1.3_rollup@1.32.1:
+    resolution: {integrity: 
sha512-RxtSL3XmdTAE2byxekYLnx+98kEUOrPHF/KRVjLH+DEIHy6kjIw7YINQzn+NXiH/NTrQLAwYs0GWB+csWygA9Q==}
+    engines: {node: '>= 8.0.0'}
+    peerDependencies:
+      rollup: ^1.20.0||^2.0.0
+    dependencies:
+      '@rollup/pluginutils': 3.1.0_rollup@1.32.1
+      '@types/resolve': 0.0.8
+      builtin-modules: 3.3.0
+      is-module: 1.0.0
+      resolve: 1.22.1
+      rollup: 1.32.1
     dev: true
 
-  /@webassemblyjs/helper-buffer/1.9.0:
-    resolution: {integrity: 
sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==}
+  /@rollup/plugin-replace/2.4.2_rollup@1.32.1:
+    resolution: {integrity: 
sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==}
+    peerDependencies:
+      rollup: ^1.20.0 || ^2.0.0
+    dependencies:
+      '@rollup/pluginutils': 3.1.0_rollup@1.32.1
+      magic-string: 0.25.9
+      rollup: 1.32.1
     dev: true
 
-  /@webassemblyjs/helper-code-frame/1.9.0:
-    resolution: {integrity: 
sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==}
+  /@rollup/plugin-replace/2.4.2_rollup@2.79.0:
+    resolution: {integrity: 
sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==}
+    peerDependencies:
+      rollup: ^1.20.0 || ^2.0.0
     dependencies:
-      '@webassemblyjs/wast-printer': 1.9.0
+      '@rollup/pluginutils': 3.1.0_rollup@2.79.0
+      magic-string: 0.25.9
+      rollup: 2.79.0
     dev: true
 
-  /@webassemblyjs/helper-fsm/1.9.0:
-    resolution: {integrity: 
sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==}
+  /@rollup/plugin-replace/3.1.0_rollup@2.79.0:
+    resolution: {integrity: 
sha512-pA3XRUrSKybVYqmH5TqWNZpGxF+VV+1GrYchKgCNIj2vsSOX7CVm2RCtx8p2nrC7xvkziYyK+lSi74T93MU3YA==}
+    peerDependencies:
+      rollup: ^1.20.0 || ^2.0.0
+    dependencies:
+      '@rollup/pluginutils': 3.1.0_rollup@2.79.0
+      magic-string: 0.25.9
+      rollup: 2.79.0
     dev: true
 
-  /@webassemblyjs/helper-module-context/1.9.0:
-    resolution: {integrity: 
sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==}
+  /@rollup/plugin-replace/4.0.0_rollup@2.79.0:
+    resolution: {integrity: 
sha512-+rumQFiaNac9y64OHtkHGmdjm7us9bo1PlbgQfdihQtuNxzjpaB064HbRnewUOggLQxVCCyINfStkgmBeQpv1g==}
+    peerDependencies:
+      rollup: ^1.20.0 || ^2.0.0
     dependencies:
-      '@webassemblyjs/ast': 1.9.0
+      '@rollup/pluginutils': 3.1.0_rollup@2.79.0
+      magic-string: 0.25.9
+      rollup: 2.79.0
     dev: true
 
-  /@webassemblyjs/helper-wasm-bytecode/1.9.0:
-    resolution: {integrity: 
sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==}
+  /@rollup/plugin-typescript/8.5.0_jnsxykt6ocebvgsxrxe2hsbo6y:
+    resolution: {integrity: 
sha512-wMv1/scv0m/rXx21wD2IsBbJFba8wGF3ErJIr6IKRfRj49S85Lszbxb4DCo8iILpluTjk2GAAu9CoZt4G3ppgQ==}
+    engines: {node: '>=8.0.0'}
+    peerDependencies:
+      rollup: ^2.14.0
+      tslib: '*'
+      typescript: '>=3.7.0'
+    peerDependenciesMeta:
+      tslib:
+        optional: true
+    dependencies:
+      '@rollup/pluginutils': 3.1.0_rollup@2.79.0
+      resolve: 1.22.1
+      rollup: 2.79.0
+      tslib: 2.4.0
+      typescript: 4.8.4
     dev: true
 
-  /@webassemblyjs/helper-wasm-section/1.9.0:
-    resolution: {integrity: 
sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==}
+  /@rollup/pluginutils/3.1.0_rollup@1.32.1:
+    resolution: {integrity: 
sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==}
+    engines: {node: '>= 8.0.0'}
+    peerDependencies:
+      rollup: ^1.20.0||^2.0.0
     dependencies:
-      '@webassemblyjs/ast': 1.9.0
-      '@webassemblyjs/helper-buffer': 1.9.0
-      '@webassemblyjs/helper-wasm-bytecode': 1.9.0
-      '@webassemblyjs/wasm-gen': 1.9.0
+      '@types/estree': 0.0.39
+      estree-walker: 1.0.1
+      picomatch: 2.3.1
+      rollup: 1.32.1
     dev: true
 
-  /@webassemblyjs/ieee754/1.9.0:
-    resolution: {integrity: 
sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==}
+  /@rollup/pluginutils/3.1.0_rollup@2.79.0:
+    resolution: {integrity: 
sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==}
+    engines: {node: '>= 8.0.0'}
+    peerDependencies:
+      rollup: ^1.20.0||^2.0.0
     dependencies:
-      '@xtuc/ieee754': 1.2.0
+      '@types/estree': 0.0.39
+      estree-walker: 1.0.1
+      picomatch: 2.3.1
+      rollup: 2.79.0
     dev: true
 
-  /@webassemblyjs/leb128/1.9.0:
-    resolution: {integrity: 
sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==}
+  /@rollup/pluginutils/4.2.1:
+    resolution: {integrity: 
sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==}
+    engines: {node: '>= 8.0.0'}
     dependencies:
-      '@xtuc/long': 4.2.2
+      estree-walker: 2.0.2
+      picomatch: 2.3.1
     dev: true
 
-  /@webassemblyjs/utf8/1.9.0:
-    resolution: {integrity: 
sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==}
+  /@sinclair/typebox/0.24.50:
+    resolution: {integrity: 
sha512-k8ETQOOQDg5FtK7y9KJWpsGLik+QlPmIi8zzl/dGUgshV2QitprkFlCR/AemjWOTyKn9UwSSGRTzLVotvgCjYQ==}
     dev: true
 
-  /@webassemblyjs/wasm-edit/1.9.0:
-    resolution: {integrity: 
sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==}
-    dependencies:
-      '@webassemblyjs/ast': 1.9.0
-      '@webassemblyjs/helper-buffer': 1.9.0
-      '@webassemblyjs/helper-wasm-bytecode': 1.9.0
-      '@webassemblyjs/helper-wasm-section': 1.9.0
-      '@webassemblyjs/wasm-gen': 1.9.0
-      '@webassemblyjs/wasm-opt': 1.9.0
-      '@webassemblyjs/wasm-parser': 1.9.0
-      '@webassemblyjs/wast-printer': 1.9.0
+  /@sindresorhus/is/0.14.0:
+    resolution: {integrity: 
sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==}
+    engines: {node: '>=6'}
     dev: true
 
-  /@webassemblyjs/wasm-gen/1.9.0:
-    resolution: {integrity: 
sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==}
+  /@sinonjs/commons/1.8.3:
+    resolution: {integrity: 
sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==}
     dependencies:
-      '@webassemblyjs/ast': 1.9.0
-      '@webassemblyjs/helper-wasm-bytecode': 1.9.0
-      '@webassemblyjs/ieee754': 1.9.0
-      '@webassemblyjs/leb128': 1.9.0
-      '@webassemblyjs/utf8': 1.9.0
+      type-detect: 4.0.8
     dev: true
 
-  /@webassemblyjs/wasm-opt/1.9.0:
-    resolution: {integrity: 
sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==}
+  /@sinonjs/fake-timers/6.0.1:
+    resolution: {integrity: 
sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==}
     dependencies:
-      '@webassemblyjs/ast': 1.9.0
-      '@webassemblyjs/helper-buffer': 1.9.0
-      '@webassemblyjs/wasm-gen': 1.9.0
-      '@webassemblyjs/wasm-parser': 1.9.0
+      '@sinonjs/commons': 1.8.3
     dev: true
 
-  /@webassemblyjs/wasm-parser/1.9.0:
-    resolution: {integrity: 
sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==}
+  /@sinonjs/fake-timers/8.1.0:
+    resolution: {integrity: 
sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==}
     dependencies:
-      '@webassemblyjs/ast': 1.9.0
-      '@webassemblyjs/helper-api-error': 1.9.0
-      '@webassemblyjs/helper-wasm-bytecode': 1.9.0
-      '@webassemblyjs/ieee754': 1.9.0
-      '@webassemblyjs/leb128': 1.9.0
-      '@webassemblyjs/utf8': 1.9.0
+      '@sinonjs/commons': 1.8.3
     dev: true
 
-  /@webassemblyjs/wast-parser/1.9.0:
-    resolution: {integrity: 
sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==}
+  /@storybook/addon-a11y/6.2.9:
+    resolution: {integrity: 
sha512-wo7nFpEqEeiHDsRKnhqe2gIHZ9Z7/Aefw570kBgReU5tKlmrb5rFAfTVBWGBZlLHWeJMsFsRsWrWrmkf1B52OQ==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+    peerDependenciesMeta:
+      react:
+        optional: true
+      react-dom:
+        optional: true
     dependencies:
-      '@webassemblyjs/ast': 1.9.0
-      '@webassemblyjs/floating-point-hex-parser': 1.9.0
-      '@webassemblyjs/helper-api-error': 1.9.0
-      '@webassemblyjs/helper-code-frame': 1.9.0
-      '@webassemblyjs/helper-fsm': 1.9.0
-      '@xtuc/long': 4.2.2
+      '@storybook/addons': 6.2.9
+      '@storybook/api': 6.2.9
+      '@storybook/channels': 6.2.9
+      '@storybook/client-api': 6.2.9
+      '@storybook/client-logger': 6.2.9
+      '@storybook/components': 6.2.9
+      '@storybook/core-events': 6.2.9
+      '@storybook/theming': 6.2.9
+      axe-core: 4.3.5
+      core-js: 3.26.0
+      global: 4.4.0
+      lodash: 4.17.21
+      react-sizeme: 3.0.2
+      regenerator-runtime: 0.13.9
+      ts-dedent: 2.2.0
+      util-deprecate: 1.0.2
+    transitivePeerDependencies:
+      - '@types/react'
     dev: true
 
-  /@webassemblyjs/wast-printer/1.9.0:
-    resolution: {integrity: 
sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==}
+  /@storybook/addon-a11y/6.5.13:
+    resolution: {integrity: 
sha512-+Tcl/4LWRh3ygLUZFGvkjT42CF/tJcP+kgsIho7i2MxpgZyD6+BUhL9srPZusjbR+uHcHXJ/yxw/vxFQ+UCTLA==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    peerDependenciesMeta:
+      react:
+        optional: true
+      react-dom:
+        optional: true
     dependencies:
-      '@webassemblyjs/ast': 1.9.0
-      '@webassemblyjs/wast-parser': 1.9.0
-      '@xtuc/long': 4.2.2
+      '@storybook/addons': 6.5.13
+      '@storybook/api': 6.5.13
+      '@storybook/channels': 6.5.13
+      '@storybook/client-logger': 6.5.13
+      '@storybook/components': 6.5.13
+      '@storybook/core-events': 6.5.13
+      '@storybook/csf': 0.0.2--canary.4566f4d.1
+      '@storybook/theming': 6.5.13
+      axe-core: 4.3.5
+      core-js: 3.26.0
+      global: 4.4.0
+      lodash: 4.17.21
+      react-sizeme: 3.0.2
+      regenerator-runtime: 0.13.9
+      ts-dedent: 2.2.0
+      util-deprecate: 1.0.2
     dev: true
 
-  /@xtuc/ieee754/1.2.0:
-    resolution: {integrity: 
sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==}
+  /@storybook/addon-actions/6.2.9:
+    resolution: {integrity: 
sha512-CkUYSMt+fvuHfWvtDzlhhaeQBCWlUo99xdL88JTsTml05P43bIHZNIRv2QJ8DwhHuxdIPeHKLmz9y/ymOagOnw==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+    peerDependenciesMeta:
+      react:
+        optional: true
+      react-dom:
+        optional: true
+    dependencies:
+      '@storybook/addons': 6.2.9
+      '@storybook/api': 6.2.9
+      '@storybook/client-api': 6.2.9
+      '@storybook/components': 6.2.9
+      '@storybook/core-events': 6.2.9
+      '@storybook/theming': 6.2.9
+      core-js: 3.26.0
+      fast-deep-equal: 3.1.3
+      global: 4.4.0
+      lodash: 4.17.21
+      polished: 4.1.4
+      prop-types: 15.8.1
+      react-inspector: 5.1.1
+      regenerator-runtime: 0.13.9
+      ts-dedent: 2.2.0
+      util-deprecate: 1.0.2
+      uuid-browser: 3.1.0
+    transitivePeerDependencies:
+      - '@types/react'
     dev: true
 
-  /@xtuc/long/4.2.2:
-    resolution: {integrity: 
sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==}
+  /@storybook/addon-actions/6.5.13:
+    resolution: {integrity: 
sha512-3Tji0gIy95havhTpSc6CsFl5lNxGn4O5Y1U9fyji+GRkKqDFOrvVLYAHPtLOpYdEI5tF0bDo+akiqfDouY8+eA==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    peerDependenciesMeta:
+      react:
+        optional: true
+      react-dom:
+        optional: true
+    dependencies:
+      '@storybook/addons': 6.5.13
+      '@storybook/api': 6.5.13
+      '@storybook/client-logger': 6.5.13
+      '@storybook/components': 6.5.13
+      '@storybook/core-events': 6.5.13
+      '@storybook/csf': 0.0.2--canary.4566f4d.1
+      '@storybook/theming': 6.5.13
+      core-js: 3.26.0
+      fast-deep-equal: 3.1.3
+      global: 4.4.0
+      lodash: 4.17.21
+      polished: 4.2.2
+      prop-types: 15.8.1
+      react-inspector: 5.1.1
+      regenerator-runtime: 0.13.9
+      telejson: 6.0.8
+      ts-dedent: 2.2.0
+      util-deprecate: 1.0.2
+      uuid-browser: 3.1.0
     dev: true
 
-  /abab/2.0.5:
-    resolution: {integrity: 
sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==}
+  /@storybook/addon-backgrounds/6.2.9:
+    resolution: {integrity: 
sha512-oPSdeoUuvaXshY5sQRagbYXpr6ZEVUuLhGYBnZTlvm19QMeNCXQE+rdlgzcgyafq4mc1FI/udE2MpJ1dhfS6pQ==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+    peerDependenciesMeta:
+      react:
+        optional: true
+      react-dom:
+        optional: true
+    dependencies:
+      '@storybook/addons': 6.2.9
+      '@storybook/api': 6.2.9
+      '@storybook/client-logger': 6.2.9
+      '@storybook/components': 6.2.9
+      '@storybook/core-events': 6.2.9
+      '@storybook/theming': 6.2.9
+      core-js: 3.26.0
+      global: 4.4.0
+      memoizerific: 1.11.3
+      regenerator-runtime: 0.13.9
+      ts-dedent: 2.2.0
+      util-deprecate: 1.0.2
+    transitivePeerDependencies:
+      - '@types/react'
     dev: true
 
-  /accepts/1.3.8:
-    resolution: {integrity: 
sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==}
-    engines: {node: '>= 0.6'}
+  /@storybook/addon-backgrounds/6.5.13:
+    resolution: {integrity: 
sha512-b4JX7JMY7e50y1l6g71D+2XWV3GO0TO2z1ta8J6W4OQt8f44V7sSkRQaJUzXdLjQMrA+Anojuy1ZwPjVeLC6vg==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    peerDependenciesMeta:
+      react:
+        optional: true
+      react-dom:
+        optional: true
     dependencies:
-      mime-types: 2.1.34
-      negotiator: 0.6.3
+      '@storybook/addons': 6.5.13
+      '@storybook/api': 6.5.13
+      '@storybook/client-logger': 6.5.13
+      '@storybook/components': 6.5.13
+      '@storybook/core-events': 6.5.13
+      '@storybook/csf': 0.0.2--canary.4566f4d.1
+      '@storybook/theming': 6.5.13
+      core-js: 3.26.0
+      global: 4.4.0
+      memoizerific: 1.11.3
+      regenerator-runtime: 0.13.9
+      ts-dedent: 2.2.0
+      util-deprecate: 1.0.2
     dev: true
 
-  /acorn-globals/4.3.4:
-    resolution: {integrity: 
sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==}
+  /@storybook/addon-controls/6.2.9:
+    resolution: {integrity: 
sha512-NvXAJ7I5U4CLxv4wL3/Ne9rehJlgnSmQlLIG/z6dg5zm7JIb48LT4IY6GzjlUP5LkjmO9KJ8gJC249uRt2iPBQ==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+    peerDependenciesMeta:
+      react:
+        optional: true
+      react-dom:
+        optional: true
     dependencies:
-      acorn: 6.4.2
-      acorn-walk: 6.2.0
+      '@storybook/addons': 6.2.9
+      '@storybook/api': 6.2.9
+      '@storybook/client-api': 6.2.9
+      '@storybook/components': 6.2.9
+      '@storybook/node-logger': 6.2.9
+      '@storybook/theming': 6.2.9
+      core-js: 3.26.0
+      ts-dedent: 2.2.0
+    transitivePeerDependencies:
+      - '@types/react'
     dev: true
 
-  /acorn-jsx/5.3.2_acorn@8.7.0:
-    resolution: {integrity: 
sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
+  /@storybook/addon-controls/6.5.13_3rubbgt5ekhqrcgx4uwls3neim:
+    resolution: {integrity: 
sha512-lYq3uf2mlVevm0bi6ueL3H6TpUMRYW9s/pTNTVJT225l27kLdFR9wEKxAkCBrlKaTgDLJmzzDRsJE3NLZlR/5Q==}
     peerDependencies:
-      acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    peerDependenciesMeta:
+      react:
+        optional: true
+      react-dom:
+        optional: true
     dependencies:
-      acorn: 8.7.0
+      '@storybook/addons': 6.5.13
+      '@storybook/api': 6.5.13
+      '@storybook/client-logger': 6.5.13
+      '@storybook/components': 6.5.13
+      '@storybook/core-common': 6.5.13_3rubbgt5ekhqrcgx4uwls3neim
+      '@storybook/csf': 0.0.2--canary.4566f4d.1
+      '@storybook/node-logger': 6.5.13
+      '@storybook/store': 6.5.13
+      '@storybook/theming': 6.5.13
+      core-js: 3.26.0
+      lodash: 4.17.21
+      ts-dedent: 2.2.0
+    transitivePeerDependencies:
+      - eslint
+      - supports-color
+      - typescript
+      - vue-template-compiler
+      - webpack-cli
+      - webpack-command
     dev: true
 
-  /acorn-walk/6.2.0:
-    resolution: {integrity: 
sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==}
-    engines: {node: '>=0.4.0'}
+  /@storybook/addon-docs/6.2.9_dtgd2mm6ybnh5irau5bfapxhdy:
+    resolution: {integrity: 
sha512-qOtwgiqI3LMqT0eXYNV6ykp7qSu0LQGeXxy3wOBGuDDqAizfgnAjomYEWGFcyKp5ahV7HCRCjxbixAklFPUmyw==}
+    peerDependencies:
+      '@babel/core': ^7.11.5
+      '@storybook/angular': 6.2.9
+      '@storybook/vue': 6.2.9
+      '@storybook/vue3': 6.2.9
+      babel-loader: ^8.0.0
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+      svelte: ^3.31.2
+      sveltedoc-parser: ^4.1.0
+      vue: ^2.6.10 || ^3.0.0
+      webpack: '*'
+    peerDependenciesMeta:
+      '@storybook/angular':
+        optional: true
+      '@storybook/vue':
+        optional: true
+      '@storybook/vue3':
+        optional: true
+      react:
+        optional: true
+      react-dom:
+        optional: true
+      svelte:
+        optional: true
+      sveltedoc-parser:
+        optional: true
+      vue:
+        optional: true
+      webpack:
+        optional: true
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/generator': 7.18.2
+      '@babel/parser': 7.18.4
+      '@babel/plugin-transform-react-jsx': 7.16.7_@babel+core@7.17.2
+      '@babel/preset-env': 7.16.11_@babel+core@7.17.2
+      '@jest/transform': 26.6.2
+      '@mdx-js/loader': 1.6.22
+      '@mdx-js/mdx': 1.6.22
+      '@mdx-js/react': 1.6.22
+      '@storybook/addons': 6.2.9
+      '@storybook/api': 6.2.9
+      '@storybook/builder-webpack4': 6.2.9_o2nrgn6wwxunlqlzzokx4es3q4
+      '@storybook/client-api': 6.2.9
+      '@storybook/client-logger': 6.2.9
+      '@storybook/components': 6.2.9
+      '@storybook/core': 6.2.9_o2nrgn6wwxunlqlzzokx4es3q4
+      '@storybook/core-events': 6.2.9
+      '@storybook/csf': 0.0.1
+      '@storybook/node-logger': 6.2.9
+      '@storybook/postinstall': 6.2.9
+      '@storybook/source-loader': 6.2.9
+      '@storybook/theming': 6.2.9
+      acorn: 7.4.1
+      acorn-jsx: 5.3.2_acorn@7.4.1
+      acorn-walk: 7.2.0
+      babel-loader: 8.2.3_@babel+core@7.17.2
+      core-js: 3.26.0
+      doctrine: 3.0.0
+      escodegen: 2.0.0
+      fast-deep-equal: 3.1.3
+      global: 4.4.0
+      html-tags: 3.2.0
+      js-string-escape: 1.0.1
+      loader-utils: 2.0.2
+      lodash: 4.17.21
+      prettier: 2.2.1
+      prop-types: 15.8.1
+      react-element-to-jsx-string: 14.3.4
+      regenerator-runtime: 0.13.9
+      remark-external-links: 8.0.0
+      remark-slug: 6.1.0
+      ts-dedent: 2.2.0
+      util-deprecate: 1.0.2
+    transitivePeerDependencies:
+      - '@storybook/builder-webpack5'
+      - '@types/react'
+      - bluebird
+      - encoding
+      - eslint
+      - supports-color
+      - typescript
+      - vue-template-compiler
+      - webpack-cli
+      - webpack-command
     dev: true
 
-  /acorn-walk/8.2.0:
-    resolution: {integrity: 
sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==}
-    engines: {node: '>=0.4.0'}
+  /@storybook/addon-docs/6.5.13_t6isvk4c5wetct53pn5ufojx2u:
+    resolution: {integrity: 
sha512-RG/NjsheD9FixZ789RJlNyNccaR2Cuy7CtAwph4oUNi3aDFjtOI8Oe9L+FOT7qtVnZLw/YMjF+pZxoDqJNKLPw==}
+    peerDependencies:
+      '@storybook/mdx2-csf': ^0.0.3
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    peerDependenciesMeta:
+      '@storybook/mdx2-csf':
+        optional: true
+      react:
+        optional: true
+      react-dom:
+        optional: true
+    dependencies:
+      '@babel/plugin-transform-react-jsx': 7.16.7_@babel+core@7.17.2
+      '@babel/preset-env': 7.16.11_@babel+core@7.17.2
+      '@jest/transform': 26.6.2
+      '@mdx-js/react': 1.6.22
+      '@storybook/addons': 6.5.13
+      '@storybook/api': 6.5.13
+      '@storybook/components': 6.5.13
+      '@storybook/core-common': 6.5.13_3rubbgt5ekhqrcgx4uwls3neim
+      '@storybook/core-events': 6.5.13
+      '@storybook/csf': 0.0.2--canary.4566f4d.1
+      '@storybook/docs-tools': 6.5.13
+      '@storybook/mdx1-csf': 0.0.1_@babel+core@7.17.2
+      '@storybook/node-logger': 6.5.13
+      '@storybook/postinstall': 6.5.13
+      '@storybook/preview-web': 6.5.13
+      '@storybook/source-loader': 6.5.13
+      '@storybook/store': 6.5.13
+      '@storybook/theming': 6.5.13
+      babel-loader: 8.2.3_@babel+core@7.17.2
+      core-js: 3.26.0
+      fast-deep-equal: 3.1.3
+      global: 4.4.0
+      lodash: 4.17.21
+      regenerator-runtime: 0.13.9
+      remark-external-links: 8.0.0
+      remark-slug: 6.1.0
+      ts-dedent: 2.2.0
+      util-deprecate: 1.0.2
+    transitivePeerDependencies:
+      - '@babel/core'
+      - eslint
+      - supports-color
+      - typescript
+      - vue-template-compiler
+      - webpack
+      - webpack-cli
+      - webpack-command
     dev: true
 
-  /acorn/6.4.2:
-    resolution: {integrity: 
sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==}
-    engines: {node: '>=0.4.0'}
-    hasBin: true
+  /@storybook/addon-essentials/6.2.9_dtgd2mm6ybnh5irau5bfapxhdy:
+    resolution: {integrity: 
sha512-zXsV4e1TCkHyDwi7hew4h9eJfDW++f2BNKzTif+DAcjPUVFDp7yC17gLjS5IhOjcQk+db0UUlFSx/OrTxhy7Xw==}
+    peerDependencies:
+      '@babel/core': ^7.9.6
+      '@storybook/vue': 6.2.9
+      babel-loader: ^8.0.0
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+      webpack: '*'
+    peerDependenciesMeta:
+      '@storybook/vue':
+        optional: true
+      react:
+        optional: true
+      react-dom:
+        optional: true
+      webpack:
+        optional: true
+    dependencies:
+      '@babel/core': 7.17.2
+      '@storybook/addon-actions': 6.2.9
+      '@storybook/addon-backgrounds': 6.2.9
+      '@storybook/addon-controls': 6.2.9
+      '@storybook/addon-docs': 6.2.9_dtgd2mm6ybnh5irau5bfapxhdy
+      '@storybook/addon-toolbars': 6.2.9
+      '@storybook/addon-viewport': 6.2.9
+      '@storybook/addons': 6.2.9
+      '@storybook/api': 6.2.9
+      '@storybook/node-logger': 6.2.9
+      babel-loader: 8.2.3_@babel+core@7.17.2
+      core-js: 3.26.0
+      regenerator-runtime: 0.13.9
+      ts-dedent: 2.2.0
+    transitivePeerDependencies:
+      - '@storybook/angular'
+      - '@storybook/builder-webpack5'
+      - '@storybook/vue3'
+      - '@types/react'
+      - bluebird
+      - encoding
+      - eslint
+      - supports-color
+      - svelte
+      - sveltedoc-parser
+      - typescript
+      - vue
+      - vue-template-compiler
+      - webpack-cli
+      - webpack-command
     dev: true
 
-  /acorn/8.7.0:
-    resolution: {integrity: 
sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==}
-    engines: {node: '>=0.4.0'}
-    hasBin: true
+  /@storybook/addon-essentials/6.5.13_t6isvk4c5wetct53pn5ufojx2u:
+    resolution: {integrity: 
sha512-G9FVAWV7ixjVLWeLgIX+VT90tcAk6yQxfZQegfg5ucRilGysJCDaNnoab4xuuvm1R40TfFhba3iAGZtQYsddmw==}
+    peerDependencies:
+      '@babel/core': ^7.9.6
+      '@storybook/angular': '*'
+      '@storybook/builder-manager4': '*'
+      '@storybook/builder-manager5': '*'
+      '@storybook/builder-webpack4': '*'
+      '@storybook/builder-webpack5': '*'
+      '@storybook/html': '*'
+      '@storybook/vue': '*'
+      '@storybook/vue3': '*'
+      '@storybook/web-components': '*'
+      lit: '*'
+      lit-html: '*'
+      react: '*'
+      react-dom: '*'
+      svelte: '*'
+      sveltedoc-parser: '*'
+      vue: '*'
+      webpack: '*'
+    peerDependenciesMeta:
+      '@storybook/angular':
+        optional: true
+      '@storybook/builder-manager4':
+        optional: true
+      '@storybook/builder-manager5':
+        optional: true
+      '@storybook/builder-webpack4':
+        optional: true
+      '@storybook/builder-webpack5':
+        optional: true
+      '@storybook/html':
+        optional: true
+      '@storybook/vue':
+        optional: true
+      '@storybook/vue3':
+        optional: true
+      '@storybook/web-components':
+        optional: true
+      lit:
+        optional: true
+      lit-html:
+        optional: true
+      react:
+        optional: true
+      react-dom:
+        optional: true
+      svelte:
+        optional: true
+      sveltedoc-parser:
+        optional: true
+      vue:
+        optional: true
+      webpack:
+        optional: true
+    dependencies:
+      '@babel/core': 7.17.2
+      '@storybook/addon-actions': 6.5.13
+      '@storybook/addon-backgrounds': 6.5.13
+      '@storybook/addon-controls': 6.5.13_3rubbgt5ekhqrcgx4uwls3neim
+      '@storybook/addon-docs': 6.5.13_t6isvk4c5wetct53pn5ufojx2u
+      '@storybook/addon-measure': 6.5.13
+      '@storybook/addon-outline': 6.5.13
+      '@storybook/addon-toolbars': 6.5.13
+      '@storybook/addon-viewport': 6.5.13
+      '@storybook/addons': 6.5.13
+      '@storybook/api': 6.5.13
+      '@storybook/core-common': 6.5.13_3rubbgt5ekhqrcgx4uwls3neim
+      '@storybook/node-logger': 6.5.13
+      core-js: 3.26.0
+      regenerator-runtime: 0.13.9
+      ts-dedent: 2.2.0
+    transitivePeerDependencies:
+      - '@storybook/mdx2-csf'
+      - eslint
+      - supports-color
+      - typescript
+      - vue-template-compiler
+      - webpack-cli
+      - webpack-command
     dev: true
 
-  /acorn/8.8.0:
-    resolution: {integrity: 
sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==}
-    engines: {node: '>=0.4.0'}
-    hasBin: true
+  /@storybook/addon-links/6.2.9:
+    resolution: {integrity: 
sha512-pBiL6EUZI3c9qtCqnGx3RXF46kAxGMdo4xDC2y3mM132W//DzxkzLZRe4ZhxxGwaLzTNlNrypZ6Li6WyIaPZ/w==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+    peerDependenciesMeta:
+      react:
+        optional: true
+      react-dom:
+        optional: true
+    dependencies:
+      '@storybook/addons': 6.2.9
+      '@storybook/client-logger': 6.2.9
+      '@storybook/core-events': 6.2.9
+      '@storybook/csf': 0.0.1
+      '@storybook/router': 6.2.9
+      '@types/qs': 6.9.7
+      core-js: 3.26.0
+      global: 4.4.0
+      prop-types: 15.8.1
+      qs: 6.11.0
+      regenerator-runtime: 0.13.9
+      ts-dedent: 2.2.0
     dev: true
 
-  /aggregate-error/3.1.0:
-    resolution: {integrity: 
sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==}
-    engines: {node: '>=8'}
+  /@storybook/addon-links/6.5.13:
+    resolution: {integrity: 
sha512-K/LYYu9R/Xoah5h9MNh4mSHOic3q5csqjderLqr2YW/KPYiuNubgvzEbAAbzI5xq5JrtAZqnINrZUv2A4CyYbQ==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    peerDependenciesMeta:
+      react:
+        optional: true
+      react-dom:
+        optional: true
     dependencies:
-      clean-stack: 2.2.0
-      indent-string: 4.0.0
+      '@storybook/addons': 6.5.13
+      '@storybook/client-logger': 6.5.13
+      '@storybook/core-events': 6.5.13
+      '@storybook/csf': 0.0.2--canary.4566f4d.1
+      '@storybook/router': 6.5.13
+      '@types/qs': 6.9.7
+      core-js: 3.26.0
+      global: 4.4.0
+      prop-types: 15.8.1
+      qs: 6.11.0
+      regenerator-runtime: 0.13.9
+      ts-dedent: 2.2.0
     dev: true
 
-  /aggregate-error/4.0.1:
-    resolution: {integrity: 
sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==}
-    engines: {node: '>=12'}
+  /@storybook/addon-measure/6.5.13:
+    resolution: {integrity: 
sha512-pi5RFB9YTnESRFtYHAVRUrgEI5to0TFc4KndtwcCKt1fMJ8OFjXQeznEfdj95PFeUvW5TNUwjL38vK4LhicB+g==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    peerDependenciesMeta:
+      react:
+        optional: true
+      react-dom:
+        optional: true
     dependencies:
-      clean-stack: 4.2.0
-      indent-string: 5.0.0
+      '@storybook/addons': 6.5.13
+      '@storybook/api': 6.5.13
+      '@storybook/client-logger': 6.5.13
+      '@storybook/components': 6.5.13
+      '@storybook/core-events': 6.5.13
+      '@storybook/csf': 0.0.2--canary.4566f4d.1
+      core-js: 3.26.0
+      global: 4.4.0
     dev: true
 
-  /ajv-errors/1.0.1_ajv@6.12.6:
-    resolution: {integrity: 
sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==}
+  /@storybook/addon-outline/6.5.13:
+    resolution: {integrity: 
sha512-8d8taPheO/tryflzXbj2QRuxHOIS8CtzRzcaglCcioqHEMhOIDOx9BdXKdheq54gdk/UN94HdGJUoVxYyXwZ4Q==}
     peerDependencies:
-      ajv: '>=5.0.0'
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    peerDependenciesMeta:
+      react:
+        optional: true
+      react-dom:
+        optional: true
     dependencies:
-      ajv: 6.12.6
+      '@storybook/addons': 6.5.13
+      '@storybook/api': 6.5.13
+      '@storybook/client-logger': 6.5.13
+      '@storybook/components': 6.5.13
+      '@storybook/core-events': 6.5.13
+      '@storybook/csf': 0.0.2--canary.4566f4d.1
+      core-js: 3.26.0
+      global: 4.4.0
+      regenerator-runtime: 0.13.9
+      ts-dedent: 2.2.0
     dev: true
 
-  /ajv-formats/2.1.1:
-    resolution: {integrity: 
sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==}
+  /@storybook/addon-toolbars/6.2.9:
+    resolution: {integrity: 
sha512-4WjIofN5npBPNZ8v1UhzPeATB9RnAWRH/y1AVS1HB+zl6Ku92o7aOMqVxs8zR1oSSmtkHh/rcUcpATFKjuofdw==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
     peerDependenciesMeta:
-      ajv:
+      react:
+        optional: true
+      react-dom:
         optional: true
     dependencies:
-      ajv: 8.10.0
+      '@storybook/addons': 6.2.9
+      '@storybook/api': 6.2.9
+      '@storybook/client-api': 6.2.9
+      '@storybook/components': 6.2.9
+      core-js: 3.26.0
+    transitivePeerDependencies:
+      - '@types/react'
     dev: true
 
-  /ajv-keywords/3.5.2_ajv@6.12.6:
-    resolution: {integrity: 
sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==}
+  /@storybook/addon-toolbars/6.5.13:
+    resolution: {integrity: 
sha512-Qgr4wKRSP+gY1VaN7PYT4TM1um7KY341X3GHTglXLFHd8nDsCweawfV2shaX3WxCfZmVro8g4G+Oest30kLLCw==}
     peerDependencies:
-      ajv: ^6.9.1
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    peerDependenciesMeta:
+      react:
+        optional: true
+      react-dom:
+        optional: true
     dependencies:
-      ajv: 6.12.6
+      '@storybook/addons': 6.5.13
+      '@storybook/api': 6.5.13
+      '@storybook/client-logger': 6.5.13
+      '@storybook/components': 6.5.13
+      '@storybook/theming': 6.5.13
+      core-js: 3.26.0
+      regenerator-runtime: 0.13.9
     dev: true
 
-  /ajv-keywords/5.1.0_ajv@8.10.0:
-    resolution: {integrity: 
sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==}
+  /@storybook/addon-viewport/6.2.9:
+    resolution: {integrity: 
sha512-IK2mu5njmfcAT967SJtBOY2B6NPMikySZga9QuaLdSpQxPd3vXKNMVG1CjnduMLeDaAoUlvlJISeEPbYGuE+1A==}
     peerDependencies:
-      ajv: ^8.8.2
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+    peerDependenciesMeta:
+      react:
+        optional: true
+      react-dom:
+        optional: true
     dependencies:
-      ajv: 8.10.0
-      fast-deep-equal: 3.1.3
+      '@storybook/addons': 6.2.9
+      '@storybook/api': 6.2.9
+      '@storybook/client-logger': 6.2.9
+      '@storybook/components': 6.2.9
+      '@storybook/core-events': 6.2.9
+      '@storybook/theming': 6.2.9
+      core-js: 3.26.0
+      global: 4.4.0
+      memoizerific: 1.11.3
+      prop-types: 15.8.1
+      regenerator-runtime: 0.13.9
+    transitivePeerDependencies:
+      - '@types/react'
     dev: true
 
-  /ajv/6.12.6:
-    resolution: {integrity: 
sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
+  /@storybook/addon-viewport/6.5.13:
+    resolution: {integrity: 
sha512-KSfeuCSIjncwWGnUu6cZBx8WNqYvm5gHyFvkSPKEu0+MJtgncbUy7pl53lrEEr6QmIq0GRXvS3A0XzV8RCnrSA==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    peerDependenciesMeta:
+      react:
+        optional: true
+      react-dom:
+        optional: true
     dependencies:
-      fast-deep-equal: 3.1.3
-      fast-json-stable-stringify: 2.1.0
-      json-schema-traverse: 0.4.1
-      uri-js: 4.4.1
+      '@storybook/addons': 6.5.13
+      '@storybook/api': 6.5.13
+      '@storybook/client-logger': 6.5.13
+      '@storybook/components': 6.5.13
+      '@storybook/core-events': 6.5.13
+      '@storybook/theming': 6.5.13
+      core-js: 3.26.0
+      global: 4.4.0
+      memoizerific: 1.11.3
+      prop-types: 15.8.1
+      regenerator-runtime: 0.13.9
     dev: true
 
-  /ajv/8.10.0:
-    resolution: {integrity: 
sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==}
+  /@storybook/addons/6.2.9:
+    resolution: {integrity: 
sha512-GnmEKbJwiN1jncN9NSA8CuR1i2XAlasPcl/Zn0jkfV9WitQeczVcJCPw86SGH84AD+tTBCyF2i9UC0KaOV1YBQ==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
     dependencies:
-      fast-deep-equal: 3.1.3
-      json-schema-traverse: 1.0.0
-      require-from-string: 2.0.2
-      uri-js: 4.4.1
+      '@storybook/api': 6.2.9
+      '@storybook/channels': 6.2.9
+      '@storybook/client-logger': 6.2.9
+      '@storybook/core-events': 6.2.9
+      '@storybook/router': 6.2.9
+      '@storybook/theming': 6.2.9
+      core-js: 3.26.0
+      global: 4.4.0
+      regenerator-runtime: 0.13.9
     dev: true
 
-  /alphanum-sort/1.0.2:
-    resolution: {integrity: sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=}
+  /@storybook/addons/6.2.9_wcqkhtmu7mswc6yz4uyexck3ty:
+    resolution: {integrity: 
sha512-GnmEKbJwiN1jncN9NSA8CuR1i2XAlasPcl/Zn0jkfV9WitQeczVcJCPw86SGH84AD+tTBCyF2i9UC0KaOV1YBQ==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+    dependencies:
+      '@storybook/api': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/channels': 6.2.9
+      '@storybook/client-logger': 6.2.9
+      '@storybook/core-events': 6.2.9
+      '@storybook/router': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/theming': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      core-js: 3.26.0
+      global: 4.4.0
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      regenerator-runtime: 0.13.9
     dev: true
 
-  /ansi-align/3.0.1:
-    resolution: {integrity: 
sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==}
+  /@storybook/addons/6.5.13:
+    resolution: {integrity: 
sha512-18CqzNnrGMfeZtiKz+R/3rHtSNnfNwz6y6prIQIbWseK16jY8ELTfIFGviwO5V2OqpbHDQi5+xQQ63QAIb89YA==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
     dependencies:
-      string-width: 4.2.3
+      '@storybook/api': 6.5.13
+      '@storybook/channels': 6.5.13
+      '@storybook/client-logger': 6.5.13
+      '@storybook/core-events': 6.5.13
+      '@storybook/csf': 0.0.2--canary.4566f4d.1
+      '@storybook/router': 6.5.13
+      '@storybook/theming': 6.5.13
+      '@types/webpack-env': 1.18.0
+      core-js: 3.26.0
+      global: 4.4.0
+      regenerator-runtime: 0.13.9
     dev: true
 
-  /ansi-colors/3.2.4:
-    resolution: {integrity: 
sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==}
-    engines: {node: '>=6'}
+  /@storybook/addons/6.5.13_wcqkhtmu7mswc6yz4uyexck3ty:
+    resolution: {integrity: 
sha512-18CqzNnrGMfeZtiKz+R/3rHtSNnfNwz6y6prIQIbWseK16jY8ELTfIFGviwO5V2OqpbHDQi5+xQQ63QAIb89YA==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      '@storybook/api': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/channels': 6.5.13
+      '@storybook/client-logger': 6.5.13
+      '@storybook/core-events': 6.5.13
+      '@storybook/csf': 0.0.2--canary.4566f4d.1
+      '@storybook/router': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/theming': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@types/webpack-env': 1.18.0
+      core-js: 3.26.0
+      global: 4.4.0
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      regenerator-runtime: 0.13.9
     dev: true
 
-  /ansi-colors/4.1.1:
-    resolution: {integrity: 
sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==}
-    engines: {node: '>=6'}
+  /@storybook/api/6.2.9:
+    resolution: {integrity: 
sha512-okkA3HAScE9tGnYBrjTOcgzT+L1lRHNoEh3ZfGgh1u/XNEyHGNkj4grvkd6nX7BzRcYQ/l2VkcKCqmOjUnSkVQ==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+    dependencies:
+      '@reach/router': 1.3.4
+      '@storybook/channels': 6.2.9
+      '@storybook/client-logger': 6.2.9
+      '@storybook/core-events': 6.2.9
+      '@storybook/csf': 0.0.1
+      '@storybook/router': 6.2.9
+      '@storybook/semver': 7.3.2
+      '@storybook/theming': 6.2.9
+      '@types/reach__router': 1.3.11
+      core-js: 3.26.0
+      fast-deep-equal: 3.1.3
+      global: 4.4.0
+      lodash: 4.17.21
+      memoizerific: 1.11.3
+      qs: 6.11.0
+      regenerator-runtime: 0.13.9
+      store2: 2.14.2
+      telejson: 5.3.3
+      ts-dedent: 2.2.0
+      util-deprecate: 1.0.2
     dev: true
 
-  /ansi-html-community/0.0.8:
-    resolution: {integrity: 
sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==}
-    engines: {'0': node >= 0.8.0}
-    hasBin: true
+  /@storybook/api/6.2.9_wcqkhtmu7mswc6yz4uyexck3ty:
+    resolution: {integrity: 
sha512-okkA3HAScE9tGnYBrjTOcgzT+L1lRHNoEh3ZfGgh1u/XNEyHGNkj4grvkd6nX7BzRcYQ/l2VkcKCqmOjUnSkVQ==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+    dependencies:
+      '@reach/router': 1.3.4_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/channels': 6.2.9
+      '@storybook/client-logger': 6.2.9
+      '@storybook/core-events': 6.2.9
+      '@storybook/csf': 0.0.1
+      '@storybook/router': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/semver': 7.3.2
+      '@storybook/theming': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      '@types/reach__router': 1.3.11
+      core-js: 3.26.0
+      fast-deep-equal: 3.1.3
+      global: 4.4.0
+      lodash: 4.17.21
+      memoizerific: 1.11.3
+      qs: 6.11.0
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      regenerator-runtime: 0.13.9
+      store2: 2.14.2
+      telejson: 5.3.3
+      ts-dedent: 2.2.0
+      util-deprecate: 1.0.2
     dev: true
 
-  /ansi-regex/2.1.1:
-    resolution: {integrity: sha1-w7M6te42DYbg5ijwRorn7yfWVN8=}
-    engines: {node: '>=0.10.0'}
+  /@storybook/api/6.5.13:
+    resolution: {integrity: 
sha512-xVSmB7/IuFd6G7eiJjbI2MuS7SZunoUM6d+YCWpjiehfMeX47MXt1gZtOwFrgJC1ShZlefXFahq/dvxwtmWs+w==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      '@storybook/channels': 6.5.13
+      '@storybook/client-logger': 6.5.13
+      '@storybook/core-events': 6.5.13
+      '@storybook/csf': 0.0.2--canary.4566f4d.1
+      '@storybook/router': 6.5.13
+      '@storybook/semver': 7.3.2
+      '@storybook/theming': 6.5.13
+      core-js: 3.26.0
+      fast-deep-equal: 3.1.3
+      global: 4.4.0
+      lodash: 4.17.21
+      memoizerific: 1.11.3
+      regenerator-runtime: 0.13.9
+      store2: 2.14.2
+      telejson: 6.0.8
+      ts-dedent: 2.2.0
+      util-deprecate: 1.0.2
     dev: true
 
-  /ansi-regex/5.0.1:
-    resolution: {integrity: 
sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
-    engines: {node: '>=8'}
+  /@storybook/api/6.5.13_wcqkhtmu7mswc6yz4uyexck3ty:
+    resolution: {integrity: 
sha512-xVSmB7/IuFd6G7eiJjbI2MuS7SZunoUM6d+YCWpjiehfMeX47MXt1gZtOwFrgJC1ShZlefXFahq/dvxwtmWs+w==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      '@storybook/channels': 6.5.13
+      '@storybook/client-logger': 6.5.13
+      '@storybook/core-events': 6.5.13
+      '@storybook/csf': 0.0.2--canary.4566f4d.1
+      '@storybook/router': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/semver': 7.3.2
+      '@storybook/theming': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      core-js: 3.26.0
+      fast-deep-equal: 3.1.3
+      global: 4.4.0
+      lodash: 4.17.21
+      memoizerific: 1.11.3
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      regenerator-runtime: 0.13.9
+      store2: 2.14.2
+      telejson: 6.0.8
+      ts-dedent: 2.2.0
+      util-deprecate: 1.0.2
     dev: true
 
-  /ansi-regex/6.0.1:
-    resolution: {integrity: 
sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==}
-    engines: {node: '>=12'}
-    dev: true
-
-  /ansi-styles/1.0.0:
-    resolution: {integrity: sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=}
-    engines: {node: '>=0.8.0'}
-    dev: true
-
-  /ansi-styles/3.2.1:
-    resolution: {integrity: 
sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
-    engines: {node: '>=4'}
+  /@storybook/builder-webpack4/6.2.9_g2frytwdyb7gw6koky3kitwvuu:
+    resolution: {integrity: 
sha512-swECic1huVdj+B+iRJIQ8ds59HuPVE4fmhI+j/nhw0CQCsgAEKqDlOQVYEimW6nZX8GO4WxNm6tiiRzxixejbw==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
     dependencies:
-      color-convert: 1.9.3
+      '@babel/core': 7.19.6
+      '@babel/plugin-proposal-class-properties': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-decorators': 7.17.2_@babel+core@7.19.6
+      '@babel/plugin-proposal-export-default-from': 7.18.10_@babel+core@7.19.6
+      '@babel/plugin-proposal-nullish-coalescing-operator': 
7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-object-rest-spread': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-optional-chaining': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-private-methods': 7.16.11_@babel+core@7.19.6
+      '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.19.6
+      '@babel/plugin-transform-arrow-functions': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-block-scoping': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-classes': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-destructuring': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-for-of': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-parameters': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-shorthand-properties': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-spread': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-template-literals': 7.16.7_@babel+core@7.19.6
+      '@babel/preset-env': 7.16.11_@babel+core@7.19.6
+      '@babel/preset-react': 7.18.6_@babel+core@7.19.6
+      '@babel/preset-typescript': 7.16.7_@babel+core@7.19.6
+      '@storybook/addons': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/api': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/channel-postmessage': 6.2.9
+      '@storybook/channels': 6.2.9
+      '@storybook/client-api': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/client-logger': 6.2.9
+      '@storybook/components': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/core-common': 6.2.9_g2frytwdyb7gw6koky3kitwvuu
+      '@storybook/core-events': 6.2.9
+      '@storybook/node-logger': 6.2.9
+      '@storybook/router': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/semver': 7.3.2
+      '@storybook/theming': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/ui': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      '@types/node': 14.18.32
+      '@types/webpack': 4.41.32
+      autoprefixer: 9.8.8
+      babel-loader: 8.2.3_q4ydpsrmbqywduja5orgah6fgq
+      babel-plugin-macros: 2.8.0
+      babel-plugin-polyfill-corejs3: 0.1.7_@babel+core@7.19.6
+      case-sensitive-paths-webpack-plugin: 2.4.0
+      core-js: 3.26.0
+      css-loader: 3.6.0_webpack@4.46.0
+      dotenv-webpack: 1.8.0_webpack@4.46.0
+      file-loader: 6.2.0_webpack@4.46.0
+      find-up: 5.0.0
+      fork-ts-checker-webpack-plugin: 4.1.6_ef2lra3u3fsnrdrpybbvbgzate
+      fs-extra: 9.1.0
+      glob: 7.2.3
+      glob-promise: 3.4.0_glob@7.2.3
+      global: 4.4.0
+      html-webpack-plugin: 4.5.2_webpack@4.46.0
+      pnp-webpack-plugin: 1.6.4_typescript@4.8.4
+      postcss: 7.0.39
+      postcss-flexbugs-fixes: 4.2.1
+      postcss-loader: 4.3.0_gzaxsinx64nntyd3vmdqwl7coe
+      raw-loader: 4.0.2_webpack@4.46.0
+      react: 16.14.0
+      react-dev-utils: 11.0.4_ef2lra3u3fsnrdrpybbvbgzate
+      react-dom: 16.14.0_react@16.14.0
+      stable: 0.1.8
+      style-loader: 1.3.0_webpack@4.46.0
+      terser-webpack-plugin: 3.1.0_webpack@4.46.0
+      ts-dedent: 2.2.0
+      typescript: 4.8.4
+      url-loader: 4.1.1_lit45vopotvaqup7lrvlnvtxwy
+      util-deprecate: 1.0.2
+      webpack: 4.46.0
+      webpack-dev-middleware: 3.7.3_webpack@4.46.0
+      webpack-filter-warnings-plugin: 1.2.1_webpack@4.46.0
+      webpack-hot-middleware: 2.25.2
+      webpack-virtual-modules: 0.2.2
+    transitivePeerDependencies:
+      - '@types/react'
+      - bluebird
+      - eslint
+      - supports-color
+      - vue-template-compiler
+      - webpack-cli
+      - webpack-command
     dev: true
 
-  /ansi-styles/4.3.0:
-    resolution: {integrity: 
sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
-    engines: {node: '>=8'}
+  /@storybook/builder-webpack4/6.2.9_o2nrgn6wwxunlqlzzokx4es3q4:
+    resolution: {integrity: 
sha512-swECic1huVdj+B+iRJIQ8ds59HuPVE4fmhI+j/nhw0CQCsgAEKqDlOQVYEimW6nZX8GO4WxNm6tiiRzxixejbw==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
     dependencies:
-      color-convert: 2.0.1
-    dev: true
-
-  /ansi-styles/6.2.1:
-    resolution: {integrity: 
sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
-    engines: {node: '>=12'}
+      '@babel/core': 7.19.6
+      '@babel/plugin-proposal-class-properties': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-decorators': 7.17.2_@babel+core@7.19.6
+      '@babel/plugin-proposal-export-default-from': 7.18.10_@babel+core@7.19.6
+      '@babel/plugin-proposal-nullish-coalescing-operator': 
7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-object-rest-spread': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-optional-chaining': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-private-methods': 7.16.11_@babel+core@7.19.6
+      '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.19.6
+      '@babel/plugin-transform-arrow-functions': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-block-scoping': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-classes': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-destructuring': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-for-of': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-parameters': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-shorthand-properties': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-spread': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-template-literals': 7.16.7_@babel+core@7.19.6
+      '@babel/preset-env': 7.16.11_@babel+core@7.19.6
+      '@babel/preset-react': 7.18.6_@babel+core@7.19.6
+      '@babel/preset-typescript': 7.16.7_@babel+core@7.19.6
+      '@storybook/addons': 6.2.9
+      '@storybook/api': 6.2.9
+      '@storybook/channel-postmessage': 6.2.9
+      '@storybook/channels': 6.2.9
+      '@storybook/client-api': 6.2.9
+      '@storybook/client-logger': 6.2.9
+      '@storybook/components': 6.2.9
+      '@storybook/core-common': 6.2.9_o2nrgn6wwxunlqlzzokx4es3q4
+      '@storybook/core-events': 6.2.9
+      '@storybook/node-logger': 6.2.9
+      '@storybook/router': 6.2.9
+      '@storybook/semver': 7.3.2
+      '@storybook/theming': 6.2.9
+      '@storybook/ui': 6.2.9
+      '@types/node': 14.18.32
+      '@types/webpack': 4.41.32
+      autoprefixer: 9.8.8
+      babel-loader: 8.2.3_q4ydpsrmbqywduja5orgah6fgq
+      babel-plugin-macros: 2.8.0
+      babel-plugin-polyfill-corejs3: 0.1.7_@babel+core@7.19.6
+      case-sensitive-paths-webpack-plugin: 2.4.0
+      core-js: 3.26.0
+      css-loader: 3.6.0_webpack@4.46.0
+      dotenv-webpack: 1.8.0_webpack@4.46.0
+      file-loader: 6.2.0_webpack@4.46.0
+      find-up: 5.0.0
+      fork-ts-checker-webpack-plugin: 4.1.6_ef2lra3u3fsnrdrpybbvbgzate
+      fs-extra: 9.1.0
+      glob: 7.2.3
+      glob-promise: 3.4.0_glob@7.2.3
+      global: 4.4.0
+      html-webpack-plugin: 4.5.2_webpack@4.46.0
+      pnp-webpack-plugin: 1.6.4_typescript@4.8.4
+      postcss: 7.0.39
+      postcss-flexbugs-fixes: 4.2.1
+      postcss-loader: 4.3.0_gzaxsinx64nntyd3vmdqwl7coe
+      raw-loader: 4.0.2_webpack@4.46.0
+      react-dev-utils: 11.0.4_ef2lra3u3fsnrdrpybbvbgzate
+      stable: 0.1.8
+      style-loader: 1.3.0_webpack@4.46.0
+      terser-webpack-plugin: 3.1.0_webpack@4.46.0
+      ts-dedent: 2.2.0
+      typescript: 4.8.4
+      url-loader: 4.1.1_lit45vopotvaqup7lrvlnvtxwy
+      util-deprecate: 1.0.2
+      webpack: 4.46.0
+      webpack-dev-middleware: 3.7.3_webpack@4.46.0
+      webpack-filter-warnings-plugin: 1.2.1_webpack@4.46.0
+      webpack-hot-middleware: 2.25.2
+      webpack-virtual-modules: 0.2.2
+    transitivePeerDependencies:
+      - '@types/react'
+      - bluebird
+      - eslint
+      - supports-color
+      - vue-template-compiler
+      - webpack-cli
+      - webpack-command
     dev: true
 
-  /anymatch/2.0.0:
-    resolution: {integrity: 
sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==}
+  /@storybook/builder-webpack4/6.5.13_u5cwnb36e3nipolzgtjnnpepdu:
+    resolution: {integrity: 
sha512-Agqy3IKPv3Nl8QqdS7PjtqLp+c0BD8+/3A2ki/YfKqVz+F+J34EpbZlh3uU053avm1EoNQHSmhZok3ZlWH6O7A==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
     dependencies:
-      micromatch: 3.1.10
-      normalize-path: 2.1.1
+      '@babel/core': 7.19.6
+      '@storybook/addons': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/api': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/channel-postmessage': 6.5.13
+      '@storybook/channels': 6.5.13
+      '@storybook/client-api': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/client-logger': 6.5.13
+      '@storybook/components': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/core-common': 6.5.13_u5cwnb36e3nipolzgtjnnpepdu
+      '@storybook/core-events': 6.5.13
+      '@storybook/node-logger': 6.5.13
+      '@storybook/preview-web': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/router': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/semver': 7.3.2
+      '@storybook/store': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/theming': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/ui': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@types/node': 16.18.0
+      '@types/webpack': 4.41.32
+      autoprefixer: 9.8.8
+      babel-loader: 8.2.3_q4ydpsrmbqywduja5orgah6fgq
+      case-sensitive-paths-webpack-plugin: 2.4.0
+      core-js: 3.26.0
+      css-loader: 3.6.0_webpack@4.46.0
+      file-loader: 6.2.0_webpack@4.46.0
+      find-up: 5.0.0
+      fork-ts-checker-webpack-plugin: 4.1.6_3n2x3j6farblcaf52bherr6og4
+      glob: 7.2.3
+      glob-promise: 3.4.0_glob@7.2.3
+      global: 4.4.0
+      html-webpack-plugin: 4.5.2_webpack@4.46.0
+      pnp-webpack-plugin: 1.6.4_typescript@4.8.4
+      postcss: 7.0.39
+      postcss-flexbugs-fixes: 4.2.1
+      postcss-loader: 4.3.0_gzaxsinx64nntyd3vmdqwl7coe
+      raw-loader: 4.0.2_webpack@4.46.0
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      stable: 0.1.8
+      style-loader: 1.3.0_webpack@4.46.0
+      terser-webpack-plugin: 4.2.3_webpack@4.46.0
+      ts-dedent: 2.2.0
+      typescript: 4.8.4
+      url-loader: 4.1.1_lit45vopotvaqup7lrvlnvtxwy
+      util-deprecate: 1.0.2
+      webpack: 4.46.0
+      webpack-dev-middleware: 3.7.3_webpack@4.46.0
+      webpack-filter-warnings-plugin: 1.2.1_webpack@4.46.0
+      webpack-hot-middleware: 2.25.2
+      webpack-virtual-modules: 0.2.2
     transitivePeerDependencies:
+      - bluebird
+      - eslint
       - supports-color
+      - vue-template-compiler
+      - webpack-cli
+      - webpack-command
     dev: true
-    optional: true
 
-  /anymatch/3.1.2:
-    resolution: {integrity: 
sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==}
-    engines: {node: '>= 8'}
+  /@storybook/channel-postmessage/6.2.9:
+    resolution: {integrity: 
sha512-OqV+gLeeCHR0KExsIz0B7gD17Cjd9D+I75qnBsLWM9inWO5kc/WZ5svw8Bvjlcm6snWpvxUaT8L+svuqcPSmww==}
     dependencies:
-      normalize-path: 3.0.0
-      picomatch: 2.3.1
+      '@storybook/channels': 6.2.9
+      '@storybook/client-logger': 6.2.9
+      '@storybook/core-events': 6.2.9
+      core-js: 3.26.0
+      global: 4.4.0
+      qs: 6.11.0
+      telejson: 5.3.3
     dev: true
 
-  /append-transform/2.0.0:
-    resolution: {integrity: 
sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==}
-    engines: {node: '>=8'}
+  /@storybook/channel-postmessage/6.5.13:
+    resolution: {integrity: 
sha512-R79MBs0mQ7TV8M/a6x/SiTRyvZBidDfMEEthG7Cyo9p35JYiKOhj2535zhW4qlVMESBu95pwKYBibTjASoStPw==}
     dependencies:
-      default-require-extensions: 3.0.0
+      '@storybook/channels': 6.5.13
+      '@storybook/client-logger': 6.5.13
+      '@storybook/core-events': 6.5.13
+      core-js: 3.26.0
+      global: 4.4.0
+      qs: 6.11.0
+      telejson: 6.0.8
     dev: true
 
-  /aproba/1.2.0:
-    resolution: {integrity: 
sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==}
+  /@storybook/channel-websocket/6.5.13:
+    resolution: {integrity: 
sha512-kwh667H+tzCiNvs92GNwYOwVXdj9uHZyieRAN5rJtTBJ7XgLzGkpTEU50mWlbc0nDKhgE0qYvzyr5H393Iy5ug==}
+    dependencies:
+      '@storybook/channels': 6.5.13
+      '@storybook/client-logger': 6.5.13
+      core-js: 3.26.0
+      global: 4.4.0
+      telejson: 6.0.8
     dev: true
 
-  /archy/1.0.0:
-    resolution: {integrity: sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=}
+  /@storybook/channels/6.2.9:
+    resolution: {integrity: 
sha512-6dC8Fb2ipNyOQXnUZMDeEUaJGH5DMLzyHlGLhVyDtrO5WR6bO8mQdkzf4+5dSKXgCBNX0BSkssXth4pDjn18rg==}
+    dependencies:
+      core-js: 3.26.0
+      ts-dedent: 2.2.0
+      util-deprecate: 1.0.2
     dev: true
 
-  /argparse/1.0.10:
-    resolution: {integrity: 
sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
+  /@storybook/channels/6.5.13:
+    resolution: {integrity: 
sha512-sGYSilE30bz0jG+HdHnkv0B4XkAv2hP+KRZr4xmnv+MOOQpRnZpJ5Z3HVU16s17cj/83NWihKj6BuKcEVzyilg==}
     dependencies:
-      sprintf-js: 1.0.3
+      core-js: 3.26.0
+      ts-dedent: 2.2.0
+      util-deprecate: 1.0.2
     dev: true
 
-  /argparse/2.0.1:
-    resolution: {integrity: 
sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+  /@storybook/client-api/6.2.9:
+    resolution: {integrity: 
sha512-aLvEUVkbvv6Qo/2mF4rFCecdqi2CGOUDdsV1a6EFIVS/9gXFdpirsOwKHo9qNjacGdWPlBYGCUcbrw+DvNaSFA==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+    dependencies:
+      '@storybook/addons': 6.2.9
+      '@storybook/channel-postmessage': 6.2.9
+      '@storybook/channels': 6.2.9
+      '@storybook/client-logger': 6.2.9
+      '@storybook/core-events': 6.2.9
+      '@storybook/csf': 0.0.1
+      '@types/qs': 6.9.7
+      '@types/webpack-env': 1.18.0
+      core-js: 3.26.0
+      global: 4.4.0
+      lodash: 4.17.21
+      memoizerific: 1.11.3
+      qs: 6.11.0
+      regenerator-runtime: 0.13.9
+      stable: 0.1.8
+      store2: 2.14.2
+      ts-dedent: 2.2.0
+      util-deprecate: 1.0.2
     dev: true
 
-  /aria-query/4.2.2:
-    resolution: {integrity: 
sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==}
-    engines: {node: '>=6.0'}
+  /@storybook/client-api/6.2.9_wcqkhtmu7mswc6yz4uyexck3ty:
+    resolution: {integrity: 
sha512-aLvEUVkbvv6Qo/2mF4rFCecdqi2CGOUDdsV1a6EFIVS/9gXFdpirsOwKHo9qNjacGdWPlBYGCUcbrw+DvNaSFA==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
     dependencies:
-      '@babel/runtime': 7.16.7
-      '@babel/runtime-corejs3': 7.16.7
+      '@storybook/addons': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/channel-postmessage': 6.2.9
+      '@storybook/channels': 6.2.9
+      '@storybook/client-logger': 6.2.9
+      '@storybook/core-events': 6.2.9
+      '@storybook/csf': 0.0.1
+      '@types/qs': 6.9.7
+      '@types/webpack-env': 1.18.0
+      core-js: 3.26.0
+      global: 4.4.0
+      lodash: 4.17.21
+      memoizerific: 1.11.3
+      qs: 6.11.0
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      regenerator-runtime: 0.13.9
+      stable: 0.1.8
+      store2: 2.14.2
+      ts-dedent: 2.2.0
+      util-deprecate: 1.0.2
     dev: true
 
-  /arr-diff/4.0.0:
-    resolution: {integrity: sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=}
-    engines: {node: '>=0.10.0'}
+  /@storybook/client-api/6.5.13_wcqkhtmu7mswc6yz4uyexck3ty:
+    resolution: {integrity: 
sha512-uH1mAWbidPiuuTdMUVEiuaNOfrYXm+9QLSP1MMYTKULqEOZI5MSOGkEDqRfVWxbYv/iWBOPTQ+OM9TQ6ecYacg==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      '@storybook/addons': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/channel-postmessage': 6.5.13
+      '@storybook/channels': 6.5.13
+      '@storybook/client-logger': 6.5.13
+      '@storybook/core-events': 6.5.13
+      '@storybook/csf': 0.0.2--canary.4566f4d.1
+      '@storybook/store': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@types/qs': 6.9.7
+      '@types/webpack-env': 1.18.0
+      core-js: 3.26.0
+      fast-deep-equal: 3.1.3
+      global: 4.4.0
+      lodash: 4.17.21
+      memoizerific: 1.11.3
+      qs: 6.11.0
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      regenerator-runtime: 0.13.9
+      store2: 2.14.2
+      synchronous-promise: 2.0.16
+      ts-dedent: 2.2.0
+      util-deprecate: 1.0.2
     dev: true
 
-  /arr-flatten/1.1.0:
-    resolution: {integrity: 
sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==}
-    engines: {node: '>=0.10.0'}
+  /@storybook/client-logger/6.2.9:
+    resolution: {integrity: 
sha512-IfOQZuvpjh66qBInQCJOb9S0dTGpzZ/Cxlcvokp+PYt95KztaWN3mPm+HaDQCeRsrWNe0Bpm1zuickcJ6dBOXg==}
+    dependencies:
+      core-js: 3.26.0
+      global: 4.4.0
     dev: true
 
-  /arr-union/3.1.0:
-    resolution: {integrity: sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=}
-    engines: {node: '>=0.10.0'}
+  /@storybook/client-logger/6.5.13:
+    resolution: {integrity: 
sha512-F2SMW3LWFGXLm2ENTwTitrLWJgmMXRf3CWQXdN2EbkNCIBHy5Zcbt+91K4OX8e2e5h9gjGfrdYbyYDYOoUCEfA==}
+    dependencies:
+      core-js: 3.26.0
+      global: 4.4.0
     dev: true
 
-  /array-equal/1.0.0:
-    resolution: {integrity: sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=}
+  /@storybook/components/6.2.9:
+    resolution: {integrity: 
sha512-hnV1MI2aB2g1sJ7NJphpxi7TwrMZQ/tpCJeHnkjmzyC6ez1MXqcBXGrEEdSXzRfAxjQTOEpu6H1mnns0xMP0Ag==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+    dependencies:
+      '@popperjs/core': 2.11.6
+      '@storybook/client-logger': 6.2.9
+      '@storybook/csf': 0.0.1
+      '@storybook/theming': 6.2.9
+      '@types/color-convert': 2.0.0
+      '@types/overlayscrollbars': 1.12.1
+      '@types/react-syntax-highlighter': 11.0.5
+      color-convert: 2.0.1
+      core-js: 3.26.0
+      fast-deep-equal: 3.1.3
+      global: 4.4.0
+      lodash: 4.17.21
+      markdown-to-jsx: 7.1.7
+      memoizerific: 1.11.3
+      overlayscrollbars: 1.13.3
+      polished: 4.2.2
+      prop-types: 15.8.1
+      react-colorful: 5.6.1
+      react-popper-tooltip: 3.1.1
+      react-syntax-highlighter: 13.5.3
+      react-textarea-autosize: 8.3.4
+      regenerator-runtime: 0.13.9
+      ts-dedent: 2.2.0
+      util-deprecate: 1.0.2
+    transitivePeerDependencies:
+      - '@types/react'
     dev: true
 
-  /array-find-index/1.0.2:
-    resolution: {integrity: 
sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==}
-    engines: {node: '>=0.10.0'}
+  /@storybook/components/6.2.9_wcqkhtmu7mswc6yz4uyexck3ty:
+    resolution: {integrity: 
sha512-hnV1MI2aB2g1sJ7NJphpxi7TwrMZQ/tpCJeHnkjmzyC6ez1MXqcBXGrEEdSXzRfAxjQTOEpu6H1mnns0xMP0Ag==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+    dependencies:
+      '@popperjs/core': 2.11.6
+      '@storybook/client-logger': 6.2.9
+      '@storybook/csf': 0.0.1
+      '@storybook/theming': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      '@types/color-convert': 2.0.0
+      '@types/overlayscrollbars': 1.12.1
+      '@types/react-syntax-highlighter': 11.0.5
+      color-convert: 2.0.1
+      core-js: 3.26.0
+      fast-deep-equal: 3.1.3
+      global: 4.4.0
+      lodash: 4.17.21
+      markdown-to-jsx: 7.1.7_react@16.14.0
+      memoizerific: 1.11.3
+      overlayscrollbars: 1.13.3
+      polished: 4.2.2
+      prop-types: 15.8.1
+      react: 16.14.0
+      react-colorful: 5.6.1_wcqkhtmu7mswc6yz4uyexck3ty
+      react-dom: 16.14.0_react@16.14.0
+      react-popper-tooltip: 3.1.1_wcqkhtmu7mswc6yz4uyexck3ty
+      react-syntax-highlighter: 13.5.3_react@16.14.0
+      react-textarea-autosize: 8.3.4_react@16.14.0
+      regenerator-runtime: 0.13.9
+      ts-dedent: 2.2.0
+      util-deprecate: 1.0.2
+    transitivePeerDependencies:
+      - '@types/react'
     dev: true
 
-  /array-flatten/1.1.1:
-    resolution: {integrity: sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=}
+  /@storybook/components/6.5.13:
+    resolution: {integrity: 
sha512-6Hhx70JK5pGfKCkqMU4yq/BBH+vRTmzj7tZKfPwba+f8VmTMoOr/2ysTQFRtXryiHB6Z15xBYgfq5x2pIwQzLQ==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      '@storybook/client-logger': 6.5.13
+      '@storybook/csf': 0.0.2--canary.4566f4d.1
+      '@storybook/theming': 6.5.13
+      core-js: 3.26.0
+      memoizerific: 1.11.3
+      qs: 6.11.0
+      regenerator-runtime: 0.13.9
+      util-deprecate: 1.0.2
     dev: true
 
-  /array-flatten/2.1.2:
-    resolution: {integrity: 
sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==}
+  /@storybook/components/6.5.13_wcqkhtmu7mswc6yz4uyexck3ty:
+    resolution: {integrity: 
sha512-6Hhx70JK5pGfKCkqMU4yq/BBH+vRTmzj7tZKfPwba+f8VmTMoOr/2ysTQFRtXryiHB6Z15xBYgfq5x2pIwQzLQ==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      '@storybook/client-logger': 6.5.13
+      '@storybook/csf': 0.0.2--canary.4566f4d.1
+      '@storybook/theming': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      core-js: 3.26.0
+      memoizerific: 1.11.3
+      qs: 6.11.0
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      regenerator-runtime: 0.13.9
+      util-deprecate: 1.0.2
     dev: true
 
-  /array-includes/3.1.4:
-    resolution: {integrity: 
sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==}
-    engines: {node: '>= 0.4'}
+  /@storybook/core-client/6.2.9_lasgyenclx45ngbljrbo537mpe:
+    resolution: {integrity: 
sha512-jW841J5lCe1Ub5ZMtzYPgCy/OUddFxxVYeHLZyuNxlH5RoiQQxbDpuFlzuZMYGuIzD6eZw+ANE4w5vW/y5oBfA==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+      typescript: '*'
+      webpack: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
     dependencies:
-      call-bind: 1.0.2
-      define-properties: 1.1.3
-      es-abstract: 1.19.1
-      get-intrinsic: 1.1.1
-      is-string: 1.0.7
+      '@storybook/addons': 6.2.9
+      '@storybook/channel-postmessage': 6.2.9
+      '@storybook/client-api': 6.2.9
+      '@storybook/client-logger': 6.2.9
+      '@storybook/core-events': 6.2.9
+      '@storybook/csf': 0.0.1
+      '@storybook/ui': 6.2.9
+      ansi-to-html: 0.6.15
+      core-js: 3.26.0
+      global: 4.4.0
+      lodash: 4.17.21
+      qs: 6.11.0
+      regenerator-runtime: 0.13.9
+      ts-dedent: 2.2.0
+      typescript: 4.8.4
+      unfetch: 4.2.0
+      util-deprecate: 1.0.2
+      webpack: 4.46.0
+    transitivePeerDependencies:
+      - '@types/react'
     dev: true
 
-  /array-union/2.1.0:
-    resolution: {integrity: 
sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
-    engines: {node: '>=8'}
+  /@storybook/core-client/6.2.9_typescript@4.8.4:
+    resolution: {integrity: 
sha512-jW841J5lCe1Ub5ZMtzYPgCy/OUddFxxVYeHLZyuNxlH5RoiQQxbDpuFlzuZMYGuIzD6eZw+ANE4w5vW/y5oBfA==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+      typescript: '*'
+      webpack: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+    dependencies:
+      '@storybook/addons': 6.2.9
+      '@storybook/channel-postmessage': 6.2.9
+      '@storybook/client-api': 6.2.9
+      '@storybook/client-logger': 6.2.9
+      '@storybook/core-events': 6.2.9
+      '@storybook/csf': 0.0.1
+      '@storybook/ui': 6.2.9
+      ansi-to-html: 0.6.15
+      core-js: 3.26.0
+      global: 4.4.0
+      lodash: 4.17.21
+      qs: 6.11.0
+      regenerator-runtime: 0.13.9
+      ts-dedent: 2.2.0
+      typescript: 4.8.4
+      unfetch: 4.2.0
+      util-deprecate: 1.0.2
+    transitivePeerDependencies:
+      - '@types/react'
     dev: true
 
-  /array-unique/0.3.2:
-    resolution: {integrity: sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=}
-    engines: {node: '>=0.10.0'}
+  /@storybook/core-client/6.2.9_vvswzvegta47ikremfl73qk64u:
+    resolution: {integrity: 
sha512-jW841J5lCe1Ub5ZMtzYPgCy/OUddFxxVYeHLZyuNxlH5RoiQQxbDpuFlzuZMYGuIzD6eZw+ANE4w5vW/y5oBfA==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+      typescript: '*'
+      webpack: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+    dependencies:
+      '@storybook/addons': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/channel-postmessage': 6.2.9
+      '@storybook/client-api': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/client-logger': 6.2.9
+      '@storybook/core-events': 6.2.9
+      '@storybook/csf': 0.0.1
+      '@storybook/ui': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      ansi-to-html: 0.6.15
+      core-js: 3.26.0
+      global: 4.4.0
+      lodash: 4.17.21
+      qs: 6.11.0
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      regenerator-runtime: 0.13.9
+      ts-dedent: 2.2.0
+      typescript: 4.8.4
+      unfetch: 4.2.0
+      util-deprecate: 1.0.2
+      webpack: 4.46.0
+    transitivePeerDependencies:
+      - '@types/react'
     dev: true
 
-  /array.prototype.flat/1.2.5:
-    resolution: {integrity: 
sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==}
-    engines: {node: '>= 0.4'}
+  /@storybook/core-client/6.2.9_zvdcumho7mqj3lfknr2wnpofbm:
+    resolution: {integrity: 
sha512-jW841J5lCe1Ub5ZMtzYPgCy/OUddFxxVYeHLZyuNxlH5RoiQQxbDpuFlzuZMYGuIzD6eZw+ANE4w5vW/y5oBfA==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+      typescript: '*'
+      webpack: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
     dependencies:
-      call-bind: 1.0.2
-      define-properties: 1.1.3
-      es-abstract: 1.19.1
+      '@storybook/addons': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/channel-postmessage': 6.2.9
+      '@storybook/client-api': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/client-logger': 6.2.9
+      '@storybook/core-events': 6.2.9
+      '@storybook/csf': 0.0.1
+      '@storybook/ui': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      ansi-to-html: 0.6.15
+      core-js: 3.26.0
+      global: 4.4.0
+      lodash: 4.17.21
+      qs: 6.11.0
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      regenerator-runtime: 0.13.9
+      ts-dedent: 2.2.0
+      typescript: 4.8.4
+      unfetch: 4.2.0
+      util-deprecate: 1.0.2
+    transitivePeerDependencies:
+      - '@types/react'
     dev: true
 
-  /array.prototype.flatmap/1.2.5:
+  /@storybook/core-client/6.5.13_vvswzvegta47ikremfl73qk64u:
+    resolution: {integrity: 
sha512-YuELbRokTBdqjbx/R4/7O4rou9kvbBIOJjlUkor9hdLLuJ3P0yGianERGNkZFfvcfMBAxU0p52o7QvDldSR3kA==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+      typescript: '*'
+      webpack: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+    dependencies:
+      '@storybook/addons': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/channel-postmessage': 6.5.13
+      '@storybook/channel-websocket': 6.5.13
+      '@storybook/client-api': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/client-logger': 6.5.13
+      '@storybook/core-events': 6.5.13
+      '@storybook/csf': 0.0.2--canary.4566f4d.1
+      '@storybook/preview-web': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/store': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/ui': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      airbnb-js-shims: 2.2.1
+      ansi-to-html: 0.6.15
+      core-js: 3.26.0
+      global: 4.4.0
+      lodash: 4.17.21
+      qs: 6.11.0
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      regenerator-runtime: 0.13.9
+      ts-dedent: 2.2.0
+      typescript: 4.8.4
+      unfetch: 4.2.0
+      util-deprecate: 1.0.2
+      webpack: 4.46.0
+    dev: true
+
+  /@storybook/core-common/6.2.9_g2frytwdyb7gw6koky3kitwvuu:
+    resolution: {integrity: 
sha512-ve0Qb4EMit8jGibfZBprmaU2i4LtpB4vSMIzD9nB1YeBmw2cGhHubtmayZ0TwcV3fPQhtYH9wwRWuWyzzHyQyw==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/plugin-proposal-class-properties': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-proposal-decorators': 7.17.2_@babel+core@7.17.2
+      '@babel/plugin-proposal-export-default-from': 7.18.10_@babel+core@7.17.2
+      '@babel/plugin-proposal-nullish-coalescing-operator': 
7.16.7_@babel+core@7.17.2
+      '@babel/plugin-proposal-object-rest-spread': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-proposal-optional-chaining': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-proposal-private-methods': 7.16.11_@babel+core@7.17.2
+      '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.17.2
+      '@babel/plugin-transform-arrow-functions': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-transform-block-scoping': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-transform-classes': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-transform-destructuring': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-transform-for-of': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-transform-parameters': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-transform-shorthand-properties': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-transform-spread': 7.16.7_@babel+core@7.17.2
+      '@babel/preset-env': 7.16.11_@babel+core@7.17.2
+      '@babel/preset-react': 7.18.6_@babel+core@7.17.2
+      '@babel/preset-typescript': 7.16.7_@babel+core@7.17.2
+      '@babel/register': 7.18.9_@babel+core@7.17.2
+      '@storybook/node-logger': 6.2.9
+      '@storybook/semver': 7.3.2
+      '@types/glob-base': 0.3.0
+      '@types/micromatch': 4.0.2
+      '@types/node': 14.18.32
+      '@types/pretty-hrtime': 1.0.1
+      babel-loader: 8.2.3_mc362qep5qjjhwk7q3m45kuizi
+      babel-plugin-macros: 3.1.0
+      babel-plugin-polyfill-corejs3: 0.1.7_@babel+core@7.17.2
+      chalk: 4.1.2
+      core-js: 3.26.0
+      express: 4.17.2
+      file-system-cache: 1.1.0
+      find-up: 5.0.0
+      fork-ts-checker-webpack-plugin: 6.5.2_ef2lra3u3fsnrdrpybbvbgzate
+      glob: 7.2.3
+      glob-base: 0.3.0
+      interpret: 2.2.0
+      json5: 2.2.0
+      lazy-universal-dotenv: 3.0.1
+      micromatch: 4.0.5
+      pkg-dir: 5.0.0
+      pretty-hrtime: 1.0.3
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      resolve-from: 5.0.0
+      ts-dedent: 2.2.0
+      typescript: 4.8.4
+      util-deprecate: 1.0.2
+      webpack: 4.46.0
+    transitivePeerDependencies:
+      - eslint
+      - supports-color
+      - vue-template-compiler
+      - webpack-cli
+      - webpack-command
+    dev: true
+
+  /@storybook/core-common/6.2.9_o2nrgn6wwxunlqlzzokx4es3q4:
+    resolution: {integrity: 
sha512-ve0Qb4EMit8jGibfZBprmaU2i4LtpB4vSMIzD9nB1YeBmw2cGhHubtmayZ0TwcV3fPQhtYH9wwRWuWyzzHyQyw==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/plugin-proposal-class-properties': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-proposal-decorators': 7.17.2_@babel+core@7.17.2
+      '@babel/plugin-proposal-export-default-from': 7.18.10_@babel+core@7.17.2
+      '@babel/plugin-proposal-nullish-coalescing-operator': 
7.16.7_@babel+core@7.17.2
+      '@babel/plugin-proposal-object-rest-spread': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-proposal-optional-chaining': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-proposal-private-methods': 7.16.11_@babel+core@7.17.2
+      '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.17.2
+      '@babel/plugin-transform-arrow-functions': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-transform-block-scoping': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-transform-classes': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-transform-destructuring': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-transform-for-of': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-transform-parameters': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-transform-shorthand-properties': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-transform-spread': 7.16.7_@babel+core@7.17.2
+      '@babel/preset-env': 7.16.11_@babel+core@7.17.2
+      '@babel/preset-react': 7.18.6_@babel+core@7.17.2
+      '@babel/preset-typescript': 7.16.7_@babel+core@7.17.2
+      '@babel/register': 7.18.9_@babel+core@7.17.2
+      '@storybook/node-logger': 6.2.9
+      '@storybook/semver': 7.3.2
+      '@types/glob-base': 0.3.0
+      '@types/micromatch': 4.0.2
+      '@types/node': 14.18.32
+      '@types/pretty-hrtime': 1.0.1
+      babel-loader: 8.2.3_mc362qep5qjjhwk7q3m45kuizi
+      babel-plugin-macros: 3.1.0
+      babel-plugin-polyfill-corejs3: 0.1.7_@babel+core@7.17.2
+      chalk: 4.1.2
+      core-js: 3.26.0
+      express: 4.17.2
+      file-system-cache: 1.1.0
+      find-up: 5.0.0
+      fork-ts-checker-webpack-plugin: 6.5.2_ef2lra3u3fsnrdrpybbvbgzate
+      glob: 7.2.3
+      glob-base: 0.3.0
+      interpret: 2.2.0
+      json5: 2.2.0
+      lazy-universal-dotenv: 3.0.1
+      micromatch: 4.0.5
+      pkg-dir: 5.0.0
+      pretty-hrtime: 1.0.3
+      resolve-from: 5.0.0
+      ts-dedent: 2.2.0
+      typescript: 4.8.4
+      util-deprecate: 1.0.2
+      webpack: 4.46.0
+    transitivePeerDependencies:
+      - eslint
+      - supports-color
+      - vue-template-compiler
+      - webpack-cli
+      - webpack-command
+    dev: true
+
+  /@storybook/core-common/6.5.13_3rubbgt5ekhqrcgx4uwls3neim:
+    resolution: {integrity: 
sha512-+DVZrRsteE9pw0X5MNffkdBgejQnbnL+UOG3qXkE9xxUamQALnuqS/w1BzpHE9WmOHuf7RWMKflyQEW3OLKAJg==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/plugin-proposal-class-properties': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-decorators': 7.17.2_@babel+core@7.19.6
+      '@babel/plugin-proposal-export-default-from': 7.18.10_@babel+core@7.19.6
+      '@babel/plugin-proposal-nullish-coalescing-operator': 
7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-object-rest-spread': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-optional-chaining': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-private-methods': 7.16.11_@babel+core@7.19.6
+      '@babel/plugin-proposal-private-property-in-object': 
7.16.7_@babel+core@7.19.6
+      '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.19.6
+      '@babel/plugin-transform-arrow-functions': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-block-scoping': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-classes': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-destructuring': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-for-of': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-parameters': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-shorthand-properties': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-spread': 7.16.7_@babel+core@7.19.6
+      '@babel/preset-env': 7.16.11_@babel+core@7.19.6
+      '@babel/preset-react': 7.18.6_@babel+core@7.19.6
+      '@babel/preset-typescript': 7.16.7_@babel+core@7.19.6
+      '@babel/register': 7.18.9_@babel+core@7.19.6
+      '@storybook/node-logger': 6.5.13
+      '@storybook/semver': 7.3.2
+      '@types/node': 16.18.0
+      '@types/pretty-hrtime': 1.0.1
+      babel-loader: 8.2.3_q4ydpsrmbqywduja5orgah6fgq
+      babel-plugin-macros: 3.1.0
+      babel-plugin-polyfill-corejs3: 0.1.7_@babel+core@7.19.6
+      chalk: 4.1.2
+      core-js: 3.26.0
+      express: 4.17.2
+      file-system-cache: 1.1.0
+      find-up: 5.0.0
+      fork-ts-checker-webpack-plugin: 6.5.2_3n2x3j6farblcaf52bherr6og4
+      fs-extra: 9.1.0
+      glob: 7.2.3
+      handlebars: 4.7.7
+      interpret: 2.2.0
+      json5: 2.2.0
+      lazy-universal-dotenv: 3.0.1
+      picomatch: 2.3.1
+      pkg-dir: 5.0.0
+      pretty-hrtime: 1.0.3
+      resolve-from: 5.0.0
+      slash: 3.0.0
+      telejson: 6.0.8
+      ts-dedent: 2.2.0
+      typescript: 4.8.4
+      util-deprecate: 1.0.2
+      webpack: 4.46.0
+    transitivePeerDependencies:
+      - eslint
+      - supports-color
+      - vue-template-compiler
+      - webpack-cli
+      - webpack-command
+    dev: true
+
+  /@storybook/core-common/6.5.13_u5cwnb36e3nipolzgtjnnpepdu:
+    resolution: {integrity: 
sha512-+DVZrRsteE9pw0X5MNffkdBgejQnbnL+UOG3qXkE9xxUamQALnuqS/w1BzpHE9WmOHuf7RWMKflyQEW3OLKAJg==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/plugin-proposal-class-properties': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-decorators': 7.17.2_@babel+core@7.19.6
+      '@babel/plugin-proposal-export-default-from': 7.18.10_@babel+core@7.19.6
+      '@babel/plugin-proposal-nullish-coalescing-operator': 
7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-object-rest-spread': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-optional-chaining': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-proposal-private-methods': 7.16.11_@babel+core@7.19.6
+      '@babel/plugin-proposal-private-property-in-object': 
7.16.7_@babel+core@7.19.6
+      '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.19.6
+      '@babel/plugin-transform-arrow-functions': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-block-scoping': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-classes': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-destructuring': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-for-of': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-parameters': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-shorthand-properties': 7.16.7_@babel+core@7.19.6
+      '@babel/plugin-transform-spread': 7.16.7_@babel+core@7.19.6
+      '@babel/preset-env': 7.16.11_@babel+core@7.19.6
+      '@babel/preset-react': 7.18.6_@babel+core@7.19.6
+      '@babel/preset-typescript': 7.16.7_@babel+core@7.19.6
+      '@babel/register': 7.18.9_@babel+core@7.19.6
+      '@storybook/node-logger': 6.5.13
+      '@storybook/semver': 7.3.2
+      '@types/node': 16.18.0
+      '@types/pretty-hrtime': 1.0.1
+      babel-loader: 8.2.3_q4ydpsrmbqywduja5orgah6fgq
+      babel-plugin-macros: 3.1.0
+      babel-plugin-polyfill-corejs3: 0.1.7_@babel+core@7.19.6
+      chalk: 4.1.2
+      core-js: 3.26.0
+      express: 4.17.2
+      file-system-cache: 1.1.0
+      find-up: 5.0.0
+      fork-ts-checker-webpack-plugin: 6.5.2_3n2x3j6farblcaf52bherr6og4
+      fs-extra: 9.1.0
+      glob: 7.2.3
+      handlebars: 4.7.7
+      interpret: 2.2.0
+      json5: 2.2.0
+      lazy-universal-dotenv: 3.0.1
+      picomatch: 2.3.1
+      pkg-dir: 5.0.0
+      pretty-hrtime: 1.0.3
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      resolve-from: 5.0.0
+      slash: 3.0.0
+      telejson: 6.0.8
+      ts-dedent: 2.2.0
+      typescript: 4.8.4
+      util-deprecate: 1.0.2
+      webpack: 4.46.0
+    transitivePeerDependencies:
+      - eslint
+      - supports-color
+      - vue-template-compiler
+      - webpack-cli
+      - webpack-command
+    dev: true
+
+  /@storybook/core-events/6.2.9:
+    resolution: {integrity: 
sha512-xQmbX/oYQK1QsAGN8hriXX5SUKOoTUe3L4dVaVHxJqy7MReRWJpprJmCpbAPJzWS6WCbDFfCM5kVEexHLOzJlQ==}
+    dependencies:
+      core-js: 3.26.0
+    dev: true
+
+  /@storybook/core-events/6.5.13:
+    resolution: {integrity: 
sha512-kL745tPpRKejzHToA3/CoBNbI+NPRVk186vGxXBmk95OEg0TlwgQExP8BnqEtLlRZMbW08e4+6kilc1M1M4N5w==}
+    dependencies:
+      core-js: 3.26.0
+    dev: true
+
+  /@storybook/core-server/6.2.9_g2frytwdyb7gw6koky3kitwvuu:
+    resolution: {integrity: 
sha512-DzihO73pj1Ro0Y4tq9hjw2mLMUYeSRPrx7CndCOBxcTHCKQ8Kd7Dee3wJ49t5/19V7TW1+4lYR59GAy73FeOAQ==}
+    peerDependencies:
+      '@storybook/builder-webpack5': 6.2.9
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+      typescript: '*'
+    peerDependenciesMeta:
+      '@storybook/builder-webpack5':
+        optional: true
+      typescript:
+        optional: true
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/plugin-transform-template-literals': 7.16.7_@babel+core@7.19.6
+      '@babel/preset-react': 7.18.6_@babel+core@7.19.6
+      '@storybook/addons': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/builder-webpack4': 6.2.9_g2frytwdyb7gw6koky3kitwvuu
+      '@storybook/core-client': 6.2.9_vvswzvegta47ikremfl73qk64u
+      '@storybook/core-common': 6.2.9_g2frytwdyb7gw6koky3kitwvuu
+      '@storybook/node-logger': 6.2.9
+      '@storybook/semver': 7.3.2
+      '@storybook/theming': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/ui': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      '@types/node': 14.18.32
+      '@types/node-fetch': 2.6.2
+      '@types/pretty-hrtime': 1.0.1
+      '@types/webpack': 4.41.32
+      airbnb-js-shims: 2.2.1
+      babel-loader: 8.2.3_q4ydpsrmbqywduja5orgah6fgq
+      better-opn: 2.1.1
+      boxen: 4.2.0
+      case-sensitive-paths-webpack-plugin: 2.4.0
+      chalk: 4.1.2
+      cli-table3: 0.6.0
+      commander: 6.2.1
+      core-js: 3.26.0
+      cpy: 8.1.2
+      css-loader: 3.6.0_webpack@4.46.0
+      detect-port: 1.5.1
+      dotenv-webpack: 1.8.0_webpack@4.46.0
+      express: 4.17.2
+      file-loader: 6.2.0_webpack@4.46.0
+      file-system-cache: 1.1.0
+      find-up: 5.0.0
+      fs-extra: 9.1.0
+      global: 4.4.0
+      html-webpack-plugin: 4.5.2_webpack@4.46.0
+      ip: 1.1.5
+      node-fetch: 2.6.7
+      pnp-webpack-plugin: 1.6.4_typescript@4.8.4
+      pretty-hrtime: 1.0.3
+      prompts: 2.4.2
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      read-pkg-up: 7.0.1
+      regenerator-runtime: 0.13.9
+      resolve-from: 5.0.0
+      serve-favicon: 2.5.0
+      style-loader: 1.3.0_webpack@4.46.0
+      telejson: 5.3.3
+      terser-webpack-plugin: 3.1.0_webpack@4.46.0
+      ts-dedent: 2.2.0
+      typescript: 4.8.4
+      url-loader: 4.1.1_lit45vopotvaqup7lrvlnvtxwy
+      util-deprecate: 1.0.2
+      webpack: 4.46.0
+      webpack-dev-middleware: 3.7.3_webpack@4.46.0
+      webpack-virtual-modules: 0.2.2
+    transitivePeerDependencies:
+      - '@types/react'
+      - bluebird
+      - encoding
+      - eslint
+      - supports-color
+      - vue-template-compiler
+      - webpack-cli
+      - webpack-command
+    dev: true
+
+  /@storybook/core-server/6.2.9_o2nrgn6wwxunlqlzzokx4es3q4:
+    resolution: {integrity: 
sha512-DzihO73pj1Ro0Y4tq9hjw2mLMUYeSRPrx7CndCOBxcTHCKQ8Kd7Dee3wJ49t5/19V7TW1+4lYR59GAy73FeOAQ==}
+    peerDependencies:
+      '@storybook/builder-webpack5': 6.2.9
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+      typescript: '*'
+    peerDependenciesMeta:
+      '@storybook/builder-webpack5':
+        optional: true
+      typescript:
+        optional: true
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/plugin-transform-template-literals': 7.16.7_@babel+core@7.19.6
+      '@babel/preset-react': 7.18.6_@babel+core@7.19.6
+      '@storybook/addons': 6.2.9
+      '@storybook/builder-webpack4': 6.2.9_o2nrgn6wwxunlqlzzokx4es3q4
+      '@storybook/core-client': 6.2.9_lasgyenclx45ngbljrbo537mpe
+      '@storybook/core-common': 6.2.9_o2nrgn6wwxunlqlzzokx4es3q4
+      '@storybook/node-logger': 6.2.9
+      '@storybook/semver': 7.3.2
+      '@storybook/theming': 6.2.9
+      '@storybook/ui': 6.2.9
+      '@types/node': 14.18.32
+      '@types/node-fetch': 2.6.2
+      '@types/pretty-hrtime': 1.0.1
+      '@types/webpack': 4.41.32
+      airbnb-js-shims: 2.2.1
+      babel-loader: 8.2.3_q4ydpsrmbqywduja5orgah6fgq
+      better-opn: 2.1.1
+      boxen: 4.2.0
+      case-sensitive-paths-webpack-plugin: 2.4.0
+      chalk: 4.1.2
+      cli-table3: 0.6.0
+      commander: 6.2.1
+      core-js: 3.26.0
+      cpy: 8.1.2
+      css-loader: 3.6.0_webpack@4.46.0
+      detect-port: 1.5.1
+      dotenv-webpack: 1.8.0_webpack@4.46.0
+      express: 4.17.2
+      file-loader: 6.2.0_webpack@4.46.0
+      file-system-cache: 1.1.0
+      find-up: 5.0.0
+      fs-extra: 9.1.0
+      global: 4.4.0
+      html-webpack-plugin: 4.5.2_webpack@4.46.0
+      ip: 1.1.5
+      node-fetch: 2.6.7
+      pnp-webpack-plugin: 1.6.4_typescript@4.8.4
+      pretty-hrtime: 1.0.3
+      prompts: 2.4.2
+      read-pkg-up: 7.0.1
+      regenerator-runtime: 0.13.9
+      resolve-from: 5.0.0
+      serve-favicon: 2.5.0
+      style-loader: 1.3.0_webpack@4.46.0
+      telejson: 5.3.3
+      terser-webpack-plugin: 3.1.0_webpack@4.46.0
+      ts-dedent: 2.2.0
+      typescript: 4.8.4
+      url-loader: 4.1.1_lit45vopotvaqup7lrvlnvtxwy
+      util-deprecate: 1.0.2
+      webpack: 4.46.0
+      webpack-dev-middleware: 3.7.3_webpack@4.46.0
+      webpack-virtual-modules: 0.2.2
+    transitivePeerDependencies:
+      - '@types/react'
+      - bluebird
+      - encoding
+      - eslint
+      - supports-color
+      - vue-template-compiler
+      - webpack-cli
+      - webpack-command
+    dev: true
+
+  /@storybook/core-server/6.5.13_u5cwnb36e3nipolzgtjnnpepdu:
+    resolution: {integrity: 
sha512-vs7tu3kAnFwuINio1p87WyqDNlFyZESmeh9s7vvrZVbe/xS/ElqDscr9DT5seW+jbtxufAaHsx+JUTver1dheQ==}
+    peerDependencies:
+      '@storybook/builder-webpack5': '*'
+      '@storybook/manager-webpack5': '*'
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+      typescript: '*'
+    peerDependenciesMeta:
+      '@storybook/builder-webpack5':
+        optional: true
+      '@storybook/manager-webpack5':
+        optional: true
+      typescript:
+        optional: true
+    dependencies:
+      '@discoveryjs/json-ext': 0.5.7
+      '@storybook/builder-webpack4': 6.5.13_u5cwnb36e3nipolzgtjnnpepdu
+      '@storybook/core-client': 6.5.13_vvswzvegta47ikremfl73qk64u
+      '@storybook/core-common': 6.5.13_u5cwnb36e3nipolzgtjnnpepdu
+      '@storybook/core-events': 6.5.13
+      '@storybook/csf': 0.0.2--canary.4566f4d.1
+      '@storybook/csf-tools': 6.5.13
+      '@storybook/manager-webpack4': 6.5.13_u5cwnb36e3nipolzgtjnnpepdu
+      '@storybook/node-logger': 6.5.13
+      '@storybook/semver': 7.3.2
+      '@storybook/store': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/telemetry': 6.5.13_u5cwnb36e3nipolzgtjnnpepdu
+      '@types/node': 16.18.0
+      '@types/node-fetch': 2.6.2
+      '@types/pretty-hrtime': 1.0.1
+      '@types/webpack': 4.41.32
+      better-opn: 2.1.1
+      boxen: 5.1.2
+      chalk: 4.1.2
+      cli-table3: 0.6.3
+      commander: 6.2.1
+      compression: 1.7.4
+      core-js: 3.26.0
+      cpy: 8.1.2
+      detect-port: 1.5.1
+      express: 4.17.2
+      fs-extra: 9.1.0
+      global: 4.4.0
+      globby: 11.1.0
+      ip: 2.0.0
+      lodash: 4.17.21
+      node-fetch: 2.6.7
+      open: 8.4.0
+      pretty-hrtime: 1.0.3
+      prompts: 2.4.2
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      regenerator-runtime: 0.13.9
+      serve-favicon: 2.5.0
+      slash: 3.0.0
+      telejson: 6.0.8
+      ts-dedent: 2.2.0
+      typescript: 4.8.4
+      util-deprecate: 1.0.2
+      watchpack: 2.4.0
+      webpack: 4.46.0
+      ws: 8.5.0
+      x-default-browser: 0.4.0
+    transitivePeerDependencies:
+      - '@storybook/mdx2-csf'
+      - bluebird
+      - bufferutil
+      - encoding
+      - eslint
+      - supports-color
+      - utf-8-validate
+      - vue-template-compiler
+      - webpack-cli
+      - webpack-command
+    dev: true
+
+  /@storybook/core/6.2.9_g2frytwdyb7gw6koky3kitwvuu:
+    resolution: {integrity: 
sha512-pzbyjWvj0t8m0kR2pC9GQne4sZn7Y/zfcbm6/31CL+yhzOQjfJEj3n4ZFUlxikXqQJPg1aWfypfyaeaLL0QyuA==}
+    peerDependencies:
+      '@storybook/builder-webpack5': 6.2.9
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+      typescript: '*'
+    peerDependenciesMeta:
+      '@storybook/builder-webpack5':
+        optional: true
+      typescript:
+        optional: true
+    dependencies:
+      '@storybook/core-client': 6.2.9_zvdcumho7mqj3lfknr2wnpofbm
+      '@storybook/core-server': 6.2.9_g2frytwdyb7gw6koky3kitwvuu
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      typescript: 4.8.4
+    transitivePeerDependencies:
+      - '@types/react'
+      - bluebird
+      - encoding
+      - eslint
+      - supports-color
+      - vue-template-compiler
+      - webpack
+      - webpack-cli
+      - webpack-command
+    dev: true
+
+  /@storybook/core/6.2.9_o2nrgn6wwxunlqlzzokx4es3q4:
+    resolution: {integrity: 
sha512-pzbyjWvj0t8m0kR2pC9GQne4sZn7Y/zfcbm6/31CL+yhzOQjfJEj3n4ZFUlxikXqQJPg1aWfypfyaeaLL0QyuA==}
+    peerDependencies:
+      '@storybook/builder-webpack5': 6.2.9
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+      typescript: '*'
+    peerDependenciesMeta:
+      '@storybook/builder-webpack5':
+        optional: true
+      typescript:
+        optional: true
+    dependencies:
+      '@storybook/core-client': 6.2.9_typescript@4.8.4
+      '@storybook/core-server': 6.2.9_o2nrgn6wwxunlqlzzokx4es3q4
+      typescript: 4.8.4
+    transitivePeerDependencies:
+      - '@types/react'
+      - bluebird
+      - encoding
+      - eslint
+      - supports-color
+      - vue-template-compiler
+      - webpack
+      - webpack-cli
+      - webpack-command
+    dev: true
+
+  /@storybook/core/6.5.13_brfvc2pvdspackskhn4rfzxuge:
+    resolution: {integrity: 
sha512-kw1lCgbsxzUimGww6t5rmuWJmFPe9kGGyzIqvj4RC4BBcEsP40LEu9XhSfvnb8vTOLIULFZeZpdRFfJs4TYbUw==}
+    peerDependencies:
+      '@storybook/builder-webpack5': '*'
+      '@storybook/manager-webpack5': '*'
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+      typescript: '*'
+      webpack: '*'
+    peerDependenciesMeta:
+      '@storybook/builder-webpack5':
+        optional: true
+      '@storybook/manager-webpack5':
+        optional: true
+      typescript:
+        optional: true
+    dependencies:
+      '@storybook/core-client': 6.5.13_vvswzvegta47ikremfl73qk64u
+      '@storybook/core-server': 6.5.13_u5cwnb36e3nipolzgtjnnpepdu
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      typescript: 4.8.4
+      webpack: 4.46.0
+    transitivePeerDependencies:
+      - '@storybook/mdx2-csf'
+      - bluebird
+      - bufferutil
+      - encoding
+      - eslint
+      - supports-color
+      - utf-8-validate
+      - vue-template-compiler
+      - webpack-cli
+      - webpack-command
+    dev: true
+
+  /@storybook/csf-tools/6.5.13:
+    resolution: {integrity: 
sha512-63Ev+VmBqzwSwfUzbuXOLKBD5dMTK2zBYLQ9anTVw70FuTikwTsGIbPgb098K0vsxRCgxl7KM7NpivHqtZtdjw==}
+    peerDependencies:
+      '@storybook/mdx2-csf': ^0.0.3
+    peerDependenciesMeta:
+      '@storybook/mdx2-csf':
+        optional: true
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/generator': 7.19.6
+      '@babel/parser': 7.19.6
+      '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.19.6
+      '@babel/preset-env': 7.16.11_@babel+core@7.19.6
+      '@babel/traverse': 7.19.6
+      '@babel/types': 7.19.4
+      '@storybook/csf': 0.0.2--canary.4566f4d.1
+      '@storybook/mdx1-csf': 0.0.1_@babel+core@7.19.6
+      core-js: 3.26.0
+      fs-extra: 9.1.0
+      global: 4.4.0
+      regenerator-runtime: 0.13.9
+      ts-dedent: 2.2.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@storybook/csf/0.0.1:
+    resolution: {integrity: 
sha512-USTLkZze5gkel8MYCujSRBVIrUQ3YPBrLOx7GNk/0wttvVtlzWXAq9eLbQ4p/NicGxP+3T7KPEMVV//g+yubpw==}
+    dependencies:
+      lodash: 4.17.21
+    dev: true
+
+  /@storybook/csf/0.0.2--canary.4566f4d.1:
+    resolution: {integrity: 
sha512-9OVvMVh3t9znYZwb0Svf/YQoxX2gVOeQTGe2bses2yj+a3+OJnCrUF3/hGv6Em7KujtOdL2LL+JnG49oMVGFgQ==}
+    dependencies:
+      lodash: 4.17.21
+    dev: true
+
+  /@storybook/docs-tools/6.5.13:
+    resolution: {integrity: 
sha512-hB+hk+895ny4SW84j3X5iV55DHs3bCfTOp7cDdcZJdQrlm0wuDb4A6d4ffNC7ZLh9VkUjU6ST4VEV5Bb0Cptow==}
+    dependencies:
+      '@babel/core': 7.19.6
+      '@storybook/csf': 0.0.2--canary.4566f4d.1
+      '@storybook/store': 6.5.13
+      core-js: 3.26.0
+      doctrine: 3.0.0
+      lodash: 4.17.21
+      regenerator-runtime: 0.13.9
+    transitivePeerDependencies:
+      - react
+      - react-dom
+      - supports-color
+    dev: true
+
+  /@storybook/manager-webpack4/6.5.13_u5cwnb36e3nipolzgtjnnpepdu:
+    resolution: {integrity: 
sha512-pURzS5W3XM0F7bCBWzpl7TRsuy+OXFwLXiWLaexuvo0POZe31Ueo2A1R4rx3MT5Iee8O9mYvG2XTmvK9MlLefQ==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/plugin-transform-template-literals': 7.16.7_@babel+core@7.19.6
+      '@babel/preset-react': 7.18.6_@babel+core@7.19.6
+      '@storybook/addons': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/core-client': 6.5.13_vvswzvegta47ikremfl73qk64u
+      '@storybook/core-common': 6.5.13_u5cwnb36e3nipolzgtjnnpepdu
+      '@storybook/node-logger': 6.5.13
+      '@storybook/theming': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/ui': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@types/node': 16.18.0
+      '@types/webpack': 4.41.32
+      babel-loader: 8.2.3_q4ydpsrmbqywduja5orgah6fgq
+      case-sensitive-paths-webpack-plugin: 2.4.0
+      chalk: 4.1.2
+      core-js: 3.26.0
+      css-loader: 3.6.0_webpack@4.46.0
+      express: 4.17.2
+      file-loader: 6.2.0_webpack@4.46.0
+      find-up: 5.0.0
+      fs-extra: 9.1.0
+      html-webpack-plugin: 4.5.2_webpack@4.46.0
+      node-fetch: 2.6.7
+      pnp-webpack-plugin: 1.6.4_typescript@4.8.4
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      read-pkg-up: 7.0.1
+      regenerator-runtime: 0.13.9
+      resolve-from: 5.0.0
+      style-loader: 1.3.0_webpack@4.46.0
+      telejson: 6.0.8
+      terser-webpack-plugin: 4.2.3_webpack@4.46.0
+      ts-dedent: 2.2.0
+      typescript: 4.8.4
+      url-loader: 4.1.1_lit45vopotvaqup7lrvlnvtxwy
+      util-deprecate: 1.0.2
+      webpack: 4.46.0
+      webpack-dev-middleware: 3.7.3_webpack@4.46.0
+      webpack-virtual-modules: 0.2.2
+    transitivePeerDependencies:
+      - bluebird
+      - encoding
+      - eslint
+      - supports-color
+      - vue-template-compiler
+      - webpack-cli
+      - webpack-command
+    dev: true
+
+  /@storybook/mdx1-csf/0.0.1_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-4biZIWWzoWlCarMZmTpqcJNgo/RBesYZwGFbQeXiGYsswuvfWARZnW9RE9aUEMZ4XPn7B1N3EKkWcdcWe/K2tg==}
+    dependencies:
+      '@babel/generator': 7.19.6
+      '@babel/parser': 7.19.6
+      '@babel/preset-env': 7.16.11_@babel+core@7.17.2
+      '@babel/types': 7.19.4
+      '@mdx-js/mdx': 1.6.22
+      '@types/lodash': 4.14.186
+      js-string-escape: 1.0.1
+      loader-utils: 2.0.2
+      lodash: 4.17.21
+      prettier: 2.2.1
+      ts-dedent: 2.2.0
+    transitivePeerDependencies:
+      - '@babel/core'
+      - supports-color
+    dev: true
+
+  /@storybook/mdx1-csf/0.0.1_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-4biZIWWzoWlCarMZmTpqcJNgo/RBesYZwGFbQeXiGYsswuvfWARZnW9RE9aUEMZ4XPn7B1N3EKkWcdcWe/K2tg==}
+    dependencies:
+      '@babel/generator': 7.19.6
+      '@babel/parser': 7.19.6
+      '@babel/preset-env': 7.16.11_@babel+core@7.19.6
+      '@babel/types': 7.19.4
+      '@mdx-js/mdx': 1.6.22
+      '@types/lodash': 4.14.186
+      js-string-escape: 1.0.1
+      loader-utils: 2.0.2
+      lodash: 4.17.21
+      prettier: 2.2.1
+      ts-dedent: 2.2.0
+    transitivePeerDependencies:
+      - '@babel/core'
+      - supports-color
+    dev: true
+
+  /@storybook/node-logger/6.2.9:
+    resolution: {integrity: 
sha512-ryRBChWZf1A5hOVONErJZosS25IdMweoMVFAUAcj91iC0ynoSA6YL2jmoE71jQchxEXEgkDeRkX9lR/GlqFGZQ==}
+    dependencies:
+      '@types/npmlog': 4.1.4
+      chalk: 4.1.2
+      core-js: 3.26.0
+      npmlog: 4.1.2
+      pretty-hrtime: 1.0.3
+    dev: true
+
+  /@storybook/node-logger/6.5.13:
+    resolution: {integrity: 
sha512-/r5aVZAqZRoy5FyNk/G4pj7yKJd3lJfPbAaOHVROv2IF7PJP/vtRaDkcfh0g2U6zwuDxGIqSn80j+qoEli9m5A==}
+    dependencies:
+      '@types/npmlog': 4.1.4
+      chalk: 4.1.2
+      core-js: 3.26.0
+      npmlog: 5.0.1
+      pretty-hrtime: 1.0.3
+    dev: true
+
+  /@storybook/postinstall/6.2.9:
+    resolution: {integrity: 
sha512-HjAjXZV+WItonC7lVrfrUsQuRFZNz1g1lE0GgsEK2LdC5rAcD/JwJxjiWREwY+RGxKL9rpWgqyxVQajpIJRjhA==}
+    dependencies:
+      core-js: 3.26.0
+    dev: true
+
+  /@storybook/postinstall/6.5.13:
+    resolution: {integrity: 
sha512-qmqP39FGIP5NdhXC5IpAs9cFoYx9fg1psoQKwb9snYb98eVQU31uHc1W2MBUh3lG4AjAm7pQaXJci7ti4jOh3g==}
+    dependencies:
+      core-js: 3.26.0
+    dev: true
+
+  /@storybook/preact/6.2.9_lmcptaky2e4dapkymvnphph734:
+    resolution: {integrity: 
sha512-AnbRtJfIyI6AGIIaduBe2Fnr4HPldycWr1fadqpytm9LBMQsYRCzXy2+AtBIfa0O5YDVqDcKda/uBsj1tNJzqw==}
+    engines: {node: '>=10.13.0'}
+    hasBin: true
+    peerDependencies:
+      '@babel/core': '*'
+      preact: ^8.0.0||^10.0.0
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/plugin-transform-react-jsx': 7.16.7_@babel+core@7.17.2
+      '@storybook/addons': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/core': 6.2.9_g2frytwdyb7gw6koky3kitwvuu
+      '@storybook/core-common': 6.2.9_g2frytwdyb7gw6koky3kitwvuu
+      '@types/webpack-env': 1.18.0
+      core-js: 3.26.0
+      global: 4.4.0
+      preact: 10.6.5
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      read-pkg-up: 7.0.1
+      regenerator-runtime: 0.13.9
+      ts-dedent: 2.2.0
+    transitivePeerDependencies:
+      - '@storybook/builder-webpack5'
+      - '@types/react'
+      - bluebird
+      - encoding
+      - eslint
+      - supports-color
+      - typescript
+      - vue-template-compiler
+      - webpack
+      - webpack-cli
+      - webpack-command
+    dev: true
+
+  /@storybook/preact/6.5.13_pzutvqtg2sm6mgs5je6xwivarm:
+    resolution: {integrity: 
sha512-5/ufRgxh5VypFcOeIBQMg/AqZQ2+KfUw4Glo9HU75dbIe/kYqSnN3+5SEv8J6ykxHHtUWcmnILS1r7/I5R7j/w==}
+    engines: {node: '>=10.13.0'}
+    hasBin: true
+    peerDependencies:
+      '@babel/core': '*'
+      preact: ^8.0.0||^10.0.0
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/plugin-transform-react-jsx': 7.16.7_@babel+core@7.17.2
+      '@storybook/addons': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/core': 6.5.13_brfvc2pvdspackskhn4rfzxuge
+      '@storybook/core-common': 6.5.13_u5cwnb36e3nipolzgtjnnpepdu
+      '@storybook/csf': 0.0.2--canary.4566f4d.1
+      '@storybook/store': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@types/node': 16.18.0
+      '@types/webpack-env': 1.18.0
+      core-js: 3.26.0
+      global: 4.4.0
+      preact: 10.6.1
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      read-pkg-up: 7.0.1
+      regenerator-runtime: 0.13.9
+      ts-dedent: 2.2.0
+      webpack: 4.46.0
+    transitivePeerDependencies:
+      - '@storybook/builder-webpack5'
+      - '@storybook/manager-webpack5'
+      - '@storybook/mdx2-csf'
+      - bluebird
+      - bufferutil
+      - encoding
+      - eslint
+      - supports-color
+      - typescript
+      - utf-8-validate
+      - vue-template-compiler
+      - webpack-cli
+      - webpack-command
+    dev: true
+
+  /@storybook/preact/6.5.13_rv7hwuimljxvhghl3f4jocbf4q:
+    resolution: {integrity: 
sha512-5/ufRgxh5VypFcOeIBQMg/AqZQ2+KfUw4Glo9HU75dbIe/kYqSnN3+5SEv8J6ykxHHtUWcmnILS1r7/I5R7j/w==}
+    engines: {node: '>=10.13.0'}
+    hasBin: true
+    peerDependencies:
+      '@babel/core': '*'
+      preact: ^8.0.0||^10.0.0
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/plugin-transform-react-jsx': 7.16.7_@babel+core@7.17.2
+      '@storybook/addons': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/core': 6.5.13_brfvc2pvdspackskhn4rfzxuge
+      '@storybook/core-common': 6.5.13_u5cwnb36e3nipolzgtjnnpepdu
+      '@storybook/csf': 0.0.2--canary.4566f4d.1
+      '@storybook/store': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@types/node': 16.18.0
+      '@types/webpack-env': 1.18.0
+      core-js: 3.26.0
+      global: 4.4.0
+      preact: 10.6.5
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      read-pkg-up: 7.0.1
+      regenerator-runtime: 0.13.9
+      ts-dedent: 2.2.0
+      webpack: 4.46.0
+    transitivePeerDependencies:
+      - '@storybook/builder-webpack5'
+      - '@storybook/manager-webpack5'
+      - '@storybook/mdx2-csf'
+      - bluebird
+      - bufferutil
+      - encoding
+      - eslint
+      - supports-color
+      - typescript
+      - utf-8-validate
+      - vue-template-compiler
+      - webpack-cli
+      - webpack-command
+    dev: true
+
+  /@storybook/preset-scss/1.0.3_sass-loader@10.1.1:
+    resolution: {integrity: 
sha512-o9Iz6wxPeNENrQa2mKlsDKynBfqU2uWaRP80HeWp4TkGgf7/x3DVF2O7yi9N0x/PI1qzzTTpxlQ90D62XmpiTw==}
+    peerDependencies:
+      css-loader: '*'
+      sass-loader: '*'
+      style-loader: '*'
+    dependencies:
+      sass-loader: 10.1.1_sass@1.32.13
+    dev: true
+
+  /@storybook/preset-scss/1.0.3_sass-loader@10.3.1:
+    resolution: {integrity: 
sha512-o9Iz6wxPeNENrQa2mKlsDKynBfqU2uWaRP80HeWp4TkGgf7/x3DVF2O7yi9N0x/PI1qzzTTpxlQ90D62XmpiTw==}
+    peerDependencies:
+      css-loader: '*'
+      sass-loader: '*'
+      style-loader: '*'
+    dependencies:
+      sass-loader: 10.3.1_sass@1.32.13
+    dev: true
+
+  /@storybook/preview-web/6.5.13:
+    resolution: {integrity: 
sha512-GNNYVzw4SmRua3dOc52Ye6Us4iQbq5GKQ56U3iwnzZM3TBdJB+Rft94Fn1/pypHujEHS8hl5Xgp9td6C1lLCow==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      '@storybook/addons': 6.5.13
+      '@storybook/channel-postmessage': 6.5.13
+      '@storybook/client-logger': 6.5.13
+      '@storybook/core-events': 6.5.13
+      '@storybook/csf': 0.0.2--canary.4566f4d.1
+      '@storybook/store': 6.5.13
+      ansi-to-html: 0.6.15
+      core-js: 3.26.0
+      global: 4.4.0
+      lodash: 4.17.21
+      qs: 6.11.0
+      regenerator-runtime: 0.13.9
+      synchronous-promise: 2.0.16
+      ts-dedent: 2.2.0
+      unfetch: 4.2.0
+      util-deprecate: 1.0.2
+    dev: true
+
+  /@storybook/preview-web/6.5.13_wcqkhtmu7mswc6yz4uyexck3ty:
+    resolution: {integrity: 
sha512-GNNYVzw4SmRua3dOc52Ye6Us4iQbq5GKQ56U3iwnzZM3TBdJB+Rft94Fn1/pypHujEHS8hl5Xgp9td6C1lLCow==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      '@storybook/addons': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/channel-postmessage': 6.5.13
+      '@storybook/client-logger': 6.5.13
+      '@storybook/core-events': 6.5.13
+      '@storybook/csf': 0.0.2--canary.4566f4d.1
+      '@storybook/store': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      ansi-to-html: 0.6.15
+      core-js: 3.26.0
+      global: 4.4.0
+      lodash: 4.17.21
+      qs: 6.11.0
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      regenerator-runtime: 0.13.9
+      synchronous-promise: 2.0.16
+      ts-dedent: 2.2.0
+      unfetch: 4.2.0
+      util-deprecate: 1.0.2
+    dev: true
+
+  /@storybook/router/6.2.9:
+    resolution: {integrity: 
sha512-7Bn1OFoItCl8whXRT8N1qp1Lky7kzXJ3aslWp5E8HcM8rxh4OYXfbaeiyJEJxBTGC5zxgY+tAEXHFjsAviFROg==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+    dependencies:
+      '@reach/router': 1.3.4
+      '@storybook/client-logger': 6.2.9
+      '@types/reach__router': 1.3.11
+      core-js: 3.26.0
+      fast-deep-equal: 3.1.3
+      global: 4.4.0
+      lodash: 4.17.21
+      memoizerific: 1.11.3
+      qs: 6.11.0
+      ts-dedent: 2.2.0
+    dev: true
+
+  /@storybook/router/6.2.9_wcqkhtmu7mswc6yz4uyexck3ty:
+    resolution: {integrity: 
sha512-7Bn1OFoItCl8whXRT8N1qp1Lky7kzXJ3aslWp5E8HcM8rxh4OYXfbaeiyJEJxBTGC5zxgY+tAEXHFjsAviFROg==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+    dependencies:
+      '@reach/router': 1.3.4_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/client-logger': 6.2.9
+      '@types/reach__router': 1.3.11
+      core-js: 3.26.0
+      fast-deep-equal: 3.1.3
+      global: 4.4.0
+      lodash: 4.17.21
+      memoizerific: 1.11.3
+      qs: 6.11.0
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      ts-dedent: 2.2.0
+    dev: true
+
+  /@storybook/router/6.5.13:
+    resolution: {integrity: 
sha512-sf5aogfirH5ucD0d0hc2mKf2iyWsZsvXhr5kjxUQmgkcoflkGUWhc34sbSQVRQ1i8K5lkLIDH/q2s1Zr2SbzhQ==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      '@storybook/client-logger': 6.5.13
+      core-js: 3.26.0
+      memoizerific: 1.11.3
+      qs: 6.11.0
+      regenerator-runtime: 0.13.9
+    dev: true
+
+  /@storybook/router/6.5.13_wcqkhtmu7mswc6yz4uyexck3ty:
+    resolution: {integrity: 
sha512-sf5aogfirH5ucD0d0hc2mKf2iyWsZsvXhr5kjxUQmgkcoflkGUWhc34sbSQVRQ1i8K5lkLIDH/q2s1Zr2SbzhQ==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      '@storybook/client-logger': 6.5.13
+      core-js: 3.26.0
+      memoizerific: 1.11.3
+      qs: 6.11.0
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      regenerator-runtime: 0.13.9
+    dev: true
+
+  /@storybook/semver/7.3.2:
+    resolution: {integrity: 
sha512-SWeszlsiPsMI0Ps0jVNtH64cI5c0UF3f7KgjVKJoNP30crQ6wUSddY2hsdeczZXEKVJGEn50Q60flcGsQGIcrg==}
+    engines: {node: '>=10'}
+    hasBin: true
+    dependencies:
+      core-js: 3.26.0
+      find-up: 4.1.0
+    dev: true
+
+  /@storybook/source-loader/6.2.9:
+    resolution: {integrity: 
sha512-cx499g7BG2oeXvRFx45r0W0p2gKEy/e88WsUFnqqfMKZBJ8K0R/lx5DI0l1hq+TzSrE6uGe0/uPlaLkJNIro7g==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+    dependencies:
+      '@storybook/addons': 6.2.9
+      '@storybook/client-logger': 6.2.9
+      '@storybook/csf': 0.0.1
+      core-js: 3.26.0
+      estraverse: 5.3.0
+      global: 4.4.0
+      loader-utils: 2.0.2
+      lodash: 4.17.21
+      prettier: 2.2.1
+      regenerator-runtime: 0.13.9
+    dev: true
+
+  /@storybook/source-loader/6.5.13:
+    resolution: {integrity: 
sha512-tHuM8PfeB/0m+JigbaFp+Ld0euFH+fgOObH2W9rjEXy5vnwmaeex/JAdCprv4oL+LcDQEERqNULUUNIvbcTPAg==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      '@storybook/addons': 6.5.13
+      '@storybook/client-logger': 6.5.13
+      '@storybook/csf': 0.0.2--canary.4566f4d.1
+      core-js: 3.26.0
+      estraverse: 5.3.0
+      global: 4.4.0
+      loader-utils: 2.0.2
+      lodash: 4.17.21
+      prettier: 2.2.1
+      regenerator-runtime: 0.13.9
+    dev: true
+
+  /@storybook/store/6.5.13:
+    resolution: {integrity: 
sha512-GG6lm+8fBX1tNUnX7x3raBOjYhhf14bPWLtYiPlxDTFEMs3sJte7zWKZq6NQ79MoBLL6jjzTeolBfDCBw6fiWQ==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      '@storybook/addons': 6.5.13
+      '@storybook/client-logger': 6.5.13
+      '@storybook/core-events': 6.5.13
+      '@storybook/csf': 0.0.2--canary.4566f4d.1
+      core-js: 3.26.0
+      fast-deep-equal: 3.1.3
+      global: 4.4.0
+      lodash: 4.17.21
+      memoizerific: 1.11.3
+      regenerator-runtime: 0.13.9
+      slash: 3.0.0
+      stable: 0.1.8
+      synchronous-promise: 2.0.16
+      ts-dedent: 2.2.0
+      util-deprecate: 1.0.2
+    dev: true
+
+  /@storybook/store/6.5.13_wcqkhtmu7mswc6yz4uyexck3ty:
+    resolution: {integrity: 
sha512-GG6lm+8fBX1tNUnX7x3raBOjYhhf14bPWLtYiPlxDTFEMs3sJte7zWKZq6NQ79MoBLL6jjzTeolBfDCBw6fiWQ==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      '@storybook/addons': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/client-logger': 6.5.13
+      '@storybook/core-events': 6.5.13
+      '@storybook/csf': 0.0.2--canary.4566f4d.1
+      core-js: 3.26.0
+      fast-deep-equal: 3.1.3
+      global: 4.4.0
+      lodash: 4.17.21
+      memoizerific: 1.11.3
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      regenerator-runtime: 0.13.9
+      slash: 3.0.0
+      stable: 0.1.8
+      synchronous-promise: 2.0.16
+      ts-dedent: 2.2.0
+      util-deprecate: 1.0.2
+    dev: true
+
+  /@storybook/telemetry/6.5.13_u5cwnb36e3nipolzgtjnnpepdu:
+    resolution: {integrity: 
sha512-PFJEfGbunmfFWabD3rdCF8EHH+45578OHOkMPpXJjqXl94vPQxUH2XTVKQgEQJbYrgX0Vx9Z4tSkdMHuzYDbWQ==}
+    dependencies:
+      '@storybook/client-logger': 6.5.13
+      '@storybook/core-common': 6.5.13_u5cwnb36e3nipolzgtjnnpepdu
+      chalk: 4.1.2
+      core-js: 3.26.0
+      detect-package-manager: 2.0.1
+      fetch-retry: 5.0.3
+      fs-extra: 9.1.0
+      global: 4.4.0
+      isomorphic-unfetch: 3.1.0
+      nanoid: 3.3.4
+      read-pkg-up: 7.0.1
+      regenerator-runtime: 0.13.9
+    transitivePeerDependencies:
+      - encoding
+      - eslint
+      - react
+      - react-dom
+      - supports-color
+      - typescript
+      - vue-template-compiler
+      - webpack-cli
+      - webpack-command
+    dev: true
+
+  /@storybook/theming/6.2.9:
+    resolution: {integrity: 
sha512-183oJW7AD7Fhqg5NT4ct3GJntwteAb9jZnQ6yhf9JSdY+fk8OhxRbPf7ov0au2gYACcGrWDd9K5pYQsvWlP5gA==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+    dependencies:
+      '@emotion/core': 10.3.1
+      '@emotion/is-prop-valid': 0.8.8
+      '@emotion/styled': 10.3.0_@emotion+core@10.3.1
+      '@storybook/client-logger': 6.2.9
+      core-js: 3.26.0
+      deep-object-diff: 1.1.7
+      emotion-theming: 10.3.0_@emotion+core@10.3.1
+      global: 4.4.0
+      memoizerific: 1.11.3
+      polished: 4.2.2
+      resolve-from: 5.0.0
+      ts-dedent: 2.2.0
+    dev: true
+
+  /@storybook/theming/6.2.9_wcqkhtmu7mswc6yz4uyexck3ty:
+    resolution: {integrity: 
sha512-183oJW7AD7Fhqg5NT4ct3GJntwteAb9jZnQ6yhf9JSdY+fk8OhxRbPf7ov0au2gYACcGrWDd9K5pYQsvWlP5gA==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+    dependencies:
+      '@emotion/core': 10.3.1_react@16.14.0
+      '@emotion/is-prop-valid': 0.8.8
+      '@emotion/styled': 10.3.0_qzeatvug73zaio2r3dlvejynye
+      '@storybook/client-logger': 6.2.9
+      core-js: 3.26.0
+      deep-object-diff: 1.1.7
+      emotion-theming: 10.3.0_qzeatvug73zaio2r3dlvejynye
+      global: 4.4.0
+      memoizerific: 1.11.3
+      polished: 4.2.2
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      resolve-from: 5.0.0
+      ts-dedent: 2.2.0
+    dev: true
+
+  /@storybook/theming/6.5.13:
+    resolution: {integrity: 
sha512-oif5NGFAUQhizo50r+ctw2hZNLWV4dPHai+L/gFvbaSeRBeHSNkIcMoZ2FlrO566HdGZTDutYXcR+xus8rI28g==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      '@storybook/client-logger': 6.5.13
+      core-js: 3.26.0
+      memoizerific: 1.11.3
+      regenerator-runtime: 0.13.9
+    dev: true
+
+  /@storybook/theming/6.5.13_wcqkhtmu7mswc6yz4uyexck3ty:
+    resolution: {integrity: 
sha512-oif5NGFAUQhizo50r+ctw2hZNLWV4dPHai+L/gFvbaSeRBeHSNkIcMoZ2FlrO566HdGZTDutYXcR+xus8rI28g==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      '@storybook/client-logger': 6.5.13
+      core-js: 3.26.0
+      memoizerific: 1.11.3
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      regenerator-runtime: 0.13.9
+    dev: true
+
+  /@storybook/ui/6.2.9:
+    resolution: {integrity: 
sha512-jq2xmw3reIqik/6ibUSbNKGR+Xvr9wkAEwexiOl+5WQ5BeYJpw4dmDmsFQf+SQuWaSEUUPolbzkakRQM778Kdg==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+    dependencies:
+      '@emotion/core': 10.3.1
+      '@storybook/addons': 6.2.9
+      '@storybook/api': 6.2.9
+      '@storybook/channels': 6.2.9
+      '@storybook/client-logger': 6.2.9
+      '@storybook/components': 6.2.9
+      '@storybook/core-events': 6.2.9
+      '@storybook/router': 6.2.9
+      '@storybook/semver': 7.3.2
+      '@storybook/theming': 6.2.9
+      '@types/markdown-to-jsx': 6.11.3
+      copy-to-clipboard: 3.3.2
+      core-js: 3.26.0
+      core-js-pure: 3.20.2
+      downshift: 6.1.12
+      emotion-theming: 10.3.0_@emotion+core@10.3.1
+      fuse.js: 3.6.1
+      global: 4.4.0
+      lodash: 4.17.21
+      markdown-to-jsx: 6.11.4
+      memoizerific: 1.11.3
+      polished: 4.2.2
+      qs: 6.11.0
+      react-draggable: 4.4.5
+      react-helmet-async: 1.3.0
+      react-sizeme: 3.0.2
+      regenerator-runtime: 0.13.9
+      resolve-from: 5.0.0
+      store2: 2.14.2
+    transitivePeerDependencies:
+      - '@types/react'
+    dev: true
+
+  /@storybook/ui/6.2.9_wcqkhtmu7mswc6yz4uyexck3ty:
+    resolution: {integrity: 
sha512-jq2xmw3reIqik/6ibUSbNKGR+Xvr9wkAEwexiOl+5WQ5BeYJpw4dmDmsFQf+SQuWaSEUUPolbzkakRQM778Kdg==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0
+      react-dom: ^16.8.0 || ^17.0.0
+    dependencies:
+      '@emotion/core': 10.3.1_react@16.14.0
+      '@storybook/addons': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/api': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/channels': 6.2.9
+      '@storybook/client-logger': 6.2.9
+      '@storybook/components': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/core-events': 6.2.9
+      '@storybook/router': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/semver': 7.3.2
+      '@storybook/theming': 6.2.9_wcqkhtmu7mswc6yz4uyexck3ty
+      '@types/markdown-to-jsx': 6.11.3
+      copy-to-clipboard: 3.3.2
+      core-js: 3.26.0
+      core-js-pure: 3.20.2
+      downshift: 6.1.12_react@16.14.0
+      emotion-theming: 10.3.0_qzeatvug73zaio2r3dlvejynye
+      fuse.js: 3.6.1
+      global: 4.4.0
+      lodash: 4.17.21
+      markdown-to-jsx: 6.11.4_react@16.14.0
+      memoizerific: 1.11.3
+      polished: 4.2.2
+      qs: 6.11.0
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      react-draggable: 4.4.5_wcqkhtmu7mswc6yz4uyexck3ty
+      react-helmet-async: 1.3.0_wcqkhtmu7mswc6yz4uyexck3ty
+      react-sizeme: 3.0.2
+      regenerator-runtime: 0.13.9
+      resolve-from: 5.0.0
+      store2: 2.14.2
+    transitivePeerDependencies:
+      - '@types/react'
+    dev: true
+
+  /@storybook/ui/6.5.13_wcqkhtmu7mswc6yz4uyexck3ty:
+    resolution: {integrity: 
sha512-MklJuSg4Bc+MWjwhZVmZhJaucaeEBUMMa2V9oRWbIgZOdRHqdW72S2vCbaarDAYfBQdnfaoq1GkSQiw+EnWOzA==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      '@storybook/addons': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/api': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/channels': 6.5.13
+      '@storybook/client-logger': 6.5.13
+      '@storybook/components': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/core-events': 6.5.13
+      '@storybook/router': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      '@storybook/semver': 7.3.2
+      '@storybook/theming': 6.5.13_wcqkhtmu7mswc6yz4uyexck3ty
+      core-js: 3.26.0
+      memoizerific: 1.11.3
+      qs: 6.11.0
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      regenerator-runtime: 0.13.9
+      resolve-from: 5.0.0
+    dev: true
+
+  /@surma/rollup-plugin-off-main-thread/1.4.2:
+    resolution: {integrity: 
sha512-yBMPqmd1yEJo/280PAMkychuaALyQ9Lkb5q1ck3mjJrFuEobIfhnQ4J3mbvBoISmR3SWMWV+cGB/I0lCQee79A==}
+    dependencies:
+      ejs: 2.7.4
+      magic-string: 0.25.9
+    dev: true
+
+  /@surma/rollup-plugin-off-main-thread/2.2.3:
+    resolution: {integrity: 
sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==}
+    dependencies:
+      ejs: 3.1.6
+      json5: 2.2.1
+      magic-string: 0.25.9
+      string.prototype.matchall: 4.0.6
+    dev: true
+
+  /@szmarczak/http-timer/1.1.2:
+    resolution: {integrity: 
sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==}
+    engines: {node: '>=6'}
+    dependencies:
+      defer-to-connect: 1.1.3
+    dev: true
+
+  /@testing-library/dom/7.31.2:
+    resolution: {integrity: 
sha512-3UqjCpey6HiTZT92vODYLPxTBWlM8ZOOjr3LX5F37/VRipW2M1kX6I/Cm4VXzteZqfGfagg8yXywpcOgQBlNsQ==}
+    engines: {node: '>=10'}
+    dependencies:
+      '@babel/code-frame': 7.16.7
+      '@babel/runtime': 7.17.8
+      '@types/aria-query': 4.2.2
+      aria-query: 4.2.2
+      chalk: 4.1.2
+      dom-accessibility-api: 0.5.7
+      lz-string: 1.4.4
+      pretty-format: 26.6.2
+    dev: true
+
+  /@testing-library/jest-dom/5.16.5:
+    resolution: {integrity: 
sha512-N5ixQ2qKpi5OLYfwQmUb/5mSV9LneAcaUfp32pn4yCnpb8r/Yz0pXFPck21dIicKmi+ta5WRAknkZCfA8refMA==}
+    engines: {node: '>=8', npm: '>=6', yarn: '>=1'}
+    dependencies:
+      '@adobe/css-tools': 4.0.1
+      '@babel/runtime': 7.17.8
+      '@types/testing-library__jest-dom': 5.14.5
+      aria-query: 5.1.1
+      chalk: 3.0.0
+      css.escape: 1.5.1
+      dom-accessibility-api: 0.5.7
+      lodash: 4.17.21
+      redent: 3.0.0
+    dev: true
+
+  /@testing-library/preact-hooks/1.1.0_p7poi7nh2j5v3fg73wd3em3ise:
+    resolution: {integrity: 
sha512-+JIor+NsOHkK3oIrwMDGKGHXTN0JJi462dBJlj4FNbGaDPTlctE6eu2ranWQirh7/FJMkWfzQCP+tk7jmY8ZrQ==}
+    peerDependencies:
+      '@testing-library/preact': ^2.0.0
+      preact: ^10.4.8
+    dependencies:
+      '@testing-library/preact': 2.0.1_preact@10.6.1
+      preact: 10.6.1
+    dev: true
+
+  /@testing-library/preact-hooks/1.1.0_vfcmu6iy7nffpurikpgxo6gwxi:
+    resolution: {integrity: 
sha512-+JIor+NsOHkK3oIrwMDGKGHXTN0JJi462dBJlj4FNbGaDPTlctE6eu2ranWQirh7/FJMkWfzQCP+tk7jmY8ZrQ==}
+    peerDependencies:
+      '@testing-library/preact': ^2.0.0
+      preact: ^10.4.8
+    dependencies:
+      '@testing-library/preact': 2.0.1_preact@10.6.5
+      preact: 10.6.5
+    dev: true
+
+  /@testing-library/preact/2.0.1_preact@10.6.1:
+    resolution: {integrity: 
sha512-79kwVOY+3caoLgaPbiPzikjgY0Aya7Fc7TvGtR1upCnz2wrtmPDnN2t9vO7I7vDP2zoA+feSwOH5Q0BFErhaaQ==}
+    engines: {node: '>= 10'}
+    peerDependencies:
+      preact: '>=10 || ^10.0.0-alpha.0 || ^10.0.0-beta.0'
+    dependencies:
+      '@testing-library/dom': 7.31.2
+      preact: 10.6.1
+    dev: true
+
+  /@testing-library/preact/2.0.1_preact@10.6.5:
+    resolution: {integrity: 
sha512-79kwVOY+3caoLgaPbiPzikjgY0Aya7Fc7TvGtR1upCnz2wrtmPDnN2t9vO7I7vDP2zoA+feSwOH5Q0BFErhaaQ==}
+    engines: {node: '>= 10'}
+    peerDependencies:
+      preact: '>=10 || ^10.0.0-alpha.0 || ^10.0.0-beta.0'
+    dependencies:
+      '@testing-library/dom': 7.31.2
+      preact: 10.6.5
+    dev: true
+
+  /@tootallnate/once/1.1.2:
+    resolution: {integrity: 
sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==}
+    engines: {node: '>= 6'}
+    dev: true
+
+  /@trysound/sax/0.2.0:
+    resolution: {integrity: 
sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
+    engines: {node: '>=10.13.0'}
+    dev: true
+
+  /@types/aria-query/4.2.2:
+    resolution: {integrity: 
sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==}
+    dev: true
+
+  /@types/babel__core/7.1.19:
+    resolution: {integrity: 
sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==}
+    dependencies:
+      '@babel/parser': 7.18.4
+      '@babel/types': 7.18.4
+      '@types/babel__generator': 7.6.4
+      '@types/babel__template': 7.4.1
+      '@types/babel__traverse': 7.18.2
+    dev: true
+
+  /@types/babel__generator/7.6.4:
+    resolution: {integrity: 
sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==}
+    dependencies:
+      '@babel/types': 7.19.4
+    dev: true
+
+  /@types/babel__template/7.4.1:
+    resolution: {integrity: 
sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==}
+    dependencies:
+      '@babel/parser': 7.19.6
+      '@babel/types': 7.19.4
+    dev: true
+
+  /@types/babel__traverse/7.18.2:
+    resolution: {integrity: 
sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==}
+    dependencies:
+      '@babel/types': 7.19.4
+    dev: true
+
+  /@types/body-parser/1.19.2:
+    resolution: {integrity: 
sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==}
+    dependencies:
+      '@types/connect': 3.4.35
+      '@types/node': 18.8.5
+    dev: true
+
+  /@types/bonjour/3.5.10:
+    resolution: {integrity: 
sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==}
+    dependencies:
+      '@types/node': 18.8.5
+    dev: true
+
+  /@types/braces/3.0.1:
+    resolution: {integrity: 
sha512-+euflG6ygo4bn0JHtn4pYqcXwRtLvElQ7/nnjDu7iYG56H0+OhCd7d6Ug0IE3WcFpZozBKW2+80FUbv5QGk5AQ==}
+    dev: true
+
+  /@types/chai/4.3.0:
+    resolution: {integrity: 
sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw==}
+
+  /@types/cheerio/0.22.31:
+    resolution: {integrity: 
sha512-Kt7Cdjjdi2XWSfrZ53v4Of0wG3ZcmaegFXjMmz9tfNrZSkzzo36G0AL1YqSdcIA78Etjt6E609pt5h1xnQkPUw==}
+    dependencies:
+      '@types/node': 18.8.5
+    dev: true
+
+  /@types/chrome/0.0.197:
+    resolution: {integrity: 
sha512-m1NfS5bOjaypyqQfaX6CxmJodZVcvj5+Mt/K94EBHkflYjPNmXHAzbxfifdLMa0YM3PDyOxohoTS5ug/e6p5jA==}
+    dependencies:
+      '@types/filesystem': 0.0.32
+      '@types/har-format': 1.2.9
+    dev: true
+
+  /@types/color-convert/2.0.0:
+    resolution: {integrity: 
sha512-m7GG7IKKGuJUXvkZ1qqG3ChccdIM/qBBo913z+Xft0nKCX4hAU/IxKwZBU4cpRZ7GS5kV4vOblUkILtSShCPXQ==}
+    dependencies:
+      '@types/color-name': 1.1.1
+    dev: true
+
+  /@types/color-name/1.1.1:
+    resolution: {integrity: 
sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==}
+    dev: true
+
+  /@types/connect-history-api-fallback/1.3.5:
+    resolution: {integrity: 
sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==}
+    dependencies:
+      '@types/express-serve-static-core': 4.17.28
+      '@types/node': 18.8.5
+    dev: true
+
+  /@types/connect/3.4.35:
+    resolution: {integrity: 
sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==}
+    dependencies:
+      '@types/node': 18.8.5
+    dev: true
+
+  /@types/enzyme/3.10.12:
+    resolution: {integrity: 
sha512-xryQlOEIe1TduDWAOphR0ihfebKFSWOXpIsk+70JskCfRfW+xALdnJ0r1ZOTo85F9Qsjk6vtlU7edTYHbls9tA==}
+    dependencies:
+      '@types/cheerio': 0.22.31
+      '@types/react': 18.0.21
+    dev: true
+
+  /@types/estree/0.0.39:
+    resolution: {integrity: 
sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==}
+    dev: true
+
+  /@types/estree/1.0.0:
+    resolution: {integrity: 
sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==}
+    dev: true
+
+  /@types/express-serve-static-core/4.17.28:
+    resolution: {integrity: 
sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==}
+    dependencies:
+      '@types/node': 18.8.5
+      '@types/qs': 6.9.7
+      '@types/range-parser': 1.2.4
+    dev: true
+
+  /@types/express/4.17.13:
+    resolution: {integrity: 
sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==}
+    dependencies:
+      '@types/body-parser': 1.19.2
+      '@types/express-serve-static-core': 4.17.28
+      '@types/qs': 6.9.7
+      '@types/serve-static': 1.13.10
+    dev: true
+
+  /@types/filesystem/0.0.32:
+    resolution: {integrity: 
sha512-Yuf4jR5YYMR2DVgwuCiP11s0xuVRyPKmz8vo6HBY3CGdeMj8af93CFZX+T82+VD1+UqHOxTq31lO7MI7lepBtQ==}
+    dependencies:
+      '@types/filewriter': 0.0.29
+    dev: true
+
+  /@types/filewriter/0.0.29:
+    resolution: {integrity: 
sha512-BsPXH/irW0ht0Ji6iw/jJaK8Lj3FJemon2gvEqHKpCdDCeemHa+rI3WBGq5z7cDMZgoLjY40oninGxqk+8NzNQ==}
+    dev: true
+
+  /@types/glob-base/0.3.0:
+    resolution: {integrity: 
sha512-NRCU51ALpNedUvwiwifAkDIWIC25MqF9+0STzAzvhlzR5U+iHTiaUlZ1iOMCwqZAU05X9UlqL63FVrZTZ6tySA==}
+    dev: true
+
+  /@types/glob/7.2.0:
+    resolution: {integrity: 
sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==}
+    dependencies:
+      '@types/minimatch': 5.1.2
+      '@types/node': 18.8.5
+    dev: true
+
+  /@types/glob/8.0.0:
+    resolution: {integrity: 
sha512-l6NQsDDyQUVeoTynNpC9uRvCUint/gSUXQA2euwmTuWGvPY5LSDUu6tkCtJB2SvGQlJQzLaKqcGZP4//7EDveA==}
+    dependencies:
+      '@types/minimatch': 5.1.2
+      '@types/node': 18.8.5
+    dev: true
+
+  /@types/graceful-fs/4.1.5:
+    resolution: {integrity: 
sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==}
+    dependencies:
+      '@types/node': 18.8.5
+    dev: true
+
+  /@types/har-format/1.2.9:
+    resolution: {integrity: 
sha512-rffW6MhQ9yoa75bdNi+rjZBAvu2HhehWJXlhuWXnWdENeuKe82wUgAwxYOb7KRKKmxYN+D/iRKd2NDQMLqlUmg==}
+    dev: true
+
+  /@types/hast/2.3.4:
+    resolution: {integrity: 
sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==}
+    dependencies:
+      '@types/unist': 2.0.6
+    dev: true
+
+  /@types/history/4.7.9:
+    resolution: {integrity: 
sha512-MUc6zSmU3tEVnkQ78q0peeEjKWPUADMlC/t++2bI8WnAG2tvYRPIgHG8lWkXwqc8MsUF6Z2MOf+Mh5sazOmhiQ==}
+    dev: true
+
+  /@types/html-minifier-terser/5.1.2:
+    resolution: {integrity: 
sha512-h4lTMgMJctJybDp8CQrxTUiiYmedihHWkjnF/8Pxseu2S6Nlfcy8kwboQ8yejh456rP2yWoEVm1sS/FVsfM48w==}
+    dev: true
+
+  /@types/http-proxy/1.17.8:
+    resolution: {integrity: 
sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA==}
+    dependencies:
+      '@types/node': 18.8.5
+    dev: true
+
+  /@types/is-function/1.0.1:
+    resolution: {integrity: 
sha512-A79HEEiwXTFtfY+Bcbo58M2GRYzCr9itHWzbzHVFNEYCcoU/MMGwYYf721gBrnhpj1s6RGVVha/IgNFnR0Iw/Q==}
+    dev: true
+
+  /@types/istanbul-lib-coverage/2.0.3:
+    resolution: {integrity: 
sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==}
+    dev: true
+
+  /@types/istanbul-lib-coverage/2.0.4:
+    resolution: {integrity: 
sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==}
+    dev: true
+
+  /@types/istanbul-lib-report/3.0.0:
+    resolution: {integrity: 
sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==}
+    dependencies:
+      '@types/istanbul-lib-coverage': 2.0.4
+    dev: true
+
+  /@types/istanbul-reports/3.0.1:
+    resolution: {integrity: 
sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==}
+    dependencies:
+      '@types/istanbul-lib-report': 3.0.0
+    dev: true
+
+  /@types/jest/26.0.24:
+    resolution: {integrity: 
sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w==}
+    dependencies:
+      jest-diff: 26.6.2
+      pretty-format: 26.6.2
+    dev: true
+
+  /@types/jest/27.5.2:
+    resolution: {integrity: 
sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==}
+    dependencies:
+      jest-matcher-utils: 27.5.1
+      pretty-format: 27.5.1
+    dev: true
+
+  /@types/json-schema/7.0.11:
+    resolution: {integrity: 
sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==}
+    dev: true
+
+  /@types/json5/0.0.29:
+    resolution: {integrity: sha1-7ihweulOEdK4J7y+UnC86n8+ce4=}
+    dev: true
+
+  /@types/keyv/3.1.4:
+    resolution: {integrity: 
sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==}
+    dependencies:
+      '@types/node': 18.8.5
+    dev: true
+
+  /@types/lodash/4.14.186:
+    resolution: {integrity: 
sha512-eHcVlLXP0c2FlMPm56ITode2AgLMSa6aJ05JTTbYbI+7EMkCEE5qk2E41d5g2lCVTqRe0GnnRFurmlCsDODrPw==}
+
+  /@types/markdown-to-jsx/6.11.3:
+    resolution: {integrity: 
sha512-30nFYpceM/ZEvhGiqWjm5quLUxNeld0HCzJEXMZZDpq53FPkS85mTwkWtCXzCqq8s5JYLgM5W392a02xn8Bdaw==}
+    dependencies:
+      '@types/react': 18.0.21
+    dev: true
+
+  /@types/mdast/3.0.10:
+    resolution: {integrity: 
sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==}
+    dependencies:
+      '@types/unist': 2.0.6
+    dev: true
+
+  /@types/micromatch/4.0.2:
+    resolution: {integrity: 
sha512-oqXqVb0ci19GtH0vOA/U2TmHTcRY9kuZl4mqUxe0QmJAlIW13kzhuK5pi1i9+ngav8FjpSb9FVS/GE00GLX1VA==}
+    dependencies:
+      '@types/braces': 3.0.1
+    dev: true
+
+  /@types/mime/1.3.2:
+    resolution: {integrity: 
sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==}
+    dev: true
+
+  /@types/minimatch/5.1.2:
+    resolution: {integrity: 
sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==}
+    dev: true
+
+  /@types/mocha/8.2.3:
+    resolution: {integrity: 
sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==}
+    dev: true
+
+  /@types/mocha/9.0.0:
+    resolution: {integrity: 
sha512-scN0hAWyLVAvLR9AyW7HoFF5sJZglyBsbPuHO4fv7JRvfmPBMfp1ozWqOf/e4wwPNxezBZXRfWzMb6iFLgEVRA==}
+    dev: true
+
+  /@types/mustache/4.2.1:
+    resolution: {integrity: 
sha512-gFAlWL9Ik21nJioqjlGCnNYbf9zHi0sVbaZ/1hQEBcCEuxfLJDvz4bVJSV6v6CUaoLOz0XEIoP7mSrhJ6o237w==}
+    dev: true
+
+  /@types/node-fetch/2.6.2:
+    resolution: {integrity: 
sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==}
+    dependencies:
+      '@types/node': 18.8.5
+      form-data: 3.0.1
+    dev: true
+
+  /@types/node/14.18.32:
+    resolution: {integrity: 
sha512-Y6S38pFr04yb13qqHf8uk1nHE3lXgQ30WZbv1mLliV9pt0NjvqdWttLcrOYLnXbOafknVYRHZGoMSpR9UwfYow==}
+    dev: true
+
+  /@types/node/16.18.0:
+    resolution: {integrity: 
sha512-LqYqYzYvnbCaQfLAwRt0zboqnsViwhZm+vjaMSqcfN36vulAg7Pt0T83q4WZO2YOBw3XdyHi8cQ88H22zmULOA==}
+    dev: true
+
+  /@types/node/18.8.5:
+    resolution: {integrity: 
sha512-Bq7G3AErwe5A/Zki5fdD3O6+0zDChhg671NfPjtIcbtzDNZTv4NPKMRFr7gtYPG7y+B8uTiNK4Ngd9T0FTar6Q==}
+
+  /@types/normalize-package-data/2.4.1:
+    resolution: {integrity: 
sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==}
+    dev: true
+
+  /@types/npmlog/4.1.4:
+    resolution: {integrity: 
sha512-WKG4gTr8przEZBiJ5r3s8ZIAoMXNbOgQ+j/d5O4X3x6kZJRLNvyUJuUK/KoG3+8BaOHPhp2m7WC6JKKeovDSzQ==}
+    dev: true
+
+  /@types/offscreencanvas/2019.7.0:
+    resolution: {integrity: 
sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg==}
+    dev: false
+
+  /@types/overlayscrollbars/1.12.1:
+    resolution: {integrity: 
sha512-V25YHbSoKQN35UasHf0EKD9U2vcmexRSp78qa8UglxFH8H3D+adEa9zGZwrqpH4TdvqeMrgMqVqsLB4woAryrQ==}
+    dev: true
+
+  /@types/parse-json/4.0.0:
+    resolution: {integrity: 
sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==}
+    dev: true
+
+  /@types/parse5/5.0.3:
+    resolution: {integrity: 
sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==}
+    dev: true
+
+  /@types/prettier/2.7.1:
+    resolution: {integrity: 
sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==}
+    dev: true
+
+  /@types/pretty-hrtime/1.0.1:
+    resolution: {integrity: 
sha512-VjID5MJb1eGKthz2qUerWT8+R4b9N+CHvGCzg9fn4kWZgaF9AhdYikQio3R7wV8YY1NsQKPaCwKz1Yff+aHNUQ==}
+    dev: true
+
+  /@types/prop-types/15.7.5:
+    resolution: {integrity: 
sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==}
+    dev: true
+
+  /@types/q/1.5.5:
+    resolution: {integrity: 
sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==}
+    dev: true
+
+  /@types/qs/6.9.7:
+    resolution: {integrity: 
sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==}
+    dev: true
+
+  /@types/range-parser/1.2.4:
+    resolution: {integrity: 
sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==}
+    dev: true
+
+  /@types/reach__router/1.3.11:
+    resolution: {integrity: 
sha512-j23ChnIEiW8aAP4KT8OVyTXOFr+Ri65BDnwzmfHFO9WHypXYevHFjeil1Cj7YH3emfCE924BwAmgW4hOv7Wg3g==}
+    dependencies:
+      '@types/react': 18.0.21
+    dev: true
+
+  /@types/react-syntax-highlighter/11.0.5:
+    resolution: {integrity: 
sha512-VIOi9i2Oj5XsmWWoB72p3KlZoEbdRAcechJa8Ztebw7bDl2YmR+odxIqhtJGp1q2EozHs02US+gzxJ9nuf56qg==}
+    dependencies:
+      '@types/react': 18.0.21
+    dev: true
+
+  /@types/react/18.0.21:
+    resolution: {integrity: 
sha512-7QUCOxvFgnD5Jk8ZKlUAhVcRj7GuJRjnjjiY/IUBWKgOlnvDvTMLD4RTF7NPyVmbRhNrbomZiOepg7M/2Kj1mA==}
+    dependencies:
+      '@types/prop-types': 15.7.5
+      '@types/scheduler': 0.16.2
+      csstype: 3.1.1
+    dev: true
+
+  /@types/resolve/0.0.8:
+    resolution: {integrity: 
sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==}
+    dependencies:
+      '@types/node': 18.8.5
+    dev: true
+
+  /@types/resolve/1.17.1:
+    resolution: {integrity: 
sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==}
+    dependencies:
+      '@types/node': 18.8.5
+    dev: true
+
+  /@types/responselike/1.0.0:
+    resolution: {integrity: 
sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==}
+    dependencies:
+      '@types/node': 18.8.5
+    dev: true
+
+  /@types/retry/0.12.1:
+    resolution: {integrity: 
sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==}
+    dev: true
+
+  /@types/scheduler/0.16.2:
+    resolution: {integrity: 
sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==}
+    dev: true
+
+  /@types/semver/7.3.12:
+    resolution: {integrity: 
sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A==}
+    dev: true
+
+  /@types/serve-index/1.9.1:
+    resolution: {integrity: 
sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==}
+    dependencies:
+      '@types/express': 4.17.13
+    dev: true
+
+  /@types/serve-static/1.13.10:
+    resolution: {integrity: 
sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==}
+    dependencies:
+      '@types/mime': 1.3.2
+      '@types/node': 18.8.5
+    dev: true
+
+  /@types/sockjs/0.3.33:
+    resolution: {integrity: 
sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==}
+    dependencies:
+      '@types/node': 18.8.5
+    dev: true
+
+  /@types/source-list-map/0.1.2:
+    resolution: {integrity: 
sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==}
+    dev: true
+
+  /@types/stack-utils/2.0.1:
+    resolution: {integrity: 
sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==}
+    dev: true
+
+  /@types/tapable/1.0.8:
+    resolution: {integrity: 
sha512-ipixuVrh2OdNmauvtT51o3d8z12p6LtFW9in7U79der/kwejjdNchQC5UMn5u/KxNoM7VHHOs/l8KS8uHxhODQ==}
+    dev: true
+
+  /@types/testing-library__jest-dom/5.14.5:
+    resolution: {integrity: 
sha512-SBwbxYoyPIvxHbeHxTZX2Pe/74F/tX2/D3mMvzabdeJ25bBojfW0TyB8BHrbq/9zaaKICJZjLP+8r6AeZMFCuQ==}
+    dependencies:
+      '@types/jest': 27.5.2
+    dev: true
+
+  /@types/trusted-types/2.0.2:
+    resolution: {integrity: 
sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==}
+    dev: true
+
+  /@types/uglify-js/3.13.1:
+    resolution: {integrity: 
sha512-O3MmRAk6ZuAKa9CHgg0Pr0+lUOqoMLpc9AS4R8ano2auvsg7IE8syF3Xh/NPr26TWklxYcqoEEFdzLLs1fV9PQ==}
+    dependencies:
+      source-map: 0.6.1
+    dev: true
+
+  /@types/unist/2.0.6:
+    resolution: {integrity: 
sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==}
+    dev: true
+
+  /@types/webpack-env/1.18.0:
+    resolution: {integrity: 
sha512-56/MAlX5WMsPVbOg7tAxnYvNYMMWr/QJiIp6BxVSW3JJXUVzzOn64qW8TzQyMSqSUFM2+PVI4aUHcHOzIz/1tg==}
+    dev: true
+
+  /@types/webpack-sources/3.2.0:
+    resolution: {integrity: 
sha512-Ft7YH3lEVRQ6ls8k4Ff1oB4jN6oy/XmU6tQISKdhfh+1mR+viZFphS6WL0IrtDOzvefmJg5a0s7ZQoRXwqTEFg==}
+    dependencies:
+      '@types/node': 18.8.5
+      '@types/source-list-map': 0.1.2
+      source-map: 0.7.3
+    dev: true
+
+  /@types/webpack/4.41.32:
+    resolution: {integrity: 
sha512-cb+0ioil/7oz5//7tZUSwbrSAN/NWHrQylz5cW8G0dWTcF/g+/dSdMlKVZspBYuMAN1+WnwHrkxiRrLcwd0Heg==}
+    dependencies:
+      '@types/node': 18.8.5
+      '@types/tapable': 1.0.8
+      '@types/uglify-js': 3.13.1
+      '@types/webpack-sources': 3.2.0
+      anymatch: 3.1.2
+      source-map: 0.6.1
+    dev: true
+
+  /@types/ws/8.2.2:
+    resolution: {integrity: 
sha512-NOn5eIcgWLOo6qW8AcuLZ7G8PycXu0xTxxkS6Q18VWFxgPUSOwV0pBj2a/4viNZVu25i7RIB7GttdkAIUUXOOg==}
+    dependencies:
+      '@types/node': 18.8.5
+    dev: true
+
+  /@types/yargs-parser/20.2.1:
+    resolution: {integrity: 
sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==}
+    dev: true
+
+  /@types/yargs/15.0.14:
+    resolution: {integrity: 
sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==}
+    dependencies:
+      '@types/yargs-parser': 20.2.1
+    dev: true
+
+  /@types/yargs/16.0.4:
+    resolution: {integrity: 
sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==}
+    dependencies:
+      '@types/yargs-parser': 20.2.1
+    dev: true
+
+  /@types/yargs/17.0.13:
+    resolution: {integrity: 
sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==}
+    dependencies:
+      '@types/yargs-parser': 20.2.1
+    dev: true
+
+  /@typescript-eslint/eslint-plugin/4.33.0_k4l66av2tbo6kxzw52jzgbfzii:
+    resolution: {integrity: 
sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==}
+    engines: {node: ^10.12.0 || >=12.0.0}
+    peerDependencies:
+      '@typescript-eslint/parser': ^4.0.0
+      eslint: ^5.0.0 || ^6.0.0 || ^7.0.0
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+    dependencies:
+      '@typescript-eslint/experimental-utils': 
4.33.0_3rubbgt5ekhqrcgx4uwls3neim
+      '@typescript-eslint/parser': 4.33.0_3rubbgt5ekhqrcgx4uwls3neim
+      '@typescript-eslint/scope-manager': 4.33.0
+      debug: 4.3.4
+      eslint: 7.32.0
+      functional-red-black-tree: 1.0.1
+      ignore: 5.2.0
+      regexpp: 3.2.0
+      semver: 7.3.8
+      tsutils: 3.21.0_typescript@4.8.4
+      typescript: 4.8.4
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@typescript-eslint/eslint-plugin/5.36.1_gjcw3hhr2cxnngiu5lw4bi633m:
+    resolution: {integrity: 
sha512-iC40UK8q1tMepSDwiLbTbMXKDxzNy+4TfPWgIL661Ym0sD42vRcQU93IsZIrmi+x292DBr60UI/gSwfdVYexCA==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    peerDependencies:
+      '@typescript-eslint/parser': ^5.0.0
+      eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+    dependencies:
+      '@typescript-eslint/parser': 5.36.1_o2nrgn6wwxunlqlzzokx4es3q4
+      '@typescript-eslint/scope-manager': 5.36.1
+      '@typescript-eslint/type-utils': 5.36.1_o2nrgn6wwxunlqlzzokx4es3q4
+      '@typescript-eslint/utils': 5.36.1_o2nrgn6wwxunlqlzzokx4es3q4
+      debug: 4.3.4
+      eslint: 8.8.0
+      functional-red-black-tree: 1.0.1
+      ignore: 5.2.0
+      regexpp: 3.2.0
+      semver: 7.3.7
+      tsutils: 3.21.0_typescript@4.8.4
+      typescript: 4.8.4
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@typescript-eslint/experimental-utils/4.33.0_3rubbgt5ekhqrcgx4uwls3neim:
+    resolution: {integrity: 
sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==}
+    engines: {node: ^10.12.0 || >=12.0.0}
+    peerDependencies:
+      eslint: '*'
+    dependencies:
+      '@types/json-schema': 7.0.11
+      '@typescript-eslint/scope-manager': 4.33.0
+      '@typescript-eslint/types': 4.33.0
+      '@typescript-eslint/typescript-estree': 4.33.0_typescript@4.8.4
+      eslint: 7.32.0
+      eslint-scope: 5.1.1
+      eslint-utils: 3.0.0_eslint@7.32.0
+    transitivePeerDependencies:
+      - supports-color
+      - typescript
+    dev: true
+
+  /@typescript-eslint/experimental-utils/5.40.1_3rubbgt5ekhqrcgx4uwls3neim:
+    resolution: {integrity: 
sha512-lynjgnQuoCgxtYgYWjoQqijk0kYQNiztnVhoqha3N0kMYFVPURidzCq2vn9XvUUu2XxP130ZRKVDKyeGa2bhbw==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    peerDependencies:
+      eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
+    dependencies:
+      '@typescript-eslint/utils': 5.40.1_3rubbgt5ekhqrcgx4uwls3neim
+      eslint: 7.32.0
+    transitivePeerDependencies:
+      - supports-color
+      - typescript
+    dev: true
+
+  /@typescript-eslint/experimental-utils/5.40.1_o2nrgn6wwxunlqlzzokx4es3q4:
+    resolution: {integrity: 
sha512-lynjgnQuoCgxtYgYWjoQqijk0kYQNiztnVhoqha3N0kMYFVPURidzCq2vn9XvUUu2XxP130ZRKVDKyeGa2bhbw==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    peerDependencies:
+      eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
+    dependencies:
+      '@typescript-eslint/utils': 5.40.1_o2nrgn6wwxunlqlzzokx4es3q4
+      eslint: 8.8.0
+    transitivePeerDependencies:
+      - supports-color
+      - typescript
+    dev: true
+
+  /@typescript-eslint/parser/4.33.0_3rubbgt5ekhqrcgx4uwls3neim:
+    resolution: {integrity: 
sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==}
+    engines: {node: ^10.12.0 || >=12.0.0}
+    peerDependencies:
+      eslint: ^5.0.0 || ^6.0.0 || ^7.0.0
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+    dependencies:
+      '@typescript-eslint/scope-manager': 4.33.0
+      '@typescript-eslint/types': 4.33.0
+      '@typescript-eslint/typescript-estree': 4.33.0_typescript@4.8.4
+      debug: 4.3.4
+      eslint: 7.32.0
+      typescript: 4.8.4
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@typescript-eslint/parser/5.36.1_o2nrgn6wwxunlqlzzokx4es3q4:
+    resolution: {integrity: 
sha512-/IsgNGOkBi7CuDfUbwt1eOqUXF9WGVBW9dwEe1pi+L32XrTsZIgmDFIi2RxjzsvB/8i+MIf5JIoTEH8LOZ368A==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    peerDependencies:
+      eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+    dependencies:
+      '@typescript-eslint/scope-manager': 5.36.1
+      '@typescript-eslint/types': 5.36.1
+      '@typescript-eslint/typescript-estree': 5.36.1_typescript@4.8.4
+      debug: 4.3.4
+      eslint: 8.8.0
+      typescript: 4.8.4
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@typescript-eslint/scope-manager/4.33.0:
+    resolution: {integrity: 
sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==}
+    engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1}
+    dependencies:
+      '@typescript-eslint/types': 4.33.0
+      '@typescript-eslint/visitor-keys': 4.33.0
+    dev: true
+
+  /@typescript-eslint/scope-manager/5.36.1:
+    resolution: {integrity: 
sha512-pGC2SH3/tXdu9IH3ItoqciD3f3RRGCh7hb9zPdN2Drsr341zgd6VbhP5OHQO/reUqihNltfPpMpTNihFMarP2w==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    dependencies:
+      '@typescript-eslint/types': 5.36.1
+      '@typescript-eslint/visitor-keys': 5.36.1
+    dev: true
+
+  /@typescript-eslint/scope-manager/5.40.1:
+    resolution: {integrity: 
sha512-jkn4xsJiUQucI16OLCXrLRXDZ3afKhOIqXs4R3O+M00hdQLKR58WuyXPZZjhKLFCEP2g+TXdBRtLQ33UfAdRUg==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    dependencies:
+      '@typescript-eslint/types': 5.40.1
+      '@typescript-eslint/visitor-keys': 5.40.1
+    dev: true
+
+  /@typescript-eslint/type-utils/5.36.1_o2nrgn6wwxunlqlzzokx4es3q4:
+    resolution: {integrity: 
sha512-xfZhfmoQT6m3lmlqDvDzv9TiCYdw22cdj06xY0obSznBsT///GK5IEZQdGliXpAOaRL34o8phEvXzEo/VJx13Q==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    peerDependencies:
+      eslint: '*'
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+    dependencies:
+      '@typescript-eslint/typescript-estree': 5.36.1_typescript@4.8.4
+      '@typescript-eslint/utils': 5.36.1_o2nrgn6wwxunlqlzzokx4es3q4
+      debug: 4.3.4
+      eslint: 8.8.0
+      tsutils: 3.21.0_typescript@4.8.4
+      typescript: 4.8.4
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@typescript-eslint/types/4.33.0:
+    resolution: {integrity: 
sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==}
+    engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1}
+    dev: true
+
+  /@typescript-eslint/types/5.36.1:
+    resolution: {integrity: 
sha512-jd93ShpsIk1KgBTx9E+hCSEuLCUFwi9V/urhjOWnOaksGZFbTOxAT47OH2d4NLJnLhkVD+wDbB48BuaycZPLBg==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    dev: true
+
+  /@typescript-eslint/types/5.40.1:
+    resolution: {integrity: 
sha512-Icg9kiuVJSwdzSQvtdGspOlWNjVDnF3qVIKXdJ103o36yRprdl3Ge5cABQx+csx960nuMF21v8qvO31v9t3OHw==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    dev: true
+
+  /@typescript-eslint/typescript-estree/4.33.0_typescript@4.8.4:
+    resolution: {integrity: 
sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==}
+    engines: {node: ^10.12.0 || >=12.0.0}
+    peerDependencies:
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+    dependencies:
+      '@typescript-eslint/types': 4.33.0
+      '@typescript-eslint/visitor-keys': 4.33.0
+      debug: 4.3.4
+      globby: 11.1.0
+      is-glob: 4.0.3
+      semver: 7.3.8
+      tsutils: 3.21.0_typescript@4.8.4
+      typescript: 4.8.4
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@typescript-eslint/typescript-estree/5.36.1_typescript@4.8.4:
+    resolution: {integrity: 
sha512-ih7V52zvHdiX6WcPjsOdmADhYMDN15SylWRZrT2OMy80wzKbc79n8wFW0xpWpU0x3VpBz/oDgTm2xwDAnFTl+g==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    peerDependencies:
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+    dependencies:
+      '@typescript-eslint/types': 5.36.1
+      '@typescript-eslint/visitor-keys': 5.36.1
+      debug: 4.3.4
+      globby: 11.1.0
+      is-glob: 4.0.3
+      semver: 7.3.8
+      tsutils: 3.21.0_typescript@4.8.4
+      typescript: 4.8.4
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@typescript-eslint/typescript-estree/5.40.1_typescript@4.8.4:
+    resolution: {integrity: 
sha512-5QTP/nW5+60jBcEPfXy/EZL01qrl9GZtbgDZtDPlfW5zj/zjNrdI2B5zMUHmOsfvOr2cWqwVdWjobCiHcedmQA==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    peerDependencies:
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+    dependencies:
+      '@typescript-eslint/types': 5.40.1
+      '@typescript-eslint/visitor-keys': 5.40.1
+      debug: 4.3.4
+      globby: 11.1.0
+      is-glob: 4.0.3
+      semver: 7.3.8
+      tsutils: 3.21.0_typescript@4.8.4
+      typescript: 4.8.4
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@typescript-eslint/utils/5.36.1_o2nrgn6wwxunlqlzzokx4es3q4:
+    resolution: {integrity: 
sha512-lNj4FtTiXm5c+u0pUehozaUWhh7UYKnwryku0nxJlYUEWetyG92uw2pr+2Iy4M/u0ONMKzfrx7AsGBTCzORmIg==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    peerDependencies:
+      eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
+    dependencies:
+      '@types/json-schema': 7.0.11
+      '@typescript-eslint/scope-manager': 5.36.1
+      '@typescript-eslint/types': 5.36.1
+      '@typescript-eslint/typescript-estree': 5.36.1_typescript@4.8.4
+      eslint: 8.8.0
+      eslint-scope: 5.1.1
+      eslint-utils: 3.0.0_eslint@8.8.0
+    transitivePeerDependencies:
+      - supports-color
+      - typescript
+    dev: true
+
+  /@typescript-eslint/utils/5.40.1_3rubbgt5ekhqrcgx4uwls3neim:
+    resolution: {integrity: 
sha512-a2TAVScoX9fjryNrW6BZRnreDUszxqm9eQ9Esv8n5nXApMW0zeANUYlwh/DED04SC/ifuBvXgZpIK5xeJHQ3aw==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    peerDependencies:
+      eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
+    dependencies:
+      '@types/json-schema': 7.0.11
+      '@types/semver': 7.3.12
+      '@typescript-eslint/scope-manager': 5.40.1
+      '@typescript-eslint/types': 5.40.1
+      '@typescript-eslint/typescript-estree': 5.40.1_typescript@4.8.4
+      eslint: 7.32.0
+      eslint-scope: 5.1.1
+      eslint-utils: 3.0.0_eslint@7.32.0
+      semver: 7.3.8
+    transitivePeerDependencies:
+      - supports-color
+      - typescript
+    dev: true
+
+  /@typescript-eslint/utils/5.40.1_o2nrgn6wwxunlqlzzokx4es3q4:
+    resolution: {integrity: 
sha512-a2TAVScoX9fjryNrW6BZRnreDUszxqm9eQ9Esv8n5nXApMW0zeANUYlwh/DED04SC/ifuBvXgZpIK5xeJHQ3aw==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    peerDependencies:
+      eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
+    dependencies:
+      '@types/json-schema': 7.0.11
+      '@types/semver': 7.3.12
+      '@typescript-eslint/scope-manager': 5.40.1
+      '@typescript-eslint/types': 5.40.1
+      '@typescript-eslint/typescript-estree': 5.40.1_typescript@4.8.4
+      eslint: 8.8.0
+      eslint-scope: 5.1.1
+      eslint-utils: 3.0.0_eslint@8.8.0
+      semver: 7.3.8
+    transitivePeerDependencies:
+      - supports-color
+      - typescript
+    dev: true
+
+  /@typescript-eslint/visitor-keys/4.33.0:
+    resolution: {integrity: 
sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==}
+    engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1}
+    dependencies:
+      '@typescript-eslint/types': 4.33.0
+      eslint-visitor-keys: 2.1.0
+    dev: true
+
+  /@typescript-eslint/visitor-keys/5.36.1:
+    resolution: {integrity: 
sha512-ojB9aRyRFzVMN3b5joSYni6FAS10BBSCAfKJhjJAV08t/a95aM6tAhz+O1jF+EtgxktuSO3wJysp2R+Def/IWQ==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    dependencies:
+      '@typescript-eslint/types': 5.36.1
+      eslint-visitor-keys: 3.3.0
+    dev: true
+
+  /@typescript-eslint/visitor-keys/5.40.1:
+    resolution: {integrity: 
sha512-A2DGmeZ+FMja0geX5rww+DpvILpwo1OsiQs0M+joPWJYsiEFBLsH0y1oFymPNul6Z5okSmHpP4ivkc2N0Cgfkw==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    dependencies:
+      '@typescript-eslint/types': 5.40.1
+      eslint-visitor-keys: 3.3.0
+    dev: true
+
+  /@ungap/promise-all-settled/1.1.2:
+    resolution: {integrity: 
sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==}
+    dev: true
+
+  /@webassemblyjs/ast/1.9.0:
+    resolution: {integrity: 
sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==}
+    dependencies:
+      '@webassemblyjs/helper-module-context': 1.9.0
+      '@webassemblyjs/helper-wasm-bytecode': 1.9.0
+      '@webassemblyjs/wast-parser': 1.9.0
+    dev: true
+
+  /@webassemblyjs/floating-point-hex-parser/1.9.0:
+    resolution: {integrity: 
sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==}
+    dev: true
+
+  /@webassemblyjs/helper-api-error/1.9.0:
+    resolution: {integrity: 
sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==}
+    dev: true
+
+  /@webassemblyjs/helper-buffer/1.9.0:
+    resolution: {integrity: 
sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==}
+    dev: true
+
+  /@webassemblyjs/helper-code-frame/1.9.0:
+    resolution: {integrity: 
sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==}
+    dependencies:
+      '@webassemblyjs/wast-printer': 1.9.0
+    dev: true
+
+  /@webassemblyjs/helper-fsm/1.9.0:
+    resolution: {integrity: 
sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==}
+    dev: true
+
+  /@webassemblyjs/helper-module-context/1.9.0:
+    resolution: {integrity: 
sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==}
+    dependencies:
+      '@webassemblyjs/ast': 1.9.0
+    dev: true
+
+  /@webassemblyjs/helper-wasm-bytecode/1.9.0:
+    resolution: {integrity: 
sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==}
+    dev: true
+
+  /@webassemblyjs/helper-wasm-section/1.9.0:
+    resolution: {integrity: 
sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==}
+    dependencies:
+      '@webassemblyjs/ast': 1.9.0
+      '@webassemblyjs/helper-buffer': 1.9.0
+      '@webassemblyjs/helper-wasm-bytecode': 1.9.0
+      '@webassemblyjs/wasm-gen': 1.9.0
+    dev: true
+
+  /@webassemblyjs/ieee754/1.9.0:
+    resolution: {integrity: 
sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==}
+    dependencies:
+      '@xtuc/ieee754': 1.2.0
+    dev: true
+
+  /@webassemblyjs/leb128/1.9.0:
+    resolution: {integrity: 
sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==}
+    dependencies:
+      '@xtuc/long': 4.2.2
+    dev: true
+
+  /@webassemblyjs/utf8/1.9.0:
+    resolution: {integrity: 
sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==}
+    dev: true
+
+  /@webassemblyjs/wasm-edit/1.9.0:
+    resolution: {integrity: 
sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==}
+    dependencies:
+      '@webassemblyjs/ast': 1.9.0
+      '@webassemblyjs/helper-buffer': 1.9.0
+      '@webassemblyjs/helper-wasm-bytecode': 1.9.0
+      '@webassemblyjs/helper-wasm-section': 1.9.0
+      '@webassemblyjs/wasm-gen': 1.9.0
+      '@webassemblyjs/wasm-opt': 1.9.0
+      '@webassemblyjs/wasm-parser': 1.9.0
+      '@webassemblyjs/wast-printer': 1.9.0
+    dev: true
+
+  /@webassemblyjs/wasm-gen/1.9.0:
+    resolution: {integrity: 
sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==}
+    dependencies:
+      '@webassemblyjs/ast': 1.9.0
+      '@webassemblyjs/helper-wasm-bytecode': 1.9.0
+      '@webassemblyjs/ieee754': 1.9.0
+      '@webassemblyjs/leb128': 1.9.0
+      '@webassemblyjs/utf8': 1.9.0
+    dev: true
+
+  /@webassemblyjs/wasm-opt/1.9.0:
+    resolution: {integrity: 
sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==}
+    dependencies:
+      '@webassemblyjs/ast': 1.9.0
+      '@webassemblyjs/helper-buffer': 1.9.0
+      '@webassemblyjs/wasm-gen': 1.9.0
+      '@webassemblyjs/wasm-parser': 1.9.0
+    dev: true
+
+  /@webassemblyjs/wasm-parser/1.9.0:
+    resolution: {integrity: 
sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==}
+    dependencies:
+      '@webassemblyjs/ast': 1.9.0
+      '@webassemblyjs/helper-api-error': 1.9.0
+      '@webassemblyjs/helper-wasm-bytecode': 1.9.0
+      '@webassemblyjs/ieee754': 1.9.0
+      '@webassemblyjs/leb128': 1.9.0
+      '@webassemblyjs/utf8': 1.9.0
+    dev: true
+
+  /@webassemblyjs/wast-parser/1.9.0:
+    resolution: {integrity: 
sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==}
+    dependencies:
+      '@webassemblyjs/ast': 1.9.0
+      '@webassemblyjs/floating-point-hex-parser': 1.9.0
+      '@webassemblyjs/helper-api-error': 1.9.0
+      '@webassemblyjs/helper-code-frame': 1.9.0
+      '@webassemblyjs/helper-fsm': 1.9.0
+      '@xtuc/long': 4.2.2
+    dev: true
+
+  /@webassemblyjs/wast-printer/1.9.0:
+    resolution: {integrity: 
sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==}
+    dependencies:
+      '@webassemblyjs/ast': 1.9.0
+      '@webassemblyjs/wast-parser': 1.9.0
+      '@xtuc/long': 4.2.2
+    dev: true
+
+  /@xtuc/ieee754/1.2.0:
+    resolution: {integrity: 
sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==}
+    dev: true
+
+  /@xtuc/long/4.2.2:
+    resolution: {integrity: 
sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==}
+    dev: true
+
+  /abab/2.0.5:
+    resolution: {integrity: 
sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==}
+    dev: true
+
+  /accepts/1.3.8:
+    resolution: {integrity: 
sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==}
+    engines: {node: '>= 0.6'}
+    dependencies:
+      mime-types: 2.1.35
+      negotiator: 0.6.3
+    dev: true
+
+  /acorn-es7-plugin/1.1.7:
+    resolution: {integrity: 
sha512-7D+8kscFMf6F2t+8ZRYmv82CncDZETsaZ4dEl5lh3qQez7FVABk2Vz616SAbnIq1PbNsLVaZjl2oSkk5BWAKng==}
+    dev: true
+
+  /acorn-globals/4.3.4:
+    resolution: {integrity: 
sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==}
+    dependencies:
+      acorn: 6.4.2
+      acorn-walk: 6.2.0
+    dev: true
+
+  /acorn-globals/6.0.0:
+    resolution: {integrity: 
sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==}
+    dependencies:
+      acorn: 7.4.1
+      acorn-walk: 7.2.0
+    dev: true
+
+  /acorn-jsx/5.3.2_acorn@7.4.1:
+    resolution: {integrity: 
sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
+    peerDependencies:
+      acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+    dependencies:
+      acorn: 7.4.1
+    dev: true
+
+  /acorn-jsx/5.3.2_acorn@8.7.0:
+    resolution: {integrity: 
sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
+    peerDependencies:
+      acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+    dependencies:
+      acorn: 8.7.0
+    dev: true
+
+  /acorn-walk/6.2.0:
+    resolution: {integrity: 
sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==}
+    engines: {node: '>=0.4.0'}
+    dev: true
+
+  /acorn-walk/7.2.0:
+    resolution: {integrity: 
sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==}
+    engines: {node: '>=0.4.0'}
+    dev: true
+
+  /acorn-walk/8.2.0:
+    resolution: {integrity: 
sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==}
+    engines: {node: '>=0.4.0'}
+    dev: true
+
+  /acorn/5.7.4:
+    resolution: {integrity: 
sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==}
+    engines: {node: '>=0.4.0'}
+    hasBin: true
+    dev: true
+
+  /acorn/6.4.2:
+    resolution: {integrity: 
sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==}
+    engines: {node: '>=0.4.0'}
+    hasBin: true
+    dev: true
+
+  /acorn/7.4.1:
+    resolution: {integrity: 
sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==}
+    engines: {node: '>=0.4.0'}
+    hasBin: true
+    dev: true
+
+  /acorn/8.7.0:
+    resolution: {integrity: 
sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==}
+    engines: {node: '>=0.4.0'}
+    hasBin: true
+    dev: true
+
+  /acorn/8.8.0:
+    resolution: {integrity: 
sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==}
+    engines: {node: '>=0.4.0'}
+    hasBin: true
+    dev: true
+
+  /address/1.1.2:
+    resolution: {integrity: 
sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==}
+    engines: {node: '>= 0.12.0'}
+    dev: true
+
+  /address/1.2.1:
+    resolution: {integrity: 
sha512-B+6bi5D34+fDYENiH5qOlA0cV2rAGKuWZ9LeyUUehbXy8e0VS9e498yO0Jeeh+iM+6KbfudHTFjXw2MmJD4QRA==}
+    engines: {node: '>= 10.0.0'}
+    dev: true
+
+  /agent-base/6.0.2:
+    resolution: {integrity: 
sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
+    engines: {node: '>= 6.0.0'}
+    dependencies:
+      debug: 4.3.4
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /aggregate-error/3.1.0:
+    resolution: {integrity: 
sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==}
+    engines: {node: '>=8'}
+    dependencies:
+      clean-stack: 2.2.0
+      indent-string: 4.0.0
+    dev: true
+
+  /aggregate-error/4.0.1:
+    resolution: {integrity: 
sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==}
+    engines: {node: '>=12'}
+    dependencies:
+      clean-stack: 4.2.0
+      indent-string: 5.0.0
+    dev: true
+
+  /airbnb-js-shims/2.2.1:
+    resolution: {integrity: 
sha512-wJNXPH66U2xjgo1Zwyjf9EydvJ2Si94+vSdk6EERcBfB2VZkeltpqIats0cqIZMLCXP3zcyaUKGYQeIBT6XjsQ==}
+    dependencies:
+      array-includes: 3.1.4
+      array.prototype.flat: 1.2.5
+      array.prototype.flatmap: 1.2.5
+      es5-shim: 4.6.7
+      es6-shim: 0.35.6
+      function.prototype.name: 1.1.5
+      globalthis: 1.0.3
+      object.entries: 1.1.5
+      object.fromentries: 2.0.5
+      object.getownpropertydescriptors: 2.1.3
+      object.values: 1.1.5
+      promise.allsettled: 1.0.5
+      promise.prototype.finally: 3.1.3
+      string.prototype.matchall: 4.0.6
+      string.prototype.padend: 3.1.3
+      string.prototype.padstart: 3.1.3
+      symbol.prototype.description: 1.0.5
+    dev: true
+
+  /ajv-errors/1.0.1_ajv@6.12.6:
+    resolution: {integrity: 
sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==}
+    peerDependencies:
+      ajv: '>=5.0.0'
+    dependencies:
+      ajv: 6.12.6
+    dev: true
+
+  /ajv-formats/2.1.1:
+    resolution: {integrity: 
sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==}
+    peerDependenciesMeta:
+      ajv:
+        optional: true
+    dependencies:
+      ajv: 8.10.0
+    dev: true
+
+  /ajv-keywords/3.5.2_ajv@6.12.6:
+    resolution: {integrity: 
sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==}
+    peerDependencies:
+      ajv: ^6.9.1
+    dependencies:
+      ajv: 6.12.6
+
+  /ajv-keywords/5.1.0_ajv@8.10.0:
+    resolution: {integrity: 
sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==}
+    peerDependencies:
+      ajv: ^8.8.2
+    dependencies:
+      ajv: 8.10.0
+      fast-deep-equal: 3.1.3
+    dev: true
+
+  /ajv/6.12.6:
+    resolution: {integrity: 
sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
+    dependencies:
+      fast-deep-equal: 3.1.3
+      fast-json-stable-stringify: 2.1.0
+      json-schema-traverse: 0.4.1
+      uri-js: 4.4.1
+
+  /ajv/8.10.0:
+    resolution: {integrity: 
sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==}
+    dependencies:
+      fast-deep-equal: 3.1.3
+      json-schema-traverse: 1.0.0
+      require-from-string: 2.0.2
+      uri-js: 4.4.1
+    dev: true
+
+  /alphanum-sort/1.0.2:
+    resolution: {integrity: 
sha512-0FcBfdcmaumGPQ0qPn7Q5qTgz/ooXgIyp1rf8ik5bGX8mpE2YHjC0P/eyQvxu1GURYQgq9ozf2mteQ5ZD9YiyQ==}
+    dev: true
+
+  /ansi-align/3.0.1:
+    resolution: {integrity: 
sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==}
+    dependencies:
+      string-width: 4.2.3
+    dev: true
+
+  /ansi-colors/3.2.4:
+    resolution: {integrity: 
sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==}
+    engines: {node: '>=6'}
+    dev: true
+
+  /ansi-colors/4.1.1:
+    resolution: {integrity: 
sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==}
+    engines: {node: '>=6'}
+    dev: true
+
+  /ansi-escapes/4.3.2:
+    resolution: {integrity: 
sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==}
+    engines: {node: '>=8'}
+    dependencies:
+      type-fest: 0.21.3
+    dev: true
+
+  /ansi-html-community/0.0.8:
+    resolution: {integrity: 
sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==}
+    engines: {'0': node >= 0.8.0}
+    hasBin: true
+    dev: true
+
+  /ansi-regex/2.1.1:
+    resolution: {integrity: 
sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /ansi-regex/4.1.1:
+    resolution: {integrity: 
sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==}
+    engines: {node: '>=6'}
+    dev: true
+
+  /ansi-regex/5.0.1:
+    resolution: {integrity: 
sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
+    engines: {node: '>=8'}
+    dev: true
+
+  /ansi-regex/6.0.1:
+    resolution: {integrity: 
sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==}
+    engines: {node: '>=12'}
+    dev: true
+
+  /ansi-styles/1.0.0:
+    resolution: {integrity: 
sha512-3iF4FIKdxaVYT3JqQuY3Wat/T2t7TRbbQ94Fu50ZUCbLy4TFbTzr90NOHQodQkNqmeEGCw8WbeP78WNi6SKYUA==}
+    engines: {node: '>=0.8.0'}
+    dev: true
+
+  /ansi-styles/3.2.1:
+    resolution: {integrity: 
sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
+    engines: {node: '>=4'}
+    dependencies:
+      color-convert: 1.9.3
+    dev: true
+
+  /ansi-styles/4.3.0:
+    resolution: {integrity: 
sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+    engines: {node: '>=8'}
+    dependencies:
+      color-convert: 2.0.1
+    dev: true
+
+  /ansi-styles/5.2.0:
+    resolution: {integrity: 
sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
+    engines: {node: '>=10'}
+    dev: true
+
+  /ansi-styles/6.2.1:
+    resolution: {integrity: 
sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
+    engines: {node: '>=12'}
+    dev: true
+
+  /ansi-to-html/0.6.15:
+    resolution: {integrity: 
sha512-28ijx2aHJGdzbs+O5SNQF65r6rrKYnkuwTYm8lZlChuoJ9P1vVzIpWO20sQTqTPDXYp6NFwk326vApTtLVFXpQ==}
+    engines: {node: '>=8.0.0'}
+    hasBin: true
+    dependencies:
+      entities: 2.2.0
+    dev: true
+
+  /anymatch/2.0.0:
+    resolution: {integrity: 
sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==}
+    dependencies:
+      micromatch: 3.1.10
+      normalize-path: 2.1.1
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /anymatch/2.0.0_supports-color@6.1.0:
+    resolution: {integrity: 
sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==}
+    dependencies:
+      micromatch: 3.1.10_supports-color@6.1.0
+      normalize-path: 2.1.1
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /anymatch/3.1.2:
+    resolution: {integrity: 
sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==}
+    engines: {node: '>= 8'}
+    dependencies:
+      normalize-path: 3.0.0
+      picomatch: 2.3.1
+    dev: true
+
+  /app-root-dir/1.0.2:
+    resolution: {integrity: 
sha512-jlpIfsOoNoafl92Sz//64uQHGSyMrD2vYG5d8o2a4qGvyNCvXur7bzIsWtAC/6flI2RYAp3kv8rsfBtaLm7w0g==}
+    dev: true
+
+  /append-transform/2.0.0:
+    resolution: {integrity: 
sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==}
+    engines: {node: '>=8'}
+    dependencies:
+      default-require-extensions: 3.0.0
+    dev: true
+
+  /aproba/1.2.0:
+    resolution: {integrity: 
sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==}
+    dev: true
+
+  /archy/1.0.0:
+    resolution: {integrity: sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=}
+    dev: true
+
+  /are-we-there-yet/1.1.7:
+    resolution: {integrity: 
sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==}
+    dependencies:
+      delegates: 1.0.0
+      readable-stream: 2.3.7
+    dev: true
+
+  /are-we-there-yet/2.0.0:
+    resolution: {integrity: 
sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==}
+    engines: {node: '>=10'}
+    dependencies:
+      delegates: 1.0.0
+      readable-stream: 3.6.0
+    dev: true
+
+  /argparse/1.0.10:
+    resolution: {integrity: 
sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
+    dependencies:
+      sprintf-js: 1.0.3
+    dev: true
+
+  /argparse/2.0.1:
+    resolution: {integrity: 
sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+    dev: true
+
+  /aria-query/4.2.2:
+    resolution: {integrity: 
sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==}
+    engines: {node: '>=6.0'}
+    dependencies:
+      '@babel/runtime': 7.17.8
+      '@babel/runtime-corejs3': 7.16.7
+    dev: true
+
+  /aria-query/5.1.1:
+    resolution: {integrity: 
sha512-4cPQjOYM2mqq7mZG8CSxkUvL2Yv/x29VhGq5LKehTsxRnoVQps1YGt9NyjcNQsznEsD4rr8a6zGxqeNTqJWjpA==}
+    dependencies:
+      deep-equal: 2.0.5
+    dev: true
+
+  /arr-diff/4.0.0:
+    resolution: {integrity: 
sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /arr-flatten/1.1.0:
+    resolution: {integrity: 
sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /arr-union/3.1.0:
+    resolution: {integrity: 
sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /array-equal/1.0.0:
+    resolution: {integrity: 
sha512-H3LU5RLiSsGXPhN+Nipar0iR0IofH+8r89G2y1tBKxQ/agagKyAjhkAFDRBfodP2caPrNKHpAWNIM/c9yeL7uA==}
+    dev: true
+
+  /array-find-index/1.0.2:
+    resolution: {integrity: 
sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /array-flatten/1.1.1:
+    resolution: {integrity: 
sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==}
+    dev: true
+
+  /array-flatten/2.1.2:
+    resolution: {integrity: 
sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==}
+    dev: true
+
+  /array-includes/3.1.4:
+    resolution: {integrity: 
sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.2
+      define-properties: 1.1.3
+      es-abstract: 1.19.1
+      get-intrinsic: 1.1.1
+      is-string: 1.0.7
+    dev: true
+
+  /array-union/1.0.2:
+    resolution: {integrity: 
sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      array-uniq: 1.0.3
+    dev: true
+
+  /array-union/2.1.0:
+    resolution: {integrity: 
sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
+    engines: {node: '>=8'}
+    dev: true
+
+  /array-uniq/1.0.3:
+    resolution: {integrity: 
sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /array-unique/0.3.2:
+    resolution: {integrity: 
sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /array.prototype.filter/1.0.1:
+    resolution: {integrity: 
sha512-Dk3Ty7N42Odk7PjU/Ci3zT4pLj20YvuVnneG/58ICM6bt4Ij5kZaJTVQ9TSaWaIECX2sFyz4KItkVZqHNnciqw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.2
+      define-properties: 1.1.4
+      es-abstract: 1.20.4
+      es-array-method-boxes-properly: 1.0.0
+      is-string: 1.0.7
+    dev: true
+
+  /array.prototype.flat/1.2.5:
+    resolution: {integrity: 
sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.2
+      define-properties: 1.1.3
+      es-abstract: 1.19.1
+    dev: true
+
+  /array.prototype.flatmap/1.2.5:
     resolution: {integrity: 
sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA==}
     engines: {node: '>= 0.4'}
     dependencies:
       call-bind: 1.0.2
-      define-properties: 1.1.3
-      es-abstract: 1.19.1
+      define-properties: 1.1.4
+      es-abstract: 1.20.4
+    dev: true
+
+  /array.prototype.map/1.0.4:
+    resolution: {integrity: 
sha512-Qds9QnX7A0qISY7JT5WuJO0NJPE9CMlC6JzHQfhpqAAQQzufVRoeH7EzUY5GcPTx72voG8LV/5eo+b8Qi8hmhA==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.2
+      define-properties: 1.1.4
+      es-abstract: 1.20.4
+      es-array-method-boxes-properly: 1.0.0
+      is-string: 1.0.7
+    dev: true
+
+  /arrgv/1.0.2:
+    resolution: {integrity: 
sha512-a4eg4yhp7mmruZDQFqVMlxNRFGi/i1r87pt8SDHy0/I8PqSXoUTlWZRdAZo0VXgvEARcujbtTk8kiZRi1uDGRw==}
+    engines: {node: '>=8.0.0'}
+    dev: true
+
+  /arrify/2.0.1:
+    resolution: {integrity: 
sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==}
+    engines: {node: '>=8'}
+    dev: true
+
+  /arrify/3.0.0:
+    resolution: {integrity: 
sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==}
+    engines: {node: '>=12'}
+    dev: true
+
+  /asn1.js/5.4.1:
+    resolution: {integrity: 
sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==}
+    dependencies:
+      bn.js: 4.12.0
+      inherits: 2.0.4
+      minimalistic-assert: 1.0.1
+      safer-buffer: 2.1.2
+    dev: true
+
+  /asn1/0.2.6:
+    resolution: {integrity: 
sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==}
+    dependencies:
+      safer-buffer: 2.1.2
+    dev: true
+
+  /assert-plus/1.0.0:
+    resolution: {integrity: 
sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==}
+    engines: {node: '>=0.8'}
+    dev: true
+
+  /assert/1.5.0:
+    resolution: {integrity: 
sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==}
+    dependencies:
+      object-assign: 4.1.1
+      util: 0.10.3
+    dev: true
+
+  /assertion-error/1.1.0:
+    resolution: {integrity: 
sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==}
+
+  /assign-symbols/1.0.0:
+    resolution: {integrity: 
sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /ast-metadata-inferer/0.7.0:
+    resolution: {integrity: 
sha512-OkMLzd8xelb3gmnp6ToFvvsHLtS6CbagTkFQvQ+ZYFe3/AIl9iKikNR9G7pY3GfOR/2Xc222hwBjzI7HLkE76Q==}
+    dependencies:
+      '@mdn/browser-compat-data': 3.3.14
+    dev: true
+
+  /ast-types-flow/0.0.7:
+    resolution: {integrity: sha1-9wtzXGvKGlycItmCw+Oef+ujva0=}
+    dev: true
+
+  /astral-regex/2.0.0:
+    resolution: {integrity: 
sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==}
+    engines: {node: '>=8'}
+    dev: true
+
+  /async-each/1.0.3:
+    resolution: {integrity: 
sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==}
+    dev: true
+
+  /async-limiter/1.0.1:
+    resolution: {integrity: 
sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==}
+    dev: true
+
+  /async/0.9.2:
+    resolution: {integrity: 
sha512-l6ToIJIotphWahxxHyzK9bnLR6kM4jJIIgLShZeqLY7iboHoGkdgFl7W2/Ivi4SkMJYGKqW8vSuk0uKUj6qsSw==}
+    dev: true
+
+  /async/2.6.3:
+    resolution: {integrity: 
sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==}
+    dependencies:
+      lodash: 4.17.21
+    dev: true
+
+  /asynckit/0.4.0:
+    resolution: {integrity: 
sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
+
+  /at-least-node/1.0.0:
+    resolution: {integrity: 
sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==}
+    engines: {node: '>= 4.0.0'}
+    dev: true
+
+  /atob/2.1.2:
+    resolution: {integrity: 
sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==}
+    engines: {node: '>= 4.5.0'}
+    hasBin: true
+    dev: true
+
+  /autoprefixer/10.4.2_postcss@8.4.6:
+    resolution: {integrity: 
sha512-9fOPpHKuDW1w/0EKfRmVnxTDt8166MAnLI3mgZ1JCnhNtYWxcJ6Ud5CO/AVOZi/AvFa8DY9RTy3h3+tFBlrrdQ==}
+    engines: {node: ^10 || ^12 || >=14}
+    hasBin: true
+    peerDependencies:
+      postcss: ^8.1.0
+    dependencies:
+      browserslist: 4.19.1
+      caniuse-lite: 1.0.30001311
+      fraction.js: 4.1.3
+      normalize-range: 0.1.2
+      picocolors: 1.0.0
+      postcss: 8.4.6
+      postcss-value-parser: 4.2.0
+    dev: true
+
+  /autoprefixer/9.8.8:
+    resolution: {integrity: 
sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==}
+    hasBin: true
+    dependencies:
+      browserslist: 4.19.1
+      caniuse-lite: 1.0.30001311
+      normalize-range: 0.1.2
+      num2fraction: 1.2.2
+      picocolors: 0.2.1
+      postcss: 7.0.39
+      postcss-value-parser: 4.2.0
+    dev: true
+
+  /ava/4.3.3:
+    resolution: {integrity: 
sha512-9Egq/d9R74ExrWohHeqUlexjDbgZJX5jA1Wq4KCTqc3wIfpGEK79zVy4rBtofJ9YKIxs4PzhJ8BgbW5PlAYe6w==}
+    engines: {node: '>=12.22 <13 || >=14.17 <15 || >=16.4 <17 || >=18'}
+    hasBin: true
+    peerDependencies:
+      '@ava/typescript': '*'
+    peerDependenciesMeta:
+      '@ava/typescript':
+        optional: true
+    dependencies:
+      acorn: 8.8.0
+      acorn-walk: 8.2.0
+      ansi-styles: 6.2.1
+      arrgv: 1.0.2
+      arrify: 3.0.0
+      callsites: 4.0.0
+      cbor: 8.1.0
+      chalk: 5.1.2
+      chokidar: 3.5.3
+      chunkd: 2.0.1
+      ci-info: 3.5.0
+      ci-parallel-vars: 1.0.1
+      clean-yaml-object: 0.1.0
+      cli-truncate: 3.1.0
+      code-excerpt: 4.0.0
+      common-path-prefix: 3.0.0
+      concordance: 5.0.4
+      currently-unhandled: 0.4.1
+      debug: 4.3.4
+      del: 6.1.1
+      emittery: 0.11.0
+      figures: 4.0.1
+      globby: 13.1.2
+      ignore-by-default: 2.1.0
+      indent-string: 5.0.0
+      is-error: 2.2.2
+      is-plain-object: 5.0.0
+      is-promise: 4.0.0
+      matcher: 5.0.0
+      mem: 9.0.2
+      ms: 2.1.3
+      p-event: 5.0.1
+      p-map: 5.5.0
+      picomatch: 2.3.1
+      pkg-conf: 4.0.0
+      plur: 5.1.0
+      pretty-ms: 7.0.1
+      resolve-cwd: 3.0.0
+      slash: 3.0.0
+      stack-utils: 2.0.5
+      strip-ansi: 7.0.1
+      supertap: 3.0.1
+      temp-dir: 2.0.0
+      write-file-atomic: 4.0.2
+      yargs: 17.6.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /ava/4.3.3_@ava+typescript@3.0.1:
+    resolution: {integrity: 
sha512-9Egq/d9R74ExrWohHeqUlexjDbgZJX5jA1Wq4KCTqc3wIfpGEK79zVy4rBtofJ9YKIxs4PzhJ8BgbW5PlAYe6w==}
+    engines: {node: '>=12.22 <13 || >=14.17 <15 || >=16.4 <17 || >=18'}
+    hasBin: true
+    peerDependencies:
+      '@ava/typescript': '*'
+    peerDependenciesMeta:
+      '@ava/typescript':
+        optional: true
+    dependencies:
+      '@ava/typescript': 3.0.1
+      acorn: 8.8.0
+      acorn-walk: 8.2.0
+      ansi-styles: 6.2.1
+      arrgv: 1.0.2
+      arrify: 3.0.0
+      callsites: 4.0.0
+      cbor: 8.1.0
+      chalk: 5.1.2
+      chokidar: 3.5.3
+      chunkd: 2.0.1
+      ci-info: 3.5.0
+      ci-parallel-vars: 1.0.1
+      clean-yaml-object: 0.1.0
+      cli-truncate: 3.1.0
+      code-excerpt: 4.0.0
+      common-path-prefix: 3.0.0
+      concordance: 5.0.4
+      currently-unhandled: 0.4.1
+      debug: 4.3.4
+      del: 6.1.1
+      emittery: 0.11.0
+      figures: 4.0.1
+      globby: 13.1.2
+      ignore-by-default: 2.1.0
+      indent-string: 5.0.0
+      is-error: 2.2.2
+      is-plain-object: 5.0.0
+      is-promise: 4.0.0
+      matcher: 5.0.0
+      mem: 9.0.2
+      ms: 2.1.3
+      p-event: 5.0.1
+      p-map: 5.5.0
+      picomatch: 2.3.1
+      pkg-conf: 4.0.0
+      plur: 5.1.0
+      pretty-ms: 7.0.1
+      resolve-cwd: 3.0.0
+      slash: 3.0.0
+      stack-utils: 2.0.5
+      strip-ansi: 7.0.1
+      supertap: 3.0.1
+      temp-dir: 2.0.0
+      write-file-atomic: 4.0.2
+      yargs: 17.6.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /available-typed-arrays/1.0.5:
+    resolution: {integrity: 
sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==}
+    engines: {node: '>= 0.4'}
+    dev: true
+
+  /aws-sign2/0.7.0:
+    resolution: {integrity: 
sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==}
+    dev: true
+
+  /aws4/1.11.0:
+    resolution: {integrity: 
sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==}
+    dev: true
+
+  /axe-core/4.3.5:
+    resolution: {integrity: 
sha512-WKTW1+xAzhMS5dJsxWkliixlO/PqC4VhmO9T4juNYcaTg9jzWiJsou6m5pxWYGfigWbwzJWeFY6z47a+4neRXA==}
+    engines: {node: '>=4'}
+    dev: true
+
+  /axios/0.21.4:
+    resolution: {integrity: 
sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==}
+    dependencies:
+      follow-redirects: 1.15.2
+    transitivePeerDependencies:
+      - debug
+
+  /axios/0.27.2:
+    resolution: {integrity: 
sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==}
+    dependencies:
+      follow-redirects: 1.15.2
+      form-data: 4.0.0
+    transitivePeerDependencies:
+      - debug
+    dev: false
+
+  /axobject-query/2.2.0:
+    resolution: {integrity: 
sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==}
+    dev: true
+
+  /babel-esm-plugin/0.9.0_webpack@4.46.0:
+    resolution: {integrity: 
sha512-OyPyLI6LUuUqNm3HNUldAkynWrLzXkhcZo4fGTsieCgHqvbCoCIMMOwJmfG9Lmp91S7WDIuUr0mvOeI8pAb/pw==}
+    peerDependencies:
+      webpack: ^4.28.4
+    dependencies:
+      chalk: 2.4.1
+      deepcopy: 1.0.0
+      webpack: 4.46.0
+    dev: true
+
+  /babel-extract-comments/1.0.0:
+    resolution: {integrity: 
sha512-qWWzi4TlddohA91bFwgt6zO/J0X+io7Qp184Fw0m2JYRSTZnJbFR8+07KmzudHCZgOiKRCrjhylwv9Xd8gfhVQ==}
+    engines: {node: '>=4'}
+    dependencies:
+      babylon: 6.18.0
+    dev: true
+
+  /babel-helper-builder-react-jsx/6.26.0:
+    resolution: {integrity: sha1-Of+DE7dci2Xc7/HzHTg+D/KkCKA=}
+    dependencies:
+      babel-runtime: 6.26.0
+      babel-types: 6.26.0
+      esutils: 2.0.3
+    dev: true
+
+  /babel-jest/26.6.3_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==}
+    engines: {node: '>= 10.14.2'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@jest/transform': 26.6.2
+      '@jest/types': 26.6.2
+      '@types/babel__core': 7.1.19
+      babel-plugin-istanbul: 6.1.1
+      babel-preset-jest: 26.6.2_@babel+core@7.19.6
+      chalk: 4.1.2
+      graceful-fs: 4.2.10
+      slash: 3.0.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /babel-jest/27.5.1_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    peerDependencies:
+      '@babel/core': ^7.8.0
+    dependencies:
+      '@babel/core': 7.17.2
+      '@jest/transform': 27.5.1
+      '@jest/types': 27.5.1
+      '@types/babel__core': 7.1.19
+      babel-plugin-istanbul: 6.1.1
+      babel-preset-jest: 27.5.1_@babel+core@7.17.2
+      chalk: 4.1.2
+      graceful-fs: 4.2.10
+      slash: 3.0.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /babel-jest/27.5.1_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    peerDependencies:
+      '@babel/core': ^7.8.0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@jest/transform': 27.5.1
+      '@jest/types': 27.5.1
+      '@types/babel__core': 7.1.19
+      babel-plugin-istanbul: 6.1.1
+      babel-preset-jest: 27.5.1_@babel+core@7.19.6
+      chalk: 4.1.2
+      graceful-fs: 4.2.10
+      slash: 3.0.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /babel-loader/8.2.3_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-n4Zeta8NC3QAsuyiizu0GkmRcQ6clkV9WFUnUf1iXP//IeSKbWjofW3UHyZVwlOB4y039YQKefawyTn64Zwbuw==}
+    engines: {node: '>= 8.9'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+      webpack: '>=2'
+    dependencies:
+      '@babel/core': 7.13.16
+      find-cache-dir: 3.3.2
+      loader-utils: 1.4.0
+      make-dir: 3.1.0
+      schema-utils: 2.7.1
+    dev: true
+
+  /babel-loader/8.2.3_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-n4Zeta8NC3QAsuyiizu0GkmRcQ6clkV9WFUnUf1iXP//IeSKbWjofW3UHyZVwlOB4y039YQKefawyTn64Zwbuw==}
+    engines: {node: '>= 8.9'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+      webpack: '>=2'
+    dependencies:
+      '@babel/core': 7.17.2
+      find-cache-dir: 3.3.2
+      loader-utils: 1.4.0
+      make-dir: 3.1.0
+      schema-utils: 2.7.1
+    dev: true
+
+  /babel-loader/8.2.3_mc362qep5qjjhwk7q3m45kuizi:
+    resolution: {integrity: 
sha512-n4Zeta8NC3QAsuyiizu0GkmRcQ6clkV9WFUnUf1iXP//IeSKbWjofW3UHyZVwlOB4y039YQKefawyTn64Zwbuw==}
+    engines: {node: '>= 8.9'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+      webpack: '>=2'
+    dependencies:
+      '@babel/core': 7.17.2
+      find-cache-dir: 3.3.2
+      loader-utils: 1.4.0
+      make-dir: 3.1.0
+      schema-utils: 2.7.1
+      webpack: 4.46.0
+    dev: true
+
+  /babel-loader/8.2.3_q4ydpsrmbqywduja5orgah6fgq:
+    resolution: {integrity: 
sha512-n4Zeta8NC3QAsuyiizu0GkmRcQ6clkV9WFUnUf1iXP//IeSKbWjofW3UHyZVwlOB4y039YQKefawyTn64Zwbuw==}
+    engines: {node: '>= 8.9'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+      webpack: '>=2'
+    dependencies:
+      '@babel/core': 7.19.6
+      find-cache-dir: 3.3.2
+      loader-utils: 1.4.0
+      make-dir: 3.1.0
+      schema-utils: 2.7.1
+      webpack: 4.46.0
+    dev: true
+
+  /babel-plugin-apply-mdx-type-prop/1.6.22_@babel+core@7.12.9:
+    resolution: {integrity: 
sha512-VefL+8o+F/DfK24lPZMtJctrCVOfgbqLAGZSkxwhazQv4VxPg3Za/i40fu22KR2m8eEda+IfSOlPLUSIiLcnCQ==}
+    peerDependencies:
+      '@babel/core': ^7.11.6
+    dependencies:
+      '@babel/core': 7.12.9
+      '@babel/helper-plugin-utils': 7.10.4
+      '@mdx-js/util': 1.6.22
+    dev: true
+
+  /babel-plugin-dynamic-import-node/2.3.3:
+    resolution: {integrity: 
sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==}
+    dependencies:
+      object.assign: 4.1.2
+    dev: true
+
+  /babel-plugin-emotion/10.2.2:
+    resolution: {integrity: 
sha512-SMSkGoqTbTyUTDeuVuPIWifPdUGkTk1Kf9BWRiXIOIcuyMfsdp2EjeiiFvOzX8NOBvEh/ypKYvUh2rkgAJMCLA==}
+    dependencies:
+      '@babel/helper-module-imports': 7.18.6
+      '@emotion/hash': 0.8.0
+      '@emotion/memoize': 0.7.4
+      '@emotion/serialize': 0.11.16
+      babel-plugin-macros: 2.8.0
+      babel-plugin-syntax-jsx: 6.18.0
+      convert-source-map: 1.8.0
+      escape-string-regexp: 1.0.5
+      find-root: 1.1.0
+      source-map: 0.5.7
+    dev: true
+
+  /babel-plugin-extract-import-names/1.6.22:
+    resolution: {integrity: 
sha512-yJ9BsJaISua7d8zNT7oRG1ZLBJCIdZ4PZqmH8qa9N5AK01ifk3fnkc98AXhtzE7UkfCsEumvoQWgoYLhOnJ7jQ==}
+    dependencies:
+      '@babel/helper-plugin-utils': 7.10.4
+    dev: true
+
+  /babel-plugin-istanbul/6.1.1:
+    resolution: {integrity: 
sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==}
+    engines: {node: '>=8'}
+    dependencies:
+      '@babel/helper-plugin-utils': 7.19.0
+      '@istanbuljs/load-nyc-config': 1.1.0
+      '@istanbuljs/schema': 0.1.3
+      istanbul-lib-instrument: 5.2.1
+      test-exclude: 6.0.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /babel-plugin-jest-hoist/26.6.2:
+    resolution: {integrity: 
sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==}
+    engines: {node: '>= 10.14.2'}
+    dependencies:
+      '@babel/template': 7.18.10
+      '@babel/types': 7.19.4
+      '@types/babel__core': 7.1.19
+      '@types/babel__traverse': 7.18.2
+    dev: true
+
+  /babel-plugin-jest-hoist/27.5.1:
+    resolution: {integrity: 
sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    dependencies:
+      '@babel/template': 7.18.10
+      '@babel/types': 7.19.4
+      '@types/babel__core': 7.1.19
+      '@types/babel__traverse': 7.18.2
+    dev: true
+
+  /babel-plugin-macros/2.8.0:
+    resolution: {integrity: 
sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==}
+    dependencies:
+      '@babel/runtime': 7.17.8
+      cosmiconfig: 6.0.0
+      resolve: 1.22.1
+    dev: true
+
+  /babel-plugin-macros/3.1.0:
+    resolution: {integrity: 
sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==}
+    engines: {node: '>=10', npm: '>=6'}
+    dependencies:
+      '@babel/runtime': 7.17.8
+      cosmiconfig: 7.0.1
+      resolve: 1.22.1
+    dev: true
+
+  /babel-plugin-polyfill-corejs2/0.3.1_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/compat-data': 7.17.0
+      '@babel/core': 7.13.16
+      '@babel/helper-define-polyfill-provider': 0.3.1_@babel+core@7.13.16
+      semver: 6.3.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /babel-plugin-polyfill-corejs2/0.3.1_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/compat-data': 7.17.0
+      '@babel/core': 7.17.2
+      '@babel/helper-define-polyfill-provider': 0.3.1_@babel+core@7.17.2
+      semver: 6.3.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /babel-plugin-polyfill-corejs2/0.3.1_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/compat-data': 7.17.0
+      '@babel/core': 7.19.6
+      '@babel/helper-define-polyfill-provider': 0.3.1_@babel+core@7.19.6
+      semver: 6.3.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /babel-plugin-polyfill-corejs3/0.1.7_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-u+gbS9bbPhZWEeyy1oR/YaaSpod/KDT07arZHb80aTpl8H5ZBq+uN1nN9/xtX7jQyfLdPfoqI4Rue/MQSWJquw==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/helper-define-polyfill-provider': 0.1.5_@babel+core@7.17.2
+      core-js-compat: 3.21.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /babel-plugin-polyfill-corejs3/0.1.7_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-u+gbS9bbPhZWEeyy1oR/YaaSpod/KDT07arZHb80aTpl8H5ZBq+uN1nN9/xtX7jQyfLdPfoqI4Rue/MQSWJquw==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-define-polyfill-provider': 0.1.5_@babel+core@7.19.6
+      core-js-compat: 3.21.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /babel-plugin-polyfill-corejs3/0.5.2_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.13.16
+      '@babel/helper-define-polyfill-provider': 0.3.1_@babel+core@7.13.16
+      core-js-compat: 3.21.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /babel-plugin-polyfill-corejs3/0.5.2_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/helper-define-polyfill-provider': 0.3.1_@babel+core@7.17.2
+      core-js-compat: 3.21.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /babel-plugin-polyfill-corejs3/0.5.2_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-define-polyfill-provider': 0.3.1_@babel+core@7.19.6
+      core-js-compat: 3.21.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /babel-plugin-polyfill-regenerator/0.3.1_@babel+core@7.13.16:
+    resolution: {integrity: 
sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.13.16
+      '@babel/helper-define-polyfill-provider': 0.3.1_@babel+core@7.13.16
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /babel-plugin-polyfill-regenerator/0.3.1_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/helper-define-polyfill-provider': 0.3.1_@babel+core@7.17.2
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /babel-plugin-polyfill-regenerator/0.3.1_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A==}
+    peerDependencies:
+      '@babel/core': ^7.0.0-0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-define-polyfill-provider': 0.3.1_@babel+core@7.19.6
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /babel-plugin-syntax-jsx/6.18.0:
+    resolution: {integrity: sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=}
+    dev: true
+
+  /babel-plugin-syntax-object-rest-spread/6.13.0:
+    resolution: {integrity: 
sha512-C4Aq+GaAj83pRQ0EFgTvw5YO6T3Qz2KGrNRwIj9mSoNHVvdZY4KO2uA6HNtNXCw993iSZnckY1aLW8nOi8i4+w==}
+    dev: true
+
+  /babel-plugin-transform-object-rest-spread/6.26.0:
+    resolution: {integrity: 
sha512-ocgA9VJvyxwt+qJB0ncxV8kb/CjfTcECUY4tQ5VT7nP6Aohzobm8CDFaQ5FHdvZQzLmf0sgDxB8iRXZXxwZcyA==}
+    dependencies:
+      babel-plugin-syntax-object-rest-spread: 6.13.0
+      babel-runtime: 6.26.0
+    dev: true
+
+  /babel-plugin-transform-react-jsx/6.24.1:
+    resolution: {integrity: sha1-hAoCjn30YN/DotKfDA2R9jduZqM=}
+    dependencies:
+      babel-helper-builder-react-jsx: 6.26.0
+      babel-plugin-syntax-jsx: 6.18.0
+      babel-runtime: 6.26.0
+    dev: true
+
+  /babel-plugin-transform-react-remove-prop-types/0.4.24:
+    resolution: {integrity: 
sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==}
+    dev: true
+
+  /babel-preset-current-node-syntax/1.0.1_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.17.2
+      '@babel/plugin-syntax-bigint': 7.8.3_@babel+core@7.17.2
+      '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.17.2
+      '@babel/plugin-syntax-import-meta': 7.10.4_@babel+core@7.17.2
+      '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.17.2
+      '@babel/plugin-syntax-logical-assignment-operators': 
7.10.4_@babel+core@7.17.2
+      '@babel/plugin-syntax-nullish-coalescing-operator': 
7.8.3_@babel+core@7.17.2
+      '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.17.2
+      '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.17.2
+      '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.17.2
+      '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.17.2
+      '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.17.2
+    dev: true
+
+  /babel-preset-current-node-syntax/1.0.1_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.19.6
+      '@babel/plugin-syntax-bigint': 7.8.3_@babel+core@7.19.6
+      '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.19.6
+      '@babel/plugin-syntax-import-meta': 7.10.4_@babel+core@7.19.6
+      '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.19.6
+      '@babel/plugin-syntax-logical-assignment-operators': 
7.10.4_@babel+core@7.19.6
+      '@babel/plugin-syntax-nullish-coalescing-operator': 
7.8.3_@babel+core@7.19.6
+      '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.19.6
+      '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.19.6
+      '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.19.6
+      '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.19.6
+      '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.19.6
+    dev: true
+
+  /babel-preset-jest/26.6.2_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==}
+    engines: {node: '>= 10.14.2'}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.19.6
+      babel-plugin-jest-hoist: 26.6.2
+      babel-preset-current-node-syntax: 1.0.1_@babel+core@7.19.6
+    dev: true
+
+  /babel-preset-jest/27.5.1_@babel+core@7.17.2:
+    resolution: {integrity: 
sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.17.2
+      babel-plugin-jest-hoist: 27.5.1
+      babel-preset-current-node-syntax: 1.0.1_@babel+core@7.17.2
+    dev: true
+
+  /babel-preset-jest/27.5.1_@babel+core@7.19.6:
+    resolution: {integrity: 
sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    peerDependencies:
+      '@babel/core': ^7.0.0
+    dependencies:
+      '@babel/core': 7.19.6
+      babel-plugin-jest-hoist: 27.5.1
+      babel-preset-current-node-syntax: 1.0.1_@babel+core@7.19.6
+    dev: true
+
+  /babel-runtime/6.26.0:
+    resolution: {integrity: sha1-llxwWGaOgrVde/4E/yM3vItWR/4=}
+    dependencies:
+      core-js: 2.6.12
+      regenerator-runtime: 0.11.1
+    dev: true
+
+  /babel-types/6.26.0:
+    resolution: {integrity: sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=}
+    dependencies:
+      babel-runtime: 6.26.0
+      esutils: 2.0.3
+      lodash: 4.17.21
+      to-fast-properties: 1.0.3
+    dev: true
+
+  /babylon/6.18.0:
+    resolution: {integrity: 
sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==}
+    hasBin: true
+    dev: true
+
+  /bail/1.0.5:
+    resolution: {integrity: 
sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==}
+    dev: true
+
+  /balanced-match/1.0.2:
+    resolution: {integrity: 
sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+
+  /base/0.11.2:
+    resolution: {integrity: 
sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      cache-base: 1.0.1
+      class-utils: 0.3.6
+      component-emitter: 1.3.0
+      define-property: 1.0.0
+      isobject: 3.0.1
+      mixin-deep: 1.3.2
+      pascalcase: 0.1.1
+    dev: true
+
+  /base64-inline-loader/1.1.1:
+    resolution: {integrity: 
sha512-v/bHvXQ8sW28t9ZwBsFGgyqZw2bpT49/dtPTtlmixoSM/s9wnOngOKFVQLRH8BfMTy6jTl5m5CdvqpZt8y5d6g==}
+    engines: {node: '>=6.2', npm: '>=3.8'}
+    peerDependencies:
+      webpack: ^4.x
+    dependencies:
+      file-loader: 1.1.11
+      loader-utils: 1.4.0
+      mime-types: 2.1.35
+
+  /base64-js/1.5.1:
+    resolution: {integrity: 
sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
+    dev: true
+
+  /batch-processor/1.0.0:
+    resolution: {integrity: sha1-dclcMrdI4IUNEMKxaPa9vpiRrOg=}
+    dev: true
+
+  /batch/0.6.1:
+    resolution: {integrity: sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=}
+    dev: true
+
+  /bcrypt-pbkdf/1.0.2:
+    resolution: {integrity: 
sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==}
+    dependencies:
+      tweetnacl: 0.14.5
+    dev: true
+
+  /better-opn/2.1.1:
+    resolution: {integrity: 
sha512-kIPXZS5qwyKiX/HcRvDYfmBQUa8XP17I0mYZZ0y4UhpYOSvtsLHDYqmomS+Mj20aDvD3knEiQ0ecQy2nhio3yA==}
+    engines: {node: '>8.0.0'}
+    dependencies:
+      open: 7.4.2
+    dev: true
+
+  /bfj/6.1.2:
+    resolution: {integrity: 
sha512-BmBJa4Lip6BPRINSZ0BPEIfB1wUY/9rwbwvIHQA1KjX9om29B6id0wnWXq7m3bn5JrUVjeOTnVuhPT1FiHwPGw==}
+    engines: {node: '>= 6.0.0'}
+    dependencies:
+      bluebird: 3.7.2
+      check-types: 8.0.3
+      hoopy: 0.1.4
+      tryer: 1.0.1
+    dev: true
+
+  /big-integer/1.6.51:
+    resolution: {integrity: 
sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==}
+    engines: {node: '>=0.6'}
+
+  /big.js/3.2.0:
+    resolution: {integrity: 
sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==}
+    dev: true
+
+  /big.js/5.2.2:
+    resolution: {integrity: 
sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==}
+
+  /binary-extensions/1.13.1:
+    resolution: {integrity: 
sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /binary-extensions/2.2.0:
+    resolution: {integrity: 
sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
+    engines: {node: '>=8'}
+    dev: true
+
+  /bindings/1.5.0:
+    resolution: {integrity: 
sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}
+    requiresBuild: true
+    dependencies:
+      file-uri-to-path: 1.0.0
+    dev: true
+    optional: true
+
+  /bl/4.1.0:
+    resolution: {integrity: 
sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
+    dependencies:
+      buffer: 5.7.1
+      inherits: 2.0.4
+      readable-stream: 3.6.0
+    dev: true
+
+  /bluebird/3.7.2:
+    resolution: {integrity: 
sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==}
+    dev: true
+
+  /blueimp-md5/2.19.0:
+    resolution: {integrity: 
sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==}
+    dev: true
+
+  /bn.js/4.12.0:
+    resolution: {integrity: 
sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==}
+    dev: true
+
+  /bn.js/5.2.0:
+    resolution: {integrity: 
sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==}
+    dev: true
+
+  /body-parser/1.19.1:
+    resolution: {integrity: 
sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==}
+    engines: {node: '>= 0.8'}
+    dependencies:
+      bytes: 3.1.1
+      content-type: 1.0.4
+      debug: 2.6.9
+      depd: 1.1.2
+      http-errors: 1.8.1
+      iconv-lite: 0.4.24
+      on-finished: 2.3.0
+      qs: 6.9.6
+      raw-body: 2.4.2
+      type-is: 1.6.18
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /body-parser/1.19.1_supports-color@6.1.0:
+    resolution: {integrity: 
sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==}
+    engines: {node: '>= 0.8'}
+    dependencies:
+      bytes: 3.1.1
+      content-type: 1.0.4
+      debug: 2.6.9_supports-color@6.1.0
+      depd: 1.1.2
+      http-errors: 1.8.1
+      iconv-lite: 0.4.24
+      on-finished: 2.3.0
+      qs: 6.9.6
+      raw-body: 2.4.2
+      type-is: 1.6.18
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /bonjour/3.5.0:
+    resolution: {integrity: 
sha512-RaVTblr+OnEli0r/ud8InrU7D+G0y6aJhlxaLa6Pwty4+xoxboF1BsUI45tujvRpbj9dQVoglChqonGAsjEBYg==}
+    dependencies:
+      array-flatten: 2.1.2
+      deep-equal: 1.1.1
+      dns-equal: 1.0.0
+      dns-txt: 2.0.2
+      multicast-dns: 6.2.3
+      multicast-dns-service-types: 1.1.0
+    dev: true
+
+  /boolbase/1.0.0:
+    resolution: {integrity: 
sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
+    dev: true
+
+  /boxen/4.2.0:
+    resolution: {integrity: 
sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==}
+    engines: {node: '>=8'}
+    dependencies:
+      ansi-align: 3.0.1
+      camelcase: 5.3.1
+      chalk: 3.0.0
+      cli-boxes: 2.2.1
+      string-width: 4.2.3
+      term-size: 2.2.1
+      type-fest: 0.8.1
+      widest-line: 3.1.0
+    dev: true
+
+  /boxen/5.1.2:
+    resolution: {integrity: 
sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==}
+    engines: {node: '>=10'}
+    dependencies:
+      ansi-align: 3.0.1
+      camelcase: 6.3.0
+      chalk: 4.1.2
+      cli-boxes: 2.2.1
+      string-width: 4.2.3
+      type-fest: 0.20.2
+      widest-line: 3.1.0
+      wrap-ansi: 7.0.0
+    dev: true
+
+  /bplist-parser/0.1.1:
+    resolution: {integrity: 
sha512-2AEM0FXy8ZxVLBuqX0hqt1gDwcnz2zygEkQ6zaD5Wko/sB9paUNwlpawrFtKeHUAQUOzjVy9AO4oeonqIHKA9Q==}
+    dependencies:
+      big-integer: 1.6.51
+    dev: true
+    optional: true
+
+  /brace-expansion/1.1.11:
+    resolution: {integrity: 
sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
+    dependencies:
+      balanced-match: 1.0.2
+      concat-map: 0.0.1
+
+  /brace-expansion/2.0.1:
+    resolution: {integrity: 
sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
+    dependencies:
+      balanced-match: 1.0.2
+    dev: true
+
+  /braces/2.3.2:
+    resolution: {integrity: 
sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      arr-flatten: 1.1.0
+      array-unique: 0.3.2
+      extend-shallow: 2.0.1
+      fill-range: 4.0.0
+      isobject: 3.0.1
+      repeat-element: 1.1.4
+      snapdragon: 0.8.2
+      snapdragon-node: 2.1.1
+      split-string: 3.1.0
+      to-regex: 3.0.2
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /braces/2.3.2_supports-color@6.1.0:
+    resolution: {integrity: 
sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      arr-flatten: 1.1.0
+      array-unique: 0.3.2
+      extend-shallow: 2.0.1
+      fill-range: 4.0.0
+      isobject: 3.0.1
+      repeat-element: 1.1.4
+      snapdragon: 0.8.2_supports-color@6.1.0
+      snapdragon-node: 2.1.1
+      split-string: 3.1.0
+      to-regex: 3.0.2
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /braces/3.0.2:
+    resolution: {integrity: 
sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
+    engines: {node: '>=8'}
+    dependencies:
+      fill-range: 7.0.1
+    dev: true
+
+  /brorand/1.1.0:
+    resolution: {integrity: 
sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==}
+    dev: true
+
+  /browser-process-hrtime/1.0.0:
+    resolution: {integrity: 
sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==}
+    dev: true
+
+  /browser-stdout/1.3.1:
+    resolution: {integrity: 
sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==}
+    dev: true
+
+  /browserify-aes/1.2.0:
+    resolution: {integrity: 
sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==}
+    dependencies:
+      buffer-xor: 1.0.3
+      cipher-base: 1.0.4
+      create-hash: 1.2.0
+      evp_bytestokey: 1.0.3
+      inherits: 2.0.4
+      safe-buffer: 5.2.1
+    dev: true
+
+  /browserify-cipher/1.0.1:
+    resolution: {integrity: 
sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==}
+    dependencies:
+      browserify-aes: 1.2.0
+      browserify-des: 1.0.2
+      evp_bytestokey: 1.0.3
+    dev: true
+
+  /browserify-des/1.0.2:
+    resolution: {integrity: 
sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==}
+    dependencies:
+      cipher-base: 1.0.4
+      des.js: 1.0.1
+      inherits: 2.0.4
+      safe-buffer: 5.2.1
+    dev: true
+
+  /browserify-rsa/4.1.0:
+    resolution: {integrity: 
sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==}
+    dependencies:
+      bn.js: 5.2.0
+      randombytes: 2.1.0
+    dev: true
+
+  /browserify-sign/4.2.1:
+    resolution: {integrity: 
sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==}
+    dependencies:
+      bn.js: 5.2.0
+      browserify-rsa: 4.1.0
+      create-hash: 1.2.0
+      create-hmac: 1.1.7
+      elliptic: 6.5.4
+      inherits: 2.0.4
+      parse-asn1: 5.1.6
+      readable-stream: 3.6.0
+      safe-buffer: 5.2.1
+    dev: true
+
+  /browserify-zlib/0.2.0:
+    resolution: {integrity: 
sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==}
+    dependencies:
+      pako: 1.0.11
+    dev: true
+
+  /browserslist/4.14.2:
+    resolution: {integrity: 
sha512-HI4lPveGKUR0x2StIz+2FXfDk9SfVMrxn6PLh1JeGUwcuoDkdKZebWiyLRJ68iIPDpMI4JLVDf7S7XzslgWOhw==}
+    engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+    hasBin: true
+    dependencies:
+      caniuse-lite: 1.0.30001311
+      electron-to-chromium: 1.4.68
+      escalade: 3.1.1
+      node-releases: 1.1.77
+    dev: true
+
+  /browserslist/4.19.1:
+    resolution: {integrity: 
sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==}
+    engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+    hasBin: true
+    dependencies:
+      caniuse-lite: 1.0.30001311
+      electron-to-chromium: 1.4.68
+      escalade: 3.1.1
+      node-releases: 2.0.2
+      picocolors: 1.0.0
+    dev: true
+
+  /browserslist/4.21.4:
+    resolution: {integrity: 
sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==}
+    engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+    hasBin: true
+    dependencies:
+      caniuse-lite: 1.0.30001423
+      electron-to-chromium: 1.4.284
+      node-releases: 2.0.6
+      update-browserslist-db: 1.0.10_browserslist@4.21.4
+    dev: true
+
+  /bser/2.1.1:
+    resolution: {integrity: 
sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==}
+    dependencies:
+      node-int64: 0.4.0
+    dev: true
+
+  /buffer-from/1.1.2:
+    resolution: {integrity: 
sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
+
+  /buffer-indexof/1.1.1:
+    resolution: {integrity: 
sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==}
+    dev: true
+
+  /buffer-xor/1.0.3:
+    resolution: {integrity: 
sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==}
+    dev: true
+
+  /buffer/4.9.2:
+    resolution: {integrity: 
sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==}
+    dependencies:
+      base64-js: 1.5.1
+      ieee754: 1.2.1
+      isarray: 1.0.0
+    dev: true
+
+  /buffer/5.7.1:
+    resolution: {integrity: 
sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
+    dependencies:
+      base64-js: 1.5.1
+      ieee754: 1.2.1
+    dev: true
+
+  /builtin-modules/3.3.0:
+    resolution: {integrity: 
sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==}
+    engines: {node: '>=6'}
+    dev: true
+
+  /builtin-status-codes/3.0.0:
+    resolution: {integrity: 
sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==}
+    dev: true
+
+  /builtins/1.0.3:
+    resolution: {integrity: 
sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==}
+    dev: true
+
+  /bulma-checkbox/1.2.1:
+    resolution: {integrity: 
sha512-Ad7kSzwYwHLYyow92IJPz9jgolDDo5ivlFdSBe7W4LR9WnLt/Gd2iE07m3uhoU/g37oIZcMHNC33ZxJKqAuSzQ==}
+    dependencies:
+      bulma: 0.9.3
+    dev: true
+
+  /bulma-radio/1.2.0:
+    resolution: {integrity: 
sha512-rIzqALGakpKf9Eju4sGMt2Pwnn7X+AdYh6itjsCxLCJ/Ext4Cdd/M7uevQlXDy0MSwrQBMBLR8buSToBCuI+zA==}
+    dependencies:
+      bulma: 0.9.3
+    dev: true
+
+  /bulma-responsive-tables/1.2.5:
+    resolution: {integrity: 
sha512-8/qYiv21cJnGYMkjIF52iKCV/B6XIswu58Vwi3/TS+wLavvA7OFXhBy0quxOnqPNqnovHly2dTCyVCqHLJU7Sg==}
+    dependencies:
+      bulma: 0.9.3
+    dev: true
+
+  /bulma-switch-control/1.2.2:
+    resolution: {integrity: 
sha512-1eHlga1Z4RBRU6DIxNiwb6+I9n9vDkj9/MmwS4pL68P7STE1vbwRutxh9oFeFWuxLXGNLILJEXJXiwyEjT9upw==}
+    dependencies:
+      bulma: 0.9.3
+    dev: true
+
+  /bulma-timeline/3.0.5:
+    resolution: {integrity: 
sha512-gBwdx7PmAEZ/+5zSn/ZBJBqkenT8wi+9nlD0uP8lXa3rGcbhG+fp8Oz98+3O10LQPlUEdKPYEUxtQ55okRfhTQ==}
+    dev: true
+
+  /bulma-upload-control/1.2.0:
+    resolution: {integrity: 
sha512-2raueVPVoG3KjHH+7Aok44nGSPIl76qzdkLKX/ziHAOwbiXBrlEYHXca8Hk0UDa0KElLiPT6Eb2Cvz+8FFUwBw==}
+    dependencies:
+      bulma: 0.9.3
+    dev: true
+
+  /bulma/0.9.3:
+    resolution: {integrity: 
sha512-0d7GNW1PY4ud8TWxdNcP6Cc8Bu7MxcntD/RRLGWuiw/s0a9P+XlH/6QoOIrmbj6o8WWJzJYhytiu9nFjTszk1g==}
+    dev: true
+
+  /bytes/3.0.0:
+    resolution: {integrity: sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=}
+    engines: {node: '>= 0.8'}
+    dev: true
+
+  /bytes/3.1.1:
+    resolution: {integrity: 
sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==}
+    engines: {node: '>= 0.8'}
+    dev: true
+
+  /c8/7.11.0:
+    resolution: {integrity: 
sha512-XqPyj1uvlHMr+Y1IeRndC2X5P7iJzJlEJwBpCdBbq2JocXOgJfr+JVfJkyNMGROke5LfKrhSFXGFXnwnRJAUJw==}
+    engines: {node: '>=10.12.0'}
+    hasBin: true
+    dependencies:
+      '@bcoe/v8-coverage': 0.2.3
+      '@istanbuljs/schema': 0.1.3
+      find-up: 5.0.0
+      foreground-child: 2.0.0
+      istanbul-lib-coverage: 3.2.0
+      istanbul-lib-report: 3.0.0
+      istanbul-reports: 3.1.3
+      rimraf: 3.0.2
+      test-exclude: 6.0.0
+      v8-to-istanbul: 8.1.1
+      yargs: 16.2.0
+      yargs-parser: 20.2.9
+    dev: true
+
+  /cacache/12.0.4:
+    resolution: {integrity: 
sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==}
+    dependencies:
+      bluebird: 3.7.2
+      chownr: 1.1.4
+      figgy-pudding: 3.5.2
+      glob: 7.2.3
+      graceful-fs: 4.2.10
+      infer-owner: 1.0.4
+      lru-cache: 5.1.1
+      mississippi: 3.0.0
+      mkdirp: 0.5.5
+      move-concurrently: 1.0.1
+      promise-inflight: 1.0.1_bluebird@3.7.2
+      rimraf: 2.7.1
+      ssri: 6.0.2
+      unique-filename: 1.1.1
+      y18n: 4.0.3
+    dev: true
+
+  /cacache/15.3.0:
+    resolution: {integrity: 
sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==}
+    engines: {node: '>= 10'}
+    dependencies:
+      '@npmcli/fs': 1.1.0
+      '@npmcli/move-file': 1.1.2
+      chownr: 2.0.0
+      fs-minipass: 2.1.0
+      glob: 7.2.3
+      infer-owner: 1.0.4
+      lru-cache: 6.0.0
+      minipass: 3.1.6
+      minipass-collect: 1.0.2
+      minipass-flush: 1.0.5
+      minipass-pipeline: 1.2.4
+      mkdirp: 1.0.4
+      p-map: 4.0.0
+      promise-inflight: 1.0.1
+      rimraf: 3.0.2
+      ssri: 8.0.1
+      tar: 6.1.11
+      unique-filename: 1.1.1
+    transitivePeerDependencies:
+      - bluebird
+    dev: true
+
+  /cache-base/1.0.1:
+    resolution: {integrity: 
sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      collection-visit: 1.0.0
+      component-emitter: 1.3.0
+      get-value: 2.0.6
+      has-value: 1.0.0
+      isobject: 3.0.1
+      set-value: 2.0.1
+      to-object-path: 0.3.0
+      union-value: 1.0.1
+      unset-value: 1.0.0
+    dev: true
+
+  /cacheable-request/6.1.0:
+    resolution: {integrity: 
sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==}
+    engines: {node: '>=8'}
+    dependencies:
+      clone-response: 1.0.2
+      get-stream: 5.2.0
+      http-cache-semantics: 4.1.0
+      keyv: 3.1.0
+      lowercase-keys: 2.0.0
+      normalize-url: 4.5.1
+      responselike: 1.0.2
+    dev: true
+
+  /caching-transform/4.0.0:
+    resolution: {integrity: 
sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==}
+    engines: {node: '>=8'}
+    dependencies:
+      hasha: 5.2.2
+      make-dir: 3.1.0
+      package-hash: 4.0.0
+      write-file-atomic: 3.0.3
+    dev: true
+
+  /call-bind/1.0.2:
+    resolution: {integrity: 
sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==}
+    dependencies:
+      function-bind: 1.1.1
+      get-intrinsic: 1.1.1
+    dev: true
+
+  /call-me-maybe/1.0.1:
+    resolution: {integrity: 
sha512-wCyFsDQkKPwwF8BDwOiWNx/9K45L/hvggQiDbve+viMNMQnWhrlYIuBk09offfwCRtCO9P6XwUttufzU11WCVw==}
+    dev: true
+
+  /caller-callsite/2.0.0:
+    resolution: {integrity: 
sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==}
+    engines: {node: '>=4'}
+    dependencies:
+      callsites: 2.0.0
+    dev: true
+
+  /caller-path/2.0.0:
+    resolution: {integrity: 
sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==}
+    engines: {node: '>=4'}
+    dependencies:
+      caller-callsite: 2.0.0
+    dev: true
+
+  /callsites/2.0.0:
+    resolution: {integrity: 
sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==}
+    engines: {node: '>=4'}
+    dev: true
+
+  /callsites/3.1.0:
+    resolution: {integrity: 
sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
+    engines: {node: '>=6'}
+    dev: true
+
+  /callsites/4.0.0:
+    resolution: {integrity: 
sha512-y3jRROutgpKdz5vzEhWM34TidDU8vkJppF8dszITeb1PQmSqV3DTxyV8G/lyO/DNvtE1YTedehmw9MPZsCBHxQ==}
+    engines: {node: '>=12.20'}
+    dev: true
+
+  /camel-case/3.0.0:
+    resolution: {integrity: 
sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==}
+    dependencies:
+      no-case: 2.3.2
+      upper-case: 1.1.3
+    dev: true
+
+  /camel-case/4.1.2:
+    resolution: {integrity: 
sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==}
+    dependencies:
+      pascal-case: 3.1.2
+      tslib: 2.4.0
+    dev: true
+
+  /camelcase-css/2.0.1:
+    resolution: {integrity: 
sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
+    engines: {node: '>= 6'}
+    dev: true
+
+  /camelcase-keys/2.1.0:
+    resolution: {integrity: 
sha512-bA/Z/DERHKqoEOrp+qeGKw1QlvEQkGZSc0XaY6VnTxZr+Kv1G5zFwttpjv8qxZ/sBPT4nthwZaAcsAZTJlSKXQ==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      camelcase: 2.1.1
+      map-obj: 1.0.1
+    dev: true
+    optional: true
+
+  /camelcase/2.1.1:
+    resolution: {integrity: 
sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+    optional: true
+
+  /camelcase/5.3.1:
+    resolution: {integrity: 
sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
+    engines: {node: '>=6'}
+    dev: true
+
+  /camelcase/6.3.0:
+    resolution: {integrity: 
sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
+    engines: {node: '>=10'}
+    dev: true
+
+  /caniuse-api/3.0.0:
+    resolution: {integrity: 
sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==}
+    dependencies:
+      browserslist: 4.21.4
+      caniuse-lite: 1.0.30001423
+      lodash.memoize: 4.1.2
+      lodash.uniq: 4.5.0
+    dev: true
+
+  /caniuse-lite/1.0.30001311:
+    resolution: {integrity: 
sha512-mleTFtFKfykEeW34EyfhGIFjGCqzhh38Y0LhdQ9aWF+HorZTtdgKV/1hEE0NlFkG2ubvisPV6l400tlbPys98A==}
+    dev: true
+
+  /caniuse-lite/1.0.30001423:
+    resolution: {integrity: 
sha512-09iwWGOlifvE1XuHokFMP7eR38a0JnajoyL3/i87c8ZjRWRrdKo1fqjNfugfBD0UDBIOz0U+jtNhJ0EPm1VleQ==}
+    dev: true
+
+  /capture-exit/2.0.0:
+    resolution: {integrity: 
sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==}
+    engines: {node: 6.* || 8.* || >= 10.*}
+    dependencies:
+      rsvp: 4.8.5
+    dev: true
+
+  /case-sensitive-paths-webpack-plugin/2.4.0:
+    resolution: {integrity: 
sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==}
+    engines: {node: '>=4'}
+    dev: true
+
+  /caseless/0.12.0:
+    resolution: {integrity: 
sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==}
+    dev: true
+
+  /cbor/8.1.0:
+    resolution: {integrity: 
sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==}
+    engines: {node: '>=12.19'}
+    dependencies:
+      nofilter: 3.1.0
+    dev: true
+
+  /ccount/1.1.0:
+    resolution: {integrity: 
sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==}
+    dev: true
+
+  /chai/4.3.6:
+    resolution: {integrity: 
sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==}
+    engines: {node: '>=4'}
+    dependencies:
+      assertion-error: 1.1.0
+      check-error: 1.0.2
+      deep-eql: 3.0.1
+      get-func-name: 2.0.0
+      loupe: 2.3.4
+      pathval: 1.1.1
+      type-detect: 4.0.8
+
+  /chalk/0.4.0:
+    resolution: {integrity: 
sha512-sQfYDlfv2DGVtjdoQqxS0cEZDroyG8h6TamA6rvxwlrU5BaSLDx9xhatBYl2pxZ7gmpNaPFVwBtdGdu5rQ+tYQ==}
+    engines: {node: '>=0.8.0'}
+    dependencies:
+      ansi-styles: 1.0.0
+      has-color: 0.1.7
+      strip-ansi: 0.1.1
+    dev: true
+
+  /chalk/2.4.1:
+    resolution: {integrity: 
sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==}
+    engines: {node: '>=4'}
+    dependencies:
+      ansi-styles: 3.2.1
+      escape-string-regexp: 1.0.5
+      supports-color: 5.5.0
+    dev: true
+
+  /chalk/2.4.2:
+    resolution: {integrity: 
sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
+    engines: {node: '>=4'}
+    dependencies:
+      ansi-styles: 3.2.1
+      escape-string-regexp: 1.0.5
+      supports-color: 5.5.0
+    dev: true
+
+  /chalk/3.0.0:
+    resolution: {integrity: 
sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==}
+    engines: {node: '>=8'}
+    dependencies:
+      ansi-styles: 4.3.0
+      supports-color: 7.2.0
+    dev: true
+
+  /chalk/4.1.2:
+    resolution: {integrity: 
sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
+    engines: {node: '>=10'}
+    dependencies:
+      ansi-styles: 4.3.0
+      supports-color: 7.2.0
+    dev: true
+
+  /chalk/5.1.2:
+    resolution: {integrity: 
sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ==}
+    engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
+    dev: true
+
+  /char-regex/1.0.2:
+    resolution: {integrity: 
sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==}
+    engines: {node: '>=10'}
+    dev: true
+
+  /char-regex/2.0.1:
+    resolution: {integrity: 
sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw==}
+    engines: {node: '>=12.20'}
+    dev: true
+
+  /character-entities-legacy/1.1.4:
+    resolution: {integrity: 
sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==}
+    dev: true
+
+  /character-entities/1.2.4:
+    resolution: {integrity: 
sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==}
+    dev: true
+
+  /character-reference-invalid/1.1.4:
+    resolution: {integrity: 
sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==}
+    dev: true
+
+  /charcodes/0.2.0:
+    resolution: {integrity: 
sha512-Y4kiDb+AM4Ecy58YkuZrrSRJBDQdQ2L+NyS1vHHFtNtUjgutcZfx3yp1dAONI/oPaPmyGfCLx5CxL+zauIMyKQ==}
+    engines: {node: '>=6'}
+    dev: true
+
+  /check-error/1.0.2:
+    resolution: {integrity: 
sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==}
+
+  /check-types/8.0.3:
+    resolution: {integrity: 
sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ==}
+    dev: true
+
+  /cheerio-select/2.1.0:
+    resolution: {integrity: 
sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==}
+    dependencies:
+      boolbase: 1.0.0
+      css-select: 5.1.0
+      css-what: 6.1.0
+      domelementtype: 2.3.0
+      domhandler: 5.0.3
+      domutils: 3.0.1
+    dev: true
+
+  /cheerio/1.0.0-rc.12:
+    resolution: {integrity: 
sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==}
+    engines: {node: '>= 6'}
+    dependencies:
+      cheerio-select: 2.1.0
+      dom-serializer: 2.0.0
+      domhandler: 5.0.3
+      domutils: 3.0.1
+      htmlparser2: 8.0.1
+      parse5: 7.1.1
+      parse5-htmlparser2-tree-adapter: 7.0.0
+    dev: true
+
+  /chokidar/2.1.8:
+    resolution: {integrity: 
sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==}
+    deprecated: Chokidar 2 does not receive security updates since 2019. 
Upgrade to chokidar 3 with 15x fewer dependencies
+    dependencies:
+      anymatch: 2.0.0
+      async-each: 1.0.3
+      braces: 2.3.2
+      glob-parent: 3.1.0
+      inherits: 2.0.4
+      is-binary-path: 1.0.1
+      is-glob: 4.0.3
+      normalize-path: 3.0.0
+      path-is-absolute: 1.0.1
+      readdirp: 2.2.1
+      upath: 1.2.0
+    optionalDependencies:
+      fsevents: 1.2.13
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+    optional: true
+
+  /chokidar/2.1.8_supports-color@6.1.0:
+    resolution: {integrity: 
sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==}
+    deprecated: Chokidar 2 does not receive security updates since 2019. 
Upgrade to chokidar 3 with 15x fewer dependencies
+    dependencies:
+      anymatch: 2.0.0_supports-color@6.1.0
+      async-each: 1.0.3
+      braces: 2.3.2_supports-color@6.1.0
+      glob-parent: 3.1.0
+      inherits: 2.0.4
+      is-binary-path: 1.0.1
+      is-glob: 4.0.3
+      normalize-path: 3.0.0
+      path-is-absolute: 1.0.1
+      readdirp: 2.2.1_supports-color@6.1.0
+      upath: 1.2.0
+    optionalDependencies:
+      fsevents: 1.2.13
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /chokidar/3.5.3:
+    resolution: {integrity: 
sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
+    engines: {node: '>= 8.10.0'}
+    dependencies:
+      anymatch: 3.1.2
+      braces: 3.0.2
+      glob-parent: 5.1.2
+      is-binary-path: 2.1.0
+      is-glob: 4.0.3
+      normalize-path: 3.0.0
+      readdirp: 3.6.0
+    optionalDependencies:
+      fsevents: 2.3.2
+    dev: true
+
+  /chownr/1.1.4:
+    resolution: {integrity: 
sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
+    dev: true
+
+  /chownr/2.0.0:
+    resolution: {integrity: 
sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==}
+    engines: {node: '>=10'}
+    dev: true
+
+  /chrome-trace-event/1.0.3:
+    resolution: {integrity: 
sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==}
+    engines: {node: '>=6.0'}
+    dev: true
+
+  /chunkd/2.0.1:
+    resolution: {integrity: 
sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==}
+    dev: true
+
+  /ci-env/1.17.0:
+    resolution: {integrity: 
sha512-NtTjhgSEqv4Aj90TUYHQLxHdnCPXnjdtuGG1X8lTfp/JqeXTdw0FTWl/vUAPuvbWZTF8QVpv6ASe/XacE+7R2A==}
+    dev: true
+
+  /ci-info/2.0.0:
+    resolution: {integrity: 
sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==}
+    dev: true
+
+  /ci-info/3.5.0:
+    resolution: {integrity: 
sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==}
+    dev: true
+
+  /ci-parallel-vars/1.0.1:
+    resolution: {integrity: 
sha512-uvzpYrpmidaoxvIQHM+rKSrigjOe9feHYbw4uOI2gdfe1C3xIlxO+kVXq83WQWNniTf8bAxVpy+cQeFQsMERKg==}
+    dev: true
+
+  /cipher-base/1.0.4:
+    resolution: {integrity: 
sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==}
+    dependencies:
+      inherits: 2.0.4
+      safe-buffer: 5.2.1
+    dev: true
+
+  /cjs-module-lexer/0.6.0:
+    resolution: {integrity: 
sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==}
+    dev: true
+
+  /cjs-module-lexer/1.2.2:
+    resolution: {integrity: 
sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==}
+    dev: true
+
+  /class-utils/0.3.6:
+    resolution: {integrity: 
sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      arr-union: 3.1.0
+      define-property: 0.2.5
+      isobject: 3.0.1
+      static-extend: 0.1.2
+    dev: true
+
+  /clean-css/4.2.4:
+    resolution: {integrity: 
sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==}
+    engines: {node: '>= 4.0'}
+    dependencies:
+      source-map: 0.6.1
+    dev: true
+
+  /clean-stack/2.2.0:
+    resolution: {integrity: 
sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==}
+    engines: {node: '>=6'}
+    dev: true
+
+  /clean-stack/4.2.0:
+    resolution: {integrity: 
sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==}
+    engines: {node: '>=12'}
+    dependencies:
+      escape-string-regexp: 5.0.0
+    dev: true
+
+  /clean-yaml-object/0.1.0:
+    resolution: {integrity: 
sha512-3yONmlN9CSAkzNwnRCiJQ7Q2xK5mWuEfL3PuTZcAUzhObbXsfsnMptJzXwz93nc5zn9V9TwCVMmV7w4xsm43dw==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /cli-boxes/2.2.1:
+    resolution: {integrity: 
sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==}
+    engines: {node: '>=6'}
+    dev: true
+
+  /cli-cursor/3.1.0:
+    resolution: {integrity: 
sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==}
+    engines: {node: '>=8'}
+    dependencies:
+      restore-cursor: 3.1.0
+    dev: true
+
+  /cli-spinners/2.6.1:
+    resolution: {integrity: 
sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==}
+    engines: {node: '>=6'}
+    dev: true
+
+  /cli-table3/0.6.0:
+    resolution: {integrity: 
sha512-gnB85c3MGC7Nm9I/FkiasNBOKjOiO1RNuXXarQms37q4QMpWdlbBgD/VnOStA2faG1dpXMv31RFApjX1/QdgWQ==}
+    engines: {node: 10.* || >= 12.*}
+    dependencies:
+      object-assign: 4.1.1
+      string-width: 4.2.3
+    optionalDependencies:
+      colors: 1.4.0
+    dev: true
+
+  /cli-table3/0.6.3:
+    resolution: {integrity: 
sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==}
+    engines: {node: 10.* || >= 12.*}
+    dependencies:
+      string-width: 4.2.3
+    optionalDependencies:
+      '@colors/colors': 1.5.0
+    dev: true
+
+  /cli-truncate/3.1.0:
+    resolution: {integrity: 
sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==}
+    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+    dependencies:
+      slice-ansi: 5.0.0
+      string-width: 5.1.2
+    dev: true
+
+  /cliui/5.0.0:
+    resolution: {integrity: 
sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==}
+    dependencies:
+      string-width: 3.1.0
+      strip-ansi: 5.2.0
+      wrap-ansi: 5.1.0
+    dev: true
+
+  /cliui/6.0.0:
+    resolution: {integrity: 
sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==}
+    dependencies:
+      string-width: 4.2.3
+      strip-ansi: 6.0.1
+      wrap-ansi: 6.2.0
+    dev: true
+
+  /cliui/7.0.4:
+    resolution: {integrity: 
sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==}
+    dependencies:
+      string-width: 4.2.3
+      strip-ansi: 6.0.1
+      wrap-ansi: 7.0.0
+    dev: true
+
+  /cliui/8.0.1:
+    resolution: {integrity: 
sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
+    engines: {node: '>=12'}
+    dependencies:
+      string-width: 4.2.3
+      strip-ansi: 6.0.1
+      wrap-ansi: 7.0.0
+    dev: true
+
+  /clone-deep/4.0.1:
+    resolution: {integrity: 
sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==}
+    engines: {node: '>=6'}
+    dependencies:
+      is-plain-object: 2.0.4
+      kind-of: 6.0.3
+      shallow-clone: 3.0.1
+    dev: true
+
+  /clone-response/1.0.2:
+    resolution: {integrity: 
sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==}
+    dependencies:
+      mimic-response: 1.0.1
+    dev: true
+
+  /clone/1.0.4:
+    resolution: {integrity: 
sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==}
+    engines: {node: '>=0.8'}
+    dev: true
+
+  /clsx/1.2.1:
+    resolution: {integrity: 
sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==}
+    engines: {node: '>=6'}
+    dev: true
+
+  /co/4.6.0:
+    resolution: {integrity: 
sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==}
+    engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'}
+    dev: true
+
+  /coa/2.0.2:
+    resolution: {integrity: 
sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==}
+    engines: {node: '>= 4.0'}
+    dependencies:
+      '@types/q': 1.5.5
+      chalk: 2.4.2
+      q: 1.5.1
+    dev: true
+
+  /code-excerpt/4.0.0:
+    resolution: {integrity: 
sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==}
+    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+    dependencies:
+      convert-to-spaces: 2.0.1
+    dev: true
+
+  /code-point-at/1.1.0:
+    resolution: {integrity: 
sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /collapse-white-space/1.0.6:
+    resolution: {integrity: 
sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==}
+    dev: true
+
+  /collect-v8-coverage/1.0.1:
+    resolution: {integrity: 
sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==}
+    dev: true
+
+  /collection-visit/1.0.0:
+    resolution: {integrity: 
sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      map-visit: 1.0.0
+      object-visit: 1.0.1
+    dev: true
+
+  /color-convert/1.9.3:
+    resolution: {integrity: 
sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
+    dependencies:
+      color-name: 1.1.3
+    dev: true
+
+  /color-convert/2.0.1:
+    resolution: {integrity: 
sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+    engines: {node: '>=7.0.0'}
+    dependencies:
+      color-name: 1.1.4
+    dev: true
+
+  /color-name/1.1.3:
+    resolution: {integrity: 
sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
+    dev: true
+
+  /color-name/1.1.4:
+    resolution: {integrity: 
sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+    dev: true
+
+  /color-string/1.9.0:
+    resolution: {integrity: 
sha512-9Mrz2AQLefkH1UvASKj6v6hj/7eWgjnT/cVsR8CumieLoT+g900exWeNogqtweI8dxloXN9BDQTYro1oWu/5CQ==}
+    dependencies:
+      color-name: 1.1.4
+      simple-swizzle: 0.2.2
+    dev: true
+
+  /color-support/1.1.3:
+    resolution: {integrity: 
sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==}
+    hasBin: true
+    dev: true
+
+  /color/3.2.1:
+    resolution: {integrity: 
sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==}
+    dependencies:
+      color-convert: 1.9.3
+      color-string: 1.9.0
+    dev: true
+
+  /colord/2.9.2:
+    resolution: {integrity: 
sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ==}
+    dev: true
+
+  /colorette/2.0.16:
+    resolution: {integrity: 
sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==}
+    dev: true
+
+  /colors/1.4.0:
+    resolution: {integrity: 
sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==}
+    engines: {node: '>=0.1.90'}
+    dev: true
+
+  /combined-stream/1.0.8:
+    resolution: {integrity: 
sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
+    engines: {node: '>= 0.8'}
+    dependencies:
+      delayed-stream: 1.0.0
+
+  /comma-separated-tokens/1.0.8:
+    resolution: {integrity: 
sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==}
+    dev: true
+
+  /commander/2.17.1:
+    resolution: {integrity: 
sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==}
+    dev: true
+
+  /commander/2.19.0:
+    resolution: {integrity: 
sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==}
+    dev: true
+
+  /commander/2.20.3:
+    resolution: {integrity: 
sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
+    dev: true
+
+  /commander/4.1.1:
+    resolution: {integrity: 
sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
+    engines: {node: '>= 6'}
+    dev: true
+
+  /commander/6.2.1:
+    resolution: {integrity: 
sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==}
+    engines: {node: '>= 6'}
+    dev: true
+
+  /commander/7.2.0:
+    resolution: {integrity: 
sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
+    engines: {node: '>= 10'}
+    dev: true
+
+  /common-path-prefix/3.0.0:
+    resolution: {integrity: 
sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==}
+    dev: true
+
+  /common-tags/1.8.2:
+    resolution: {integrity: 
sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==}
+    engines: {node: '>=4.0.0'}
+    dev: true
+
+  /commondir/1.0.1:
+    resolution: {integrity: 
sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==}
+    dev: true
+
+  /component-emitter/1.3.0:
+    resolution: {integrity: 
sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==}
+    dev: true
+
+  /compressible/2.0.18:
+    resolution: {integrity: 
sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==}
+    engines: {node: '>= 0.6'}
+    dependencies:
+      mime-db: 1.52.0
+    dev: true
+
+  /compression-webpack-plugin/4.0.1_webpack@4.46.0:
+    resolution: {integrity: 
sha512-0mg6PgwTsUe5LEcUrOu3ob32vraDx2VdbMGAT1PARcOV+UJWDYZFdkSo6RbHoGQ061mmmkC7XpRKOlvwm/gzJQ==}
+    engines: {node: '>= 10.13.0'}
+    peerDependencies:
+      webpack: ^4.0.0 || ^5.0.0
+    dependencies:
+      cacache: 15.3.0
+      find-cache-dir: 3.3.2
+      schema-utils: 2.7.1
+      serialize-javascript: 4.0.0
+      webpack: 4.46.0
+      webpack-sources: 1.4.3
+    transitivePeerDependencies:
+      - bluebird
+    dev: true
+
+  /compression-webpack-plugin/6.1.1_webpack@4.46.0:
+    resolution: {integrity: 
sha512-BEHft9M6lwOqVIQFMS/YJGmeCYXVOakC5KzQk05TFpMBlODByh1qNsZCWjUBxCQhUP9x0WfGidxTbGkjbWO/TQ==}
+    engines: {node: '>= 10.13.0'}
+    peerDependencies:
+      webpack: ^4.0.0 || ^5.0.0
+    dependencies:
+      cacache: 15.3.0
+      find-cache-dir: 3.3.2
+      schema-utils: 3.1.1
+      serialize-javascript: 5.0.1
+      webpack: 4.46.0
+      webpack-sources: 1.4.3
+    transitivePeerDependencies:
+      - bluebird
+    dev: true
+
+  /compression/1.7.4:
+    resolution: {integrity: 
sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==}
+    engines: {node: '>= 0.8.0'}
+    dependencies:
+      accepts: 1.3.8
+      bytes: 3.0.0
+      compressible: 2.0.18
+      debug: 2.6.9
+      on-headers: 1.0.2
+      safe-buffer: 5.1.2
+      vary: 1.1.2
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /compression/1.7.4_supports-color@6.1.0:
+    resolution: {integrity: 
sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==}
+    engines: {node: '>= 0.8.0'}
+    dependencies:
+      accepts: 1.3.8
+      bytes: 3.0.0
+      compressible: 2.0.18
+      debug: 2.6.9_supports-color@6.1.0
+      on-headers: 1.0.2
+      safe-buffer: 5.1.2
+      vary: 1.1.2
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /compute-scroll-into-view/1.0.17:
+    resolution: {integrity: 
sha512-j4dx+Fb0URmzbwwMUrhqWM2BEWHdFGx+qZ9qqASHRPqvTYdqvWnHg0H1hIbcyLnvgnoNAVMlwkepyqM3DaIFUg==}
+    dev: true
+
+  /concat-map/0.0.1:
+    resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
+
+  /concat-stream/1.6.2:
+    resolution: {integrity: 
sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==}
+    engines: {'0': node >= 0.8}
+    dependencies:
+      buffer-from: 1.1.2
+      inherits: 2.0.4
+      readable-stream: 2.3.7
+      typedarray: 0.0.6
+    dev: true
+
+  /concordance/5.0.4:
+    resolution: {integrity: 
sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==}
+    engines: {node: '>=10.18.0 <11 || >=12.14.0 <13 || >=14'}
+    dependencies:
+      date-time: 3.1.0
+      esutils: 2.0.3
+      fast-diff: 1.2.0
+      js-string-escape: 1.0.1
+      lodash: 4.17.21
+      md5-hex: 3.0.1
+      semver: 7.3.8
+      well-known-symbols: 2.0.0
+    dev: true
+
+  /configstore/5.0.1:
+    resolution: {integrity: 
sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==}
+    engines: {node: '>=8'}
+    dependencies:
+      dot-prop: 5.3.0
+      graceful-fs: 4.2.10
+      make-dir: 3.1.0
+      unique-string: 2.0.0
+      write-file-atomic: 3.0.3
+      xdg-basedir: 4.0.0
+    dev: true
+
+  /confusing-browser-globals/1.0.11:
+    resolution: {integrity: 
sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==}
+    dev: true
+
+  /connect-history-api-fallback/1.6.0:
+    resolution: {integrity: 
sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==}
+    engines: {node: '>=0.8'}
+    dev: true
+
+  /console-browserify/1.2.0:
+    resolution: {integrity: 
sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==}
+    dev: true
+
+  /console-clear/1.1.1:
+    resolution: {integrity: 
sha512-pMD+MVR538ipqkG5JXeOEbKWS5um1H4LUUccUQG68qpeqBYbzYy79Gh55jkd2TtPdRfUaLWdv6LPP//5Zt0aPQ==}
+    engines: {node: '>=4'}
+    dev: true
+
+  /console-control-strings/1.1.0:
+    resolution: {integrity: 
sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==}
+    dev: true
+
+  /constants-browserify/1.0.0:
+    resolution: {integrity: 
sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==}
+    dev: true
+
+  /content-disposition/0.5.4:
+    resolution: {integrity: 
sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==}
+    engines: {node: '>= 0.6'}
+    dependencies:
+      safe-buffer: 5.2.1
+    dev: true
+
+  /content-type/1.0.4:
+    resolution: {integrity: 
sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==}
+    engines: {node: '>= 0.6'}
+    dev: true
+
+  /convert-source-map/1.8.0:
+    resolution: {integrity: 
sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==}
+    dependencies:
+      safe-buffer: 5.1.2
+    dev: true
+
+  /convert-to-spaces/2.0.1:
+    resolution: {integrity: 
sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==}
+    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+    dev: true
+
+  /cookie-signature/1.0.6:
+    resolution: {integrity: sha1-4wOogrNCzD7oylE6eZmXNNqzriw=}
+    dev: true
+
+  /cookie/0.4.1:
+    resolution: {integrity: 
sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==}
+    engines: {node: '>= 0.6'}
+    dev: true
+
+  /copy-concurrently/1.0.5:
+    resolution: {integrity: 
sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==}
+    dependencies:
+      aproba: 1.2.0
+      fs-write-stream-atomic: 1.0.10
+      iferr: 0.1.5
+      mkdirp: 0.5.5
+      rimraf: 2.7.1
+      run-queue: 1.0.3
+    dev: true
+
+  /copy-descriptor/0.1.1:
+    resolution: {integrity: 
sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /copy-to-clipboard/3.3.2:
+    resolution: {integrity: 
sha512-Vme1Z6RUDzrb6xAI7EZlVZ5uvOk2F//GaxKUxajDqm9LhOVM1inxNAD2vy+UZDYsd0uyA9s7b3/FVZPSxqrCfg==}
+    dependencies:
+      toggle-selection: 1.0.6
+    dev: true
+
+  /copy-webpack-plugin/5.1.2_webpack@4.46.0:
+    resolution: {integrity: 
sha512-Uh7crJAco3AjBvgAy9Z75CjK8IG+gxaErro71THQ+vv/bl4HaQcpkexAY8KVW/T6D2W2IRr+couF/knIRkZMIQ==}
+    engines: {node: '>= 6.9.0'}
+    peerDependencies:
+      webpack: ^4.0.0 || ^5.0.0
+    dependencies:
+      cacache: 12.0.4
+      find-cache-dir: 2.1.0
+      glob-parent: 3.1.0
+      globby: 7.1.1
+      is-glob: 4.0.3
+      loader-utils: 1.4.0
+      minimatch: 3.1.2
+      normalize-path: 3.0.0
+      p-limit: 2.3.0
+      schema-utils: 1.0.0
+      serialize-javascript: 4.0.0
+      webpack: 4.46.0
+      webpack-log: 2.0.0
+    dev: true
+
+  /copy-webpack-plugin/6.4.1_webpack@4.46.0:
+    resolution: {integrity: 
sha512-MXyPCjdPVx5iiWyl40Va3JGh27bKzOTNY3NjUTrosD2q7dR/cLD0013uqJ3BpFbUjyONINjb6qI7nDIJujrMbA==}
+    engines: {node: '>= 10.13.0'}
+    peerDependencies:
+      webpack: ^4.37.0 || ^5.0.0
+    dependencies:
+      cacache: 15.3.0
+      fast-glob: 3.2.11
+      find-cache-dir: 3.3.2
+      glob-parent: 5.1.2
+      globby: 11.1.0
+      loader-utils: 2.0.2
+      normalize-path: 3.0.0
+      p-limit: 3.1.0
+      schema-utils: 3.1.1
+      serialize-javascript: 5.0.1
+      webpack: 4.46.0
+      webpack-sources: 1.4.3
+    transitivePeerDependencies:
+      - bluebird
+    dev: true
+
+  /core-js-compat/3.21.0:
+    resolution: {integrity: 
sha512-OSXseNPSK2OPJa6GdtkMz/XxeXx8/CJvfhQWTqd6neuUraujcL4jVsjkLQz1OWnax8xVQJnRPe0V2jqNWORA+A==}
+    dependencies:
+      browserslist: 4.19.1
+      semver: 7.0.0
+    dev: true
+
+  /core-js-pure/3.20.2:
+    resolution: {integrity: 
sha512-CmWHvSKn2vNL6p6StNp1EmMIfVY/pqn3JLAjfZQ8WZGPOlGoO92EkX9/Mk81i6GxvoPXjUqEQnpM3rJ5QxxIOg==}
+    deprecated: core-js-pure@<3.23.3 is no longer maintained and not 
recommended for usage due to the number of issues. Because of the V8 engine 
whims, feature detection in old core-js versions could cause a slowdown up to 
100x even if nothing is polyfilled. Some versions have web compatibility 
issues. Please, upgrade your dependencies to the actual version of core-js-pure.
+    requiresBuild: true
+    dev: true
+
+  /core-js/2.6.12:
+    resolution: {integrity: 
sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==}
+    deprecated: core-js@<3.23.3 is no longer maintained and not recommended 
for usage due to the number of issues. Because of the V8 engine whims, feature 
detection in old core-js versions could cause a slowdown up to 100x even if 
nothing is polyfilled. Some versions have web compatibility issues. Please, 
upgrade your dependencies to the actual version of core-js.
+    requiresBuild: true
+    dev: true
+
+  /core-js/3.26.0:
+    resolution: {integrity: 
sha512-+DkDrhoR4Y0PxDz6rurahuB+I45OsEUv8E1maPTB6OuHRohMMcznBq9TMpdpDMm/hUPob/mJJS3PqgbHpMTQgw==}
+    requiresBuild: true
+    dev: true
+
+  /core-util-is/1.0.2:
+    resolution: {integrity: 
sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==}
+    dev: true
+
+  /core-util-is/1.0.3:
+    resolution: {integrity: 
sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
+    dev: true
+
+  /cosmiconfig/5.2.1:
+    resolution: {integrity: 
sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==}
+    engines: {node: '>=4'}
+    dependencies:
+      import-fresh: 2.0.0
+      is-directory: 0.3.1
+      js-yaml: 3.14.1
+      parse-json: 4.0.0
+    dev: true
+
+  /cosmiconfig/6.0.0:
+    resolution: {integrity: 
sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==}
+    engines: {node: '>=8'}
+    dependencies:
+      '@types/parse-json': 4.0.0
+      import-fresh: 3.3.0
+      parse-json: 5.2.0
+      path-type: 4.0.0
+      yaml: 1.10.2
+    dev: true
+
+  /cosmiconfig/7.0.1:
+    resolution: {integrity: 
sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==}
+    engines: {node: '>=10'}
+    dependencies:
+      '@types/parse-json': 4.0.0
+      import-fresh: 3.3.0
+      parse-json: 5.2.0
+      path-type: 4.0.0
+      yaml: 1.10.2
+    dev: true
+
+  /cp-file/7.0.0:
+    resolution: {integrity: 
sha512-0Cbj7gyvFVApzpK/uhCtQ/9kE9UnYpxMzaq5nQQC/Dh4iaj5fxp7iEFIullrYwzj8nf0qnsI1Qsx34hAeAebvw==}
+    engines: {node: '>=8'}
+    dependencies:
+      graceful-fs: 4.2.10
+      make-dir: 3.1.0
+      nested-error-stacks: 2.1.1
+      p-event: 4.2.0
+    dev: true
+
+  /cpy/8.1.2:
+    resolution: {integrity: 
sha512-dmC4mUesv0OYH2kNFEidtf/skUwv4zePmGeepjyyJ0qTo5+8KhA1o99oIAwVVLzQMAeDJml74d6wPPKb6EZUTg==}
+    engines: {node: '>=8'}
+    dependencies:
+      arrify: 2.0.1
+      cp-file: 7.0.0
+      globby: 9.2.0
+      has-glob: 1.0.0
+      junk: 3.1.0
+      nested-error-stacks: 2.1.1
+      p-all: 2.1.0
+      p-filter: 2.1.0
+      p-map: 3.0.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /create-ecdh/4.0.4:
+    resolution: {integrity: 
sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==}
+    dependencies:
+      bn.js: 4.12.0
+      elliptic: 6.5.4
+    dev: true
+
+  /create-hash/1.2.0:
+    resolution: {integrity: 
sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==}
+    dependencies:
+      cipher-base: 1.0.4
+      inherits: 2.0.4
+      md5.js: 1.3.5
+      ripemd160: 2.0.2
+      sha.js: 2.4.11
+    dev: true
+
+  /create-hmac/1.1.7:
+    resolution: {integrity: 
sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==}
+    dependencies:
+      cipher-base: 1.0.4
+      create-hash: 1.2.0
+      inherits: 2.0.4
+      ripemd160: 2.0.2
+      safe-buffer: 5.2.1
+      sha.js: 2.4.11
+    dev: true
+
+  /create-react-context/0.3.0_4vyaxm4rsh2mpfdenvlqy7kmya:
+    resolution: {integrity: 
sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw==}
+    peerDependencies:
+      prop-types: ^15.0.0
+      react: ^0.14.0 || ^15.0.0 || ^16.0.0
+    dependencies:
+      gud: 1.0.0
+      prop-types: 15.8.1
+      react: 16.14.0
+      warning: 4.0.3
+    dev: true
+
+  /create-react-context/0.3.0_prop-types@15.8.1:
+    resolution: {integrity: 
sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw==}
+    peerDependencies:
+      prop-types: ^15.0.0
+      react: ^0.14.0 || ^15.0.0 || ^16.0.0
+    dependencies:
+      gud: 1.0.0
+      prop-types: 15.8.1
+      warning: 4.0.3
+    dev: true
+
+  /critters-webpack-plugin/2.5.0_html-webpack-plugin@3.2.0:
+    resolution: {integrity: 
sha512-O41TSPV2orAfrV6kSVC0SivZCtVkeypCNKb7xtrbqE/CfjrHeRaFaGuxglcjOI2IGf+oNg6E+ZoOktdlhXPTIQ==}
+    peerDependencies:
+      html-webpack-plugin: '*'
+    peerDependenciesMeta:
+      html-webpack-plugin:
+        optional: true
+    dependencies:
+      css: 2.2.4
+      cssnano: 4.1.11
+      html-webpack-plugin: 3.2.0_webpack@4.46.0
+      jsdom: 12.2.0
+      minimatch: 3.1.2
+      parse5: 4.0.0
+      postcss: 7.0.39
+      pretty-bytes: 4.0.2
+      webpack-log: 2.0.0
+      webpack-sources: 1.4.3
+    transitivePeerDependencies:
+      - bufferutil
+      - utf-8-validate
+    dev: true
+
+  /cross-fetch/3.1.5:
+    resolution: {integrity: 
sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==}
+    dependencies:
+      node-fetch: 2.6.7
+    transitivePeerDependencies:
+      - encoding
+    dev: true
+
+  /cross-spawn-promise/0.10.2:
+    resolution: {integrity: 
sha512-74PXJf6DYaab2klRS+D+9qxKJL1Weo3/ao9OPoH6NFzxtINSa/HE2mcyAPu1fpEmRTPD4Gdmpg3xEXQSgI8lpg==}
+    engines: {node: '>=4'}
+    dependencies:
+      cross-spawn: 5.1.0
+    dev: true
+
+  /cross-spawn/5.1.0:
+    resolution: {integrity: 
sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==}
+    dependencies:
+      lru-cache: 4.1.5
+      shebang-command: 1.2.0
+      which: 1.3.1
+    dev: true
+
+  /cross-spawn/6.0.5:
+    resolution: {integrity: 
sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==}
+    engines: {node: '>=4.8'}
+    dependencies:
+      nice-try: 1.0.5
+      path-key: 2.0.1
+      semver: 5.7.1
+      shebang-command: 1.2.0
+      which: 1.3.1
+    dev: true
+
+  /cross-spawn/7.0.3:
+    resolution: {integrity: 
sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
+    engines: {node: '>= 8'}
+    dependencies:
+      path-key: 3.1.1
+      shebang-command: 2.0.0
+      which: 2.0.2
+    dev: true
+
+  /crypto-browserify/3.12.0:
+    resolution: {integrity: 
sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==}
+    dependencies:
+      browserify-cipher: 1.0.1
+      browserify-sign: 4.2.1
+      create-ecdh: 4.0.4
+      create-hash: 1.2.0
+      create-hmac: 1.1.7
+      diffie-hellman: 5.0.3
+      inherits: 2.0.4
+      pbkdf2: 3.1.2
+      public-encrypt: 4.0.3
+      randombytes: 2.1.0
+      randomfill: 1.0.4
+    dev: true
+
+  /crypto-random-string/1.0.0:
+    resolution: {integrity: 
sha512-GsVpkFPlycH7/fRR7Dhcmnoii54gV1nz7y4CWyeFS14N+JVBBhY+r8amRHE4BwSYal7BPTDp8isvAlCxyFt3Hg==}
+    engines: {node: '>=4'}
+    dev: true
+
+  /crypto-random-string/2.0.0:
+    resolution: {integrity: 
sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==}
+    engines: {node: '>=8'}
+    dev: true
+
+  /css-color-names/0.0.4:
+    resolution: {integrity: 
sha512-zj5D7X1U2h2zsXOAM8EyUREBnnts6H+Jm+d1M2DbiQQcUtnqgQsMrdo8JW9R80YFUmIdBZeMu5wvYM7hcgWP/Q==}
+    dev: true
+
+  /css-declaration-sorter/4.0.1:
+    resolution: {integrity: 
sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==}
+    engines: {node: '>4'}
+    dependencies:
+      postcss: 7.0.39
+      timsort: 0.3.0
+    dev: true
+
+  /css-declaration-sorter/6.1.4_postcss@8.4.6:
+    resolution: {integrity: 
sha512-lpfkqS0fctcmZotJGhnxkIyJWvBXgpyi2wsFd4J8VB7wzyrT6Ch/3Q+FMNJpjK4gu1+GN5khOnpU2ZVKrLbhCw==}
+    engines: {node: '>= 10'}
+    peerDependencies:
+      postcss: ^8.0.9
+    dependencies:
+      postcss: 8.4.6
+      timsort: 0.3.0
+    dev: true
+
+  /css-loader/3.6.0_webpack@4.46.0:
+    resolution: {integrity: 
sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ==}
+    engines: {node: '>= 8.9.0'}
+    peerDependencies:
+      webpack: ^4.0.0 || ^5.0.0
+    dependencies:
+      camelcase: 5.3.1
+      cssesc: 3.0.0
+      icss-utils: 4.1.1
+      loader-utils: 1.4.0
+      normalize-path: 3.0.0
+      postcss: 7.0.39
+      postcss-modules-extract-imports: 2.0.0
+      postcss-modules-local-by-default: 3.0.3
+      postcss-modules-scope: 2.2.0
+      postcss-modules-values: 3.0.0
+      postcss-value-parser: 4.2.0
+      schema-utils: 2.7.1
+      semver: 6.3.0
+      webpack: 4.46.0
+    dev: true
+
+  /css-loader/5.2.7_webpack@4.46.0:
+    resolution: {integrity: 
sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg==}
+    engines: {node: '>= 10.13.0'}
+    peerDependencies:
+      webpack: ^4.27.0 || ^5.0.0
+    dependencies:
+      icss-utils: 5.1.0_postcss@8.4.6
+      loader-utils: 2.0.2
+      postcss: 8.4.6
+      postcss-modules-extract-imports: 3.0.0_postcss@8.4.6
+      postcss-modules-local-by-default: 4.0.0_postcss@8.4.6
+      postcss-modules-scope: 3.0.0_postcss@8.4.6
+      postcss-modules-values: 4.0.0_postcss@8.4.6
+      postcss-value-parser: 4.2.0
+      schema-utils: 3.1.1
+      semver: 7.3.8
+      webpack: 4.46.0
+    dev: true
+
+  /css-select-base-adapter/0.1.1:
+    resolution: {integrity: 
sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==}
+    dev: true
+
+  /css-select/2.1.0:
+    resolution: {integrity: 
sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==}
+    dependencies:
+      boolbase: 1.0.0
+      css-what: 3.4.2
+      domutils: 1.7.0
+      nth-check: 1.0.2
+    dev: true
+
+  /css-select/4.2.1:
+    resolution: {integrity: 
sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==}
+    dependencies:
+      boolbase: 1.0.0
+      css-what: 5.1.0
+      domhandler: 4.3.0
+      domutils: 2.8.0
+      nth-check: 2.0.1
+    dev: true
+
+  /css-select/5.1.0:
+    resolution: {integrity: 
sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==}
+    dependencies:
+      boolbase: 1.0.0
+      css-what: 6.1.0
+      domhandler: 5.0.3
+      domutils: 3.0.1
+      nth-check: 2.0.1
+    dev: true
+
+  /css-tree/1.0.0-alpha.37:
+    resolution: {integrity: 
sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==}
+    engines: {node: '>=8.0.0'}
+    dependencies:
+      mdn-data: 2.0.4
+      source-map: 0.6.1
+    dev: true
+
+  /css-tree/1.1.3:
+    resolution: {integrity: 
sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==}
+    engines: {node: '>=8.0.0'}
+    dependencies:
+      mdn-data: 2.0.14
+      source-map: 0.6.1
+    dev: true
+
+  /css-what/3.4.2:
+    resolution: {integrity: 
sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==}
+    engines: {node: '>= 6'}
+    dev: true
+
+  /css-what/5.1.0:
+    resolution: {integrity: 
sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==}
+    engines: {node: '>= 6'}
+    dev: true
+
+  /css-what/6.1.0:
+    resolution: {integrity: 
sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==}
+    engines: {node: '>= 6'}
+    dev: true
+
+  /css.escape/1.5.1:
+    resolution: {integrity: 
sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==}
+    dev: true
+
+  /css/2.2.4:
+    resolution: {integrity: 
sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==}
+    dependencies:
+      inherits: 2.0.4
+      source-map: 0.6.1
+      source-map-resolve: 0.5.3
+      urix: 0.1.0
+    dev: true
+
+  /cssesc/3.0.0:
+    resolution: {integrity: 
sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
+    engines: {node: '>=4'}
+    hasBin: true
+    dev: true
+
+  /cssnano-preset-default/4.0.8:
+    resolution: {integrity: 
sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      css-declaration-sorter: 4.0.1
+      cssnano-util-raw-cache: 4.0.1
+      postcss: 7.0.39
+      postcss-calc: 7.0.5
+      postcss-colormin: 4.0.3
+      postcss-convert-values: 4.0.1
+      postcss-discard-comments: 4.0.2
+      postcss-discard-duplicates: 4.0.2
+      postcss-discard-empty: 4.0.1
+      postcss-discard-overridden: 4.0.1
+      postcss-merge-longhand: 4.0.11
+      postcss-merge-rules: 4.0.3
+      postcss-minify-font-values: 4.0.2
+      postcss-minify-gradients: 4.0.2
+      postcss-minify-params: 4.0.2
+      postcss-minify-selectors: 4.0.2
+      postcss-normalize-charset: 4.0.1
+      postcss-normalize-display-values: 4.0.2
+      postcss-normalize-positions: 4.0.2
+      postcss-normalize-repeat-style: 4.0.2
+      postcss-normalize-string: 4.0.2
+      postcss-normalize-timing-functions: 4.0.2
+      postcss-normalize-unicode: 4.0.1
+      postcss-normalize-url: 4.0.1
+      postcss-normalize-whitespace: 4.0.2
+      postcss-ordered-values: 4.1.2
+      postcss-reduce-initial: 4.0.3
+      postcss-reduce-transforms: 4.0.2
+      postcss-svgo: 4.0.3
+      postcss-unique-selectors: 4.0.1
+    dev: true
+
+  /cssnano-preset-default/5.1.12_postcss@8.4.6:
+    resolution: {integrity: 
sha512-rO/JZYyjW1QNkWBxMGV28DW7d98UDLaF759frhli58QFehZ+D/LSmwQ2z/ylBAe2hUlsIWTq6NYGfQPq65EF9w==}
+    engines: {node: ^10 || ^12 || >=14.0}
+    peerDependencies:
+      postcss: ^8.2.15
+    dependencies:
+      css-declaration-sorter: 6.1.4_postcss@8.4.6
+      cssnano-utils: 3.0.2_postcss@8.4.6
+      postcss: 8.4.6
+      postcss-calc: 8.2.4_postcss@8.4.6
+      postcss-colormin: 5.2.5_postcss@8.4.6
+      postcss-convert-values: 5.0.4_postcss@8.4.6
+      postcss-discard-comments: 5.0.3_postcss@8.4.6
+      postcss-discard-duplicates: 5.0.3_postcss@8.4.6
+      postcss-discard-empty: 5.0.3_postcss@8.4.6
+      postcss-discard-overridden: 5.0.4_postcss@8.4.6
+      postcss-merge-longhand: 5.0.6_postcss@8.4.6
+      postcss-merge-rules: 5.0.6_postcss@8.4.6
+      postcss-minify-font-values: 5.0.4_postcss@8.4.6
+      postcss-minify-gradients: 5.0.6_postcss@8.4.6
+      postcss-minify-params: 5.0.5_postcss@8.4.6
+      postcss-minify-selectors: 5.1.3_postcss@8.4.6
+      postcss-normalize-charset: 5.0.3_postcss@8.4.6
+      postcss-normalize-display-values: 5.0.3_postcss@8.4.6
+      postcss-normalize-positions: 5.0.4_postcss@8.4.6
+      postcss-normalize-repeat-style: 5.0.4_postcss@8.4.6
+      postcss-normalize-string: 5.0.4_postcss@8.4.6
+      postcss-normalize-timing-functions: 5.0.3_postcss@8.4.6
+      postcss-normalize-unicode: 5.0.4_postcss@8.4.6
+      postcss-normalize-url: 5.0.5_postcss@8.4.6
+      postcss-normalize-whitespace: 5.0.4_postcss@8.4.6
+      postcss-ordered-values: 5.0.5_postcss@8.4.6
+      postcss-reduce-initial: 5.0.3_postcss@8.4.6
+      postcss-reduce-transforms: 5.0.4_postcss@8.4.6
+      postcss-svgo: 5.0.4_postcss@8.4.6
+      postcss-unique-selectors: 5.0.4_postcss@8.4.6
+    dev: true
+
+  /cssnano-util-get-arguments/4.0.0:
+    resolution: {integrity: 
sha512-6RIcwmV3/cBMG8Aj5gucQRsJb4vv4I4rn6YjPbVWd5+Pn/fuG+YseGvXGk00XLkoZkaj31QOD7vMUpNPC4FIuw==}
+    engines: {node: '>=6.9.0'}
+    dev: true
+
+  /cssnano-util-get-match/4.0.0:
+    resolution: {integrity: 
sha512-JPMZ1TSMRUPVIqEalIBNoBtAYbi8okvcFns4O0YIhcdGebeYZK7dMyHJiQ6GqNBA9kE0Hym4Aqym5rPdsV/4Cw==}
+    engines: {node: '>=6.9.0'}
+    dev: true
+
+  /cssnano-util-raw-cache/4.0.1:
+    resolution: {integrity: 
sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      postcss: 7.0.39
+    dev: true
+
+  /cssnano-util-same-parent/4.0.1:
+    resolution: {integrity: 
sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==}
+    engines: {node: '>=6.9.0'}
+    dev: true
+
+  /cssnano-utils/3.0.2_postcss@8.4.6:
+    resolution: {integrity: 
sha512-KhprijuQv2sP4kT92sSQwhlK3SJTbDIsxcfIEySB0O+3m9esFOai7dP9bMx5enHAh2MwarVIcnwiWoOm01RIbQ==}
+    engines: {node: ^10 || ^12 || >=14.0}
+    peerDependencies:
+      postcss: ^8.2.15
+    dependencies:
+      postcss: 8.4.6
+    dev: true
+
+  /cssnano/4.1.11:
+    resolution: {integrity: 
sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==}
+    engines: {node: '>=6.9.0'}
+    dependencies:
+      cosmiconfig: 5.2.1
+      cssnano-preset-default: 4.0.8
+      is-resolvable: 1.1.0
+      postcss: 7.0.39
+    dev: true
+
+  /cssnano/5.0.17_postcss@8.4.6:
+    resolution: {integrity: 
sha512-fmjLP7k8kL18xSspeXTzRhaFtRI7DL9b8IcXR80JgtnWBpvAzHT7sCR/6qdn0tnxIaINUN6OEQu83wF57Gs3Xw==}
+    engines: {node: ^10 || ^12 || >=14.0}
+    peerDependencies:
+      postcss: ^8.2.15
+    dependencies:
+      cssnano-preset-default: 5.1.12_postcss@8.4.6
+      lilconfig: 2.0.4
+      postcss: 8.4.6
+      yaml: 1.10.2
+    dev: true
+
+  /csso/4.2.0:
+    resolution: {integrity: 
sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==}
+    engines: {node: '>=8.0.0'}
+    dependencies:
+      css-tree: 1.1.3
+    dev: true
+
+  /cssom/0.3.8:
+    resolution: {integrity: 
sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==}
+    dev: true
+
+  /cssom/0.4.4:
+    resolution: {integrity: 
sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==}
+    dev: true
+
+  /cssstyle/1.4.0:
+    resolution: {integrity: 
sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==}
+    dependencies:
+      cssom: 0.3.8
+    dev: true
+
+  /cssstyle/2.3.0:
+    resolution: {integrity: 
sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==}
+    engines: {node: '>=8'}
+    dependencies:
+      cssom: 0.3.8
+    dev: true
+
+  /csstype/2.6.21:
+    resolution: {integrity: 
sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==}
+    dev: true
+
+  /csstype/3.1.1:
+    resolution: {integrity: 
sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==}
+    dev: true
+
+  /currently-unhandled/0.4.1:
+    resolution: {integrity: 
sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      array-find-index: 1.0.2
+    dev: true
+
+  /cyclist/1.0.1:
+    resolution: {integrity: 
sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A==}
+    dev: true
+
+  /damerau-levenshtein/1.0.7:
+    resolution: {integrity: 
sha512-VvdQIPGdWP0SqFXghj79Wf/5LArmreyMsGLa6FG6iC4t3j7j5s71TrwWmT/4akbDQIqjfACkLZmjXhA7g2oUZw==}
+    dev: true
+
+  /dashdash/1.14.1:
+    resolution: {integrity: 
sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==}
+    engines: {node: '>=0.10'}
+    dependencies:
+      assert-plus: 1.0.0
+    dev: true
+
+  /data-uri-to-buffer/4.0.0:
+    resolution: {integrity: 
sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==}
+    engines: {node: '>= 12'}
+    dev: false
+
+  /data-urls/1.1.0:
+    resolution: {integrity: 
sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==}
+    dependencies:
+      abab: 2.0.5
+      whatwg-mimetype: 2.3.0
+      whatwg-url: 7.1.0
+    dev: true
+
+  /data-urls/2.0.0:
+    resolution: {integrity: 
sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==}
+    engines: {node: '>=10'}
+    dependencies:
+      abab: 2.0.5
+      whatwg-mimetype: 2.3.0
+      whatwg-url: 8.7.0
+    dev: true
+
+  /date-fns/2.25.0:
+    resolution: {integrity: 
sha512-ovYRFnTrbGPD4nqaEqescPEv1mNwvt+UTqI3Ay9SzNtey9NZnYu6E2qCcBBgJ6/2VF1zGGygpyTDITqpQQ5e+w==}
+    engines: {node: '>=0.11'}
+    dev: false
+
+  /date-fns/2.29.2:
+    resolution: {integrity: 
sha512-0VNbwmWJDS/G3ySwFSJA3ayhbURMTJLtwM2DTxf9CWondCnh6DTNlO9JgRSq6ibf4eD0lfMJNBxUdEAHHix+bA==}
+    engines: {node: '>=0.11'}
+    dev: false
+
+  /date-time/3.1.0:
+    resolution: {integrity: 
sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==}
+    engines: {node: '>=6'}
+    dependencies:
+      time-zone: 1.0.0
+    dev: true
+
+  /debug/2.6.9:
+    resolution: {integrity: 
sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
+    peerDependencies:
+      supports-color: '*'
+    peerDependenciesMeta:
+      supports-color:
+        optional: true
+    dependencies:
+      ms: 2.0.0
+    dev: true
+
+  /debug/2.6.9_supports-color@6.1.0:
+    resolution: {integrity: 
sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
+    peerDependencies:
+      supports-color: '*'
+    peerDependenciesMeta:
+      supports-color:
+        optional: true
+    dependencies:
+      ms: 2.0.0
+      supports-color: 6.1.0
+    dev: true
+
+  /debug/3.2.7:
+    resolution: {integrity: 
sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
+    peerDependencies:
+      supports-color: '*'
+    peerDependenciesMeta:
+      supports-color:
+        optional: true
+    dependencies:
+      ms: 2.1.3
+    dev: true
+
+  /debug/3.2.7_supports-color@6.1.0:
+    resolution: {integrity: 
sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
+    peerDependencies:
+      supports-color: '*'
+    peerDependenciesMeta:
+      supports-color:
+        optional: true
+    dependencies:
+      ms: 2.1.3
+      supports-color: 6.1.0
+    dev: true
+
+  /debug/4.3.3:
+    resolution: {integrity: 
sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==}
+    engines: {node: '>=6.0'}
+    peerDependencies:
+      supports-color: '*'
+    peerDependenciesMeta:
+      supports-color:
+        optional: true
+    dependencies:
+      ms: 2.1.2
+    dev: true
+
+  /debug/4.3.3_supports-color@8.1.1:
+    resolution: {integrity: 
sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==}
+    engines: {node: '>=6.0'}
+    peerDependencies:
+      supports-color: '*'
+    peerDependenciesMeta:
+      supports-color:
+        optional: true
+    dependencies:
+      ms: 2.1.2
+      supports-color: 8.1.1
+    dev: true
+
+  /debug/4.3.4:
+    resolution: {integrity: 
sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
+    engines: {node: '>=6.0'}
+    peerDependencies:
+      supports-color: '*'
+    peerDependenciesMeta:
+      supports-color:
+        optional: true
+    dependencies:
+      ms: 2.1.2
+    dev: true
+
+  /debug/4.3.4_supports-color@6.1.0:
+    resolution: {integrity: 
sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
+    engines: {node: '>=6.0'}
+    peerDependencies:
+      supports-color: '*'
+    peerDependenciesMeta:
+      supports-color:
+        optional: true
+    dependencies:
+      ms: 2.1.2
+      supports-color: 6.1.0
+    dev: true
+
+  /decamelize/1.2.0:
+    resolution: {integrity: sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /decamelize/4.0.0:
+    resolution: {integrity: 
sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==}
+    engines: {node: '>=10'}
+    dev: true
+
+  /decimal.js/10.4.2:
+    resolution: {integrity: 
sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA==}
+    dev: true
+
+  /decode-uri-component/0.2.0:
+    resolution: {integrity: 
sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==}
+    engines: {node: '>=0.10'}
+    dev: true
+
+  /decompress-response/3.3.0:
+    resolution: {integrity: 
sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==}
+    engines: {node: '>=4'}
+    dependencies:
+      mimic-response: 1.0.1
+    dev: true
+
+  /dedent/0.7.0:
+    resolution: {integrity: 
sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==}
+    dev: true
+
+  /deep-eql/3.0.1:
+    resolution: {integrity: 
sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==}
+    engines: {node: '>=0.12'}
+    dependencies:
+      type-detect: 4.0.8
+
+  /deep-equal/1.1.1:
+    resolution: {integrity: 
sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==}
+    dependencies:
+      is-arguments: 1.1.1
+      is-date-object: 1.0.5
+      is-regex: 1.1.4
+      object-is: 1.1.5
+      object-keys: 1.1.1
+      regexp.prototype.flags: 1.4.3
+    dev: true
+
+  /deep-equal/2.0.5:
+    resolution: {integrity: 
sha512-nPiRgmbAtm1a3JsnLCf6/SLfXcjyN5v8L1TXzdCmHrXJ4hx+gW/w1YCcn7z8gJtSiDArZCgYtbao3QqLm/N1Sw==}
+    dependencies:
+      call-bind: 1.0.2
+      es-get-iterator: 1.1.2
+      get-intrinsic: 1.1.1
+      is-arguments: 1.1.1
+      is-date-object: 1.0.5
+      is-regex: 1.1.4
+      isarray: 2.0.5
+      object-is: 1.1.5
+      object-keys: 1.1.1
+      object.assign: 4.1.2
+      regexp.prototype.flags: 1.4.1
+      side-channel: 1.0.4
+      which-boxed-primitive: 1.0.2
+      which-collection: 1.0.1
+      which-typed-array: 1.1.8
     dev: true
 
-  /arrgv/1.0.2:
-    resolution: {integrity: 
sha512-a4eg4yhp7mmruZDQFqVMlxNRFGi/i1r87pt8SDHy0/I8PqSXoUTlWZRdAZo0VXgvEARcujbtTk8kiZRi1uDGRw==}
-    engines: {node: '>=8.0.0'}
+  /deep-extend/0.6.0:
+    resolution: {integrity: 
sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==}
+    engines: {node: '>=4.0.0'}
+    dev: true
+
+  /deep-is/0.1.4:
+    resolution: {integrity: 
sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
+    dev: true
+
+  /deep-object-diff/1.1.7:
+    resolution: {integrity: 
sha512-QkgBca0mL08P6HiOjoqvmm6xOAl2W6CT2+34Ljhg0OeFan8cwlcdq8jrLKsBBuUFAZLsN5b6y491KdKEoSo9lg==}
+    dev: true
+
+  /deepcopy/1.0.0:
+    resolution: {integrity: 
sha512-WJrecobaoqqgQHtvRI2/VCzWoWXPAnFYyAkF/spmL46lZMnd0gW0gLGuyeFVSrqt2B3s0oEEj6i+j2L/2QiS4g==}
+    dependencies:
+      type-detect: 4.0.8
+    dev: true
+
+  /deepmerge/4.2.2:
+    resolution: {integrity: 
sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /default-browser-id/1.0.4:
+    resolution: {integrity: 
sha512-qPy925qewwul9Hifs+3sx1ZYn14obHxpkX+mPD369w4Rzg+YkJBgi3SOvwUq81nWSjqGUegIgEPwD8u+HUnxlw==}
+    engines: {node: '>=0.10.0'}
+    hasBin: true
+    requiresBuild: true
+    dependencies:
+      bplist-parser: 0.1.1
+      meow: 3.7.0
+      untildify: 2.1.0
+    dev: true
+    optional: true
+
+  /default-gateway/4.2.0:
+    resolution: {integrity: 
sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==}
+    engines: {node: '>=6'}
+    dependencies:
+      execa: 1.0.0
+      ip-regex: 2.1.0
     dev: true
 
-  /arrify/3.0.0:
-    resolution: {integrity: 
sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==}
-    engines: {node: '>=12'}
+  /default-gateway/6.0.3:
+    resolution: {integrity: 
sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==}
+    engines: {node: '>= 10'}
+    dependencies:
+      execa: 5.1.1
     dev: true
 
-  /asn1.js/5.4.1:
-    resolution: {integrity: 
sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==}
+  /default-require-extensions/3.0.0:
+    resolution: {integrity: 
sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==}
+    engines: {node: '>=8'}
     dependencies:
-      bn.js: 4.12.0
-      inherits: 2.0.4
-      minimalistic-assert: 1.0.1
-      safer-buffer: 2.1.2
+      strip-bom: 4.0.0
     dev: true
 
-  /asn1/0.2.6:
-    resolution: {integrity: 
sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==}
+  /defaults/1.0.3:
+    resolution: {integrity: 
sha512-s82itHOnYrN0Ib8r+z7laQz3sdE+4FP3d9Q7VLO7U+KRT+CR0GsWuyHxzdAY82I7cXv0G/twrqomTJLOssO5HA==}
     dependencies:
-      safer-buffer: 2.1.2
+      clone: 1.0.4
     dev: true
 
-  /assert-plus/1.0.0:
-    resolution: {integrity: sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=}
-    engines: {node: '>=0.8'}
+  /defer-to-connect/1.1.3:
+    resolution: {integrity: 
sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==}
     dev: true
 
-  /assert/1.5.0:
-    resolution: {integrity: 
sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==}
+  /define-lazy-prop/2.0.0:
+    resolution: {integrity: 
sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==}
+    engines: {node: '>=8'}
+    dev: true
+
+  /define-properties/1.1.3:
+    resolution: {integrity: 
sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==}
+    engines: {node: '>= 0.4'}
     dependencies:
-      object-assign: 4.1.1
-      util: 0.10.3
+      object-keys: 1.1.1
     dev: true
 
-  /assertion-error/1.1.0:
-    resolution: {integrity: 
sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==}
+  /define-properties/1.1.4:
+    resolution: {integrity: 
sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      has-property-descriptors: 1.0.0
+      object-keys: 1.1.1
+    dev: true
 
-  /assign-symbols/1.0.0:
-    resolution: {integrity: sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=}
+  /define-property/0.2.5:
+    resolution: {integrity: 
sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==}
     engines: {node: '>=0.10.0'}
+    dependencies:
+      is-descriptor: 0.1.6
     dev: true
 
-  /ast-types-flow/0.0.7:
-    resolution: {integrity: sha1-9wtzXGvKGlycItmCw+Oef+ujva0=}
+  /define-property/1.0.0:
+    resolution: {integrity: 
sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      is-descriptor: 1.0.2
     dev: true
 
-  /async-each/1.0.3:
-    resolution: {integrity: 
sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==}
+  /define-property/2.0.2:
+    resolution: {integrity: 
sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      is-descriptor: 1.0.2
+      isobject: 3.0.1
     dev: true
-    optional: true
 
-  /async-limiter/1.0.1:
-    resolution: {integrity: 
sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==}
+  /del/4.1.1:
+    resolution: {integrity: 
sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==}
+    engines: {node: '>=6'}
+    dependencies:
+      '@types/glob': 7.2.0
+      globby: 6.1.0
+      is-path-cwd: 2.2.0
+      is-path-in-cwd: 2.1.0
+      p-map: 2.1.0
+      pify: 4.0.1
+      rimraf: 2.7.1
     dev: true
 
-  /async/0.9.2:
-    resolution: {integrity: sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=}
+  /del/6.0.0:
+    resolution: {integrity: 
sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ==}
+    engines: {node: '>=10'}
+    dependencies:
+      globby: 11.1.0
+      graceful-fs: 4.2.10
+      is-glob: 4.0.3
+      is-path-cwd: 2.2.0
+      is-path-inside: 3.0.3
+      p-map: 4.0.0
+      rimraf: 3.0.2
+      slash: 3.0.0
     dev: true
 
-  /async/2.6.3:
-    resolution: {integrity: 
sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==}
+  /del/6.1.1:
+    resolution: {integrity: 
sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==}
+    engines: {node: '>=10'}
     dependencies:
-      lodash: 4.17.21
+      globby: 11.1.0
+      graceful-fs: 4.2.10
+      is-glob: 4.0.3
+      is-path-cwd: 2.2.0
+      is-path-inside: 3.0.3
+      p-map: 4.0.0
+      rimraf: 3.0.2
+      slash: 3.0.0
     dev: true
 
-  /asynckit/0.4.0:
-    resolution: {integrity: 
sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
+  /delayed-stream/1.0.0:
+    resolution: {integrity: 
sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
+    engines: {node: '>=0.4.0'}
 
-  /at-least-node/1.0.0:
-    resolution: {integrity: 
sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==}
-    engines: {node: '>= 4.0.0'}
+  /delegates/1.0.0:
+    resolution: {integrity: 
sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==}
     dev: true
 
-  /atob/2.1.2:
-    resolution: {integrity: 
sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==}
-    engines: {node: '>= 4.5.0'}
-    hasBin: true
+  /depd/1.1.2:
+    resolution: {integrity: 
sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==}
+    engines: {node: '>= 0.6'}
     dev: true
 
-  /autoprefixer/10.4.2_postcss@8.4.6:
-    resolution: {integrity: 
sha512-9fOPpHKuDW1w/0EKfRmVnxTDt8166MAnLI3mgZ1JCnhNtYWxcJ6Ud5CO/AVOZi/AvFa8DY9RTy3h3+tFBlrrdQ==}
-    engines: {node: ^10 || ^12 || >=14}
-    hasBin: true
-    peerDependencies:
-      postcss: ^8.1.0
+  /dequal/2.0.2:
+    resolution: {integrity: 
sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug==}
+    engines: {node: '>=6'}
+    dev: false
+
+  /des.js/1.0.1:
+    resolution: {integrity: 
sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==}
     dependencies:
-      browserslist: 4.19.1
-      caniuse-lite: 1.0.30001311
-      fraction.js: 4.1.3
-      normalize-range: 0.1.2
-      picocolors: 1.0.0
-      postcss: 8.4.6
-      postcss-value-parser: 4.2.0
+      inherits: 2.0.4
+      minimalistic-assert: 1.0.1
     dev: true
 
-  /ava/4.3.3:
-    resolution: {integrity: 
sha512-9Egq/d9R74ExrWohHeqUlexjDbgZJX5jA1Wq4KCTqc3wIfpGEK79zVy4rBtofJ9YKIxs4PzhJ8BgbW5PlAYe6w==}
-    engines: {node: '>=12.22 <13 || >=14.17 <15 || >=16.4 <17 || >=18'}
-    hasBin: true
-    peerDependencies:
-      '@ava/typescript': '*'
-    peerDependenciesMeta:
-      '@ava/typescript':
-        optional: true
-    dependencies:
-      acorn: 8.8.0
-      acorn-walk: 8.2.0
-      ansi-styles: 6.2.1
-      arrgv: 1.0.2
-      arrify: 3.0.0
-      callsites: 4.0.0
-      cbor: 8.1.0
-      chalk: 5.1.2
-      chokidar: 3.5.3
-      chunkd: 2.0.1
-      ci-info: 3.5.0
-      ci-parallel-vars: 1.0.1
-      clean-yaml-object: 0.1.0
-      cli-truncate: 3.1.0
-      code-excerpt: 4.0.0
-      common-path-prefix: 3.0.0
-      concordance: 5.0.4
-      currently-unhandled: 0.4.1
-      debug: 4.3.4
-      del: 6.1.1
-      emittery: 0.11.0
-      figures: 4.0.1
-      globby: 13.1.2
-      ignore-by-default: 2.1.0
-      indent-string: 5.0.0
-      is-error: 2.2.2
-      is-plain-object: 5.0.0
-      is-promise: 4.0.0
-      matcher: 5.0.0
-      mem: 9.0.2
-      ms: 2.1.3
-      p-event: 5.0.1
-      p-map: 5.5.0
-      picomatch: 2.3.1
-      pkg-conf: 4.0.0
-      plur: 5.1.0
-      pretty-ms: 7.0.1
-      resolve-cwd: 3.0.0
-      slash: 3.0.0
-      stack-utils: 2.0.5
-      strip-ansi: 7.0.1
-      supertap: 3.0.1
-      temp-dir: 2.0.0
-      write-file-atomic: 4.0.2
-      yargs: 17.6.0
-    transitivePeerDependencies:
-      - supports-color
+  /destroy/1.0.4:
+    resolution: {integrity: 
sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==}
     dev: true
 
-  /ava/4.3.3_@ava+typescript@3.0.1:
-    resolution: {integrity: 
sha512-9Egq/d9R74ExrWohHeqUlexjDbgZJX5jA1Wq4KCTqc3wIfpGEK79zVy4rBtofJ9YKIxs4PzhJ8BgbW5PlAYe6w==}
-    engines: {node: '>=12.22 <13 || >=14.17 <15 || >=16.4 <17 || >=18'}
-    hasBin: true
-    peerDependencies:
-      '@ava/typescript': '*'
-    peerDependenciesMeta:
-      '@ava/typescript':
-        optional: true
+  /detab/2.0.4:
+    resolution: {integrity: 
sha512-8zdsQA5bIkoRECvCrNKPla84lyoR7DSAyf7p0YgXzBO9PDJx8KntPUay7NS6yp+KdxdVtiE5SpHKtbp2ZQyA9g==}
     dependencies:
-      '@ava/typescript': 3.0.1
-      acorn: 8.8.0
-      acorn-walk: 8.2.0
-      ansi-styles: 6.2.1
-      arrgv: 1.0.2
-      arrify: 3.0.0
-      callsites: 4.0.0
-      cbor: 8.1.0
-      chalk: 5.1.2
-      chokidar: 3.5.3
-      chunkd: 2.0.1
-      ci-info: 3.5.0
-      ci-parallel-vars: 1.0.1
-      clean-yaml-object: 0.1.0
-      cli-truncate: 3.1.0
-      code-excerpt: 4.0.0
-      common-path-prefix: 3.0.0
-      concordance: 5.0.4
-      currently-unhandled: 0.4.1
-      debug: 4.3.4
-      del: 6.1.1
-      emittery: 0.11.0
-      figures: 4.0.1
-      globby: 13.1.2
-      ignore-by-default: 2.1.0
-      indent-string: 5.0.0
-      is-error: 2.2.2
-      is-plain-object: 5.0.0
-      is-promise: 4.0.0
-      matcher: 5.0.0
-      mem: 9.0.2
-      ms: 2.1.3
-      p-event: 5.0.1
-      p-map: 5.5.0
-      picomatch: 2.3.1
-      pkg-conf: 4.0.0
-      plur: 5.1.0
-      pretty-ms: 7.0.1
-      resolve-cwd: 3.0.0
-      slash: 3.0.0
-      stack-utils: 2.0.5
-      strip-ansi: 7.0.1
-      supertap: 3.0.1
-      temp-dir: 2.0.0
-      write-file-atomic: 4.0.2
-      yargs: 17.6.0
+      repeat-string: 1.6.1
+    dev: true
+
+  /detect-newline/3.1.0:
+    resolution: {integrity: 
sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==}
+    engines: {node: '>=8'}
+    dev: true
+
+  /detect-node/2.1.0:
+    resolution: {integrity: 
sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==}
+    dev: true
+
+  /detect-package-manager/2.0.1:
+    resolution: {integrity: 
sha512-j/lJHyoLlWi6G1LDdLgvUtz60Zo5GEj+sVYtTVXnYLDPuzgC3llMxonXym9zIwhhUII8vjdw0LXxavpLqTbl1A==}
+    engines: {node: '>=12'}
+    dependencies:
+      execa: 5.1.1
+    dev: true
+
+  /detect-port-alt/1.1.6:
+    resolution: {integrity: 
sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==}
+    engines: {node: '>= 4.2.1'}
+    hasBin: true
+    dependencies:
+      address: 1.1.2
+      debug: 2.6.9
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /aws-sign2/0.7.0:
-    resolution: {integrity: sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=}
+  /detect-port/1.5.1:
+    resolution: {integrity: 
sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==}
+    hasBin: true
+    dependencies:
+      address: 1.2.1
+      debug: 4.3.4
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /aws4/1.11.0:
-    resolution: {integrity: 
sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==}
+  /diff-sequences/26.6.2:
+    resolution: {integrity: 
sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==}
+    engines: {node: '>= 10.14.2'}
     dev: true
 
-  /axe-core/4.3.5:
-    resolution: {integrity: 
sha512-WKTW1+xAzhMS5dJsxWkliixlO/PqC4VhmO9T4juNYcaTg9jzWiJsou6m5pxWYGfigWbwzJWeFY6z47a+4neRXA==}
+  /diff-sequences/27.5.1:
+    resolution: {integrity: 
sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    dev: true
+
+  /diff/5.0.0:
+    resolution: {integrity: 
sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==}
+    engines: {node: '>=0.3.1'}
+    dev: true
+
+  /diffie-hellman/5.0.3:
+    resolution: {integrity: 
sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==}
+    dependencies:
+      bn.js: 4.12.0
+      miller-rabin: 4.0.1
+      randombytes: 2.1.0
+    dev: true
+
+  /dir-glob/2.2.2:
+    resolution: {integrity: 
sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==}
     engines: {node: '>=4'}
+    dependencies:
+      path-type: 3.0.0
     dev: true
 
-  /axios/0.21.4:
-    resolution: {integrity: 
sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==}
+  /dir-glob/3.0.1:
+    resolution: {integrity: 
sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
+    engines: {node: '>=8'}
     dependencies:
-      follow-redirects: 1.14.8
-    transitivePeerDependencies:
-      - debug
+      path-type: 4.0.0
     dev: true
 
-  /axios/0.27.2:
-    resolution: {integrity: 
sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==}
+  /discontinuous-range/1.0.0:
+    resolution: {integrity: sha1-44Mx8IRLukm5qctxx3FYWqsbxlo=}
+    dev: true
+
+  /dns-equal/1.0.0:
+    resolution: {integrity: 
sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==}
+    dev: true
+
+  /dns-packet/1.3.4:
+    resolution: {integrity: 
sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==}
     dependencies:
-      follow-redirects: 1.15.2
-      form-data: 4.0.0
-    transitivePeerDependencies:
-      - debug
-    dev: false
+      ip: 1.1.5
+      safe-buffer: 5.2.1
+    dev: true
 
-  /axobject-query/2.2.0:
-    resolution: {integrity: 
sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==}
+  /dns-txt/2.0.2:
+    resolution: {integrity: 
sha512-Ix5PrWjphuSoUXV/Zv5gaFHjnaJtb02F2+Si3Ht9dyJ87+Z/lMmy+dpNHtTGraNK958ndXq2i+GLkWsWHcKaBQ==}
+    dependencies:
+      buffer-indexof: 1.1.1
     dev: true
 
-  /babel-esm-plugin/0.9.0_webpack@4.46.0:
-    resolution: {integrity: 
sha512-OyPyLI6LUuUqNm3HNUldAkynWrLzXkhcZo4fGTsieCgHqvbCoCIMMOwJmfG9Lmp91S7WDIuUr0mvOeI8pAb/pw==}
-    peerDependencies:
-      webpack: ^4.28.4
+  /doctrine/2.1.0:
+    resolution: {integrity: 
sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==}
+    engines: {node: '>=0.10.0'}
     dependencies:
-      chalk: 2.4.1
-      deepcopy: 1.0.0
-      webpack: 4.46.0
+      esutils: 2.0.3
     dev: true
 
-  /babel-helper-builder-react-jsx/6.26.0:
-    resolution: {integrity: sha1-Of+DE7dci2Xc7/HzHTg+D/KkCKA=}
+  /doctrine/3.0.0:
+    resolution: {integrity: 
sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
+    engines: {node: '>=6.0.0'}
     dependencies:
-      babel-runtime: 6.26.0
-      babel-types: 6.26.0
       esutils: 2.0.3
     dev: true
 
-  /babel-loader/8.2.3_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-n4Zeta8NC3QAsuyiizu0GkmRcQ6clkV9WFUnUf1iXP//IeSKbWjofW3UHyZVwlOB4y039YQKefawyTn64Zwbuw==}
-    engines: {node: '>= 8.9'}
-    peerDependencies:
-      '@babel/core': ^7.0.0
-      webpack: '>=2'
+  /dom-accessibility-api/0.5.7:
+    resolution: {integrity: 
sha512-ml3lJIq9YjUfM9TUnEPvEYWFSwivwIGBPKpewX7tii7fwCazA8yCioGdqQcNsItPpfFvSJ3VIdMQPj60LJhcQA==}
+    dev: true
+
+  /dom-converter/0.2.0:
+    resolution: {integrity: 
sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==}
     dependencies:
-      '@babel/core': 7.13.16
-      find-cache-dir: 3.3.2
-      loader-utils: 1.4.0
-      make-dir: 3.1.0
-      schema-utils: 2.7.1
+      utila: 0.4.0
     dev: true
 
-  /babel-loader/8.2.3_mc362qep5qjjhwk7q3m45kuizi:
-    resolution: {integrity: 
sha512-n4Zeta8NC3QAsuyiizu0GkmRcQ6clkV9WFUnUf1iXP//IeSKbWjofW3UHyZVwlOB4y039YQKefawyTn64Zwbuw==}
-    engines: {node: '>= 8.9'}
-    peerDependencies:
-      '@babel/core': ^7.0.0
-      webpack: '>=2'
+  /dom-serializer/0.2.2:
+    resolution: {integrity: 
sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==}
     dependencies:
-      '@babel/core': 7.17.2
-      find-cache-dir: 3.3.2
-      loader-utils: 1.4.0
-      make-dir: 3.1.0
-      schema-utils: 2.7.1
-      webpack: 4.46.0
+      domelementtype: 2.3.0
+      entities: 2.2.0
     dev: true
 
-  /babel-plugin-dynamic-import-node/2.3.3:
-    resolution: {integrity: 
sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==}
+  /dom-serializer/1.3.2:
+    resolution: {integrity: 
sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==}
     dependencies:
-      object.assign: 4.1.2
+      domelementtype: 2.3.0
+      domhandler: 4.3.0
+      entities: 2.2.0
     dev: true
 
-  /babel-plugin-macros/3.1.0:
-    resolution: {integrity: 
sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==}
-    engines: {node: '>=10', npm: '>=6'}
+  /dom-serializer/2.0.0:
+    resolution: {integrity: 
sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
     dependencies:
-      '@babel/runtime': 7.17.2
-      cosmiconfig: 7.0.1
-      resolve: 1.22.0
+      domelementtype: 2.3.0
+      domhandler: 5.0.3
+      entities: 4.4.0
     dev: true
 
-  /babel-plugin-polyfill-corejs2/0.3.1_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
+  /dom-walk/0.1.2:
+    resolution: {integrity: 
sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==}
+    dev: true
+
+  /domain-browser/1.2.0:
+    resolution: {integrity: 
sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==}
+    engines: {node: '>=0.4', npm: '>=1.2'}
+    dev: true
+
+  /domelementtype/1.3.1:
+    resolution: {integrity: 
sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==}
+    dev: true
+
+  /domelementtype/2.3.0:
+    resolution: {integrity: 
sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
+    dev: true
+
+  /domexception/1.0.1:
+    resolution: {integrity: 
sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==}
     dependencies:
-      '@babel/compat-data': 7.17.0
-      '@babel/core': 7.13.16
-      '@babel/helper-define-polyfill-provider': 0.3.1_@babel+core@7.13.16
-      semver: 6.3.0
-    transitivePeerDependencies:
-      - supports-color
+      webidl-conversions: 4.0.2
     dev: true
 
-  /babel-plugin-polyfill-corejs2/0.3.1_@babel+core@7.17.2:
-    resolution: {integrity: 
sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
+  /domexception/2.0.1:
+    resolution: {integrity: 
sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==}
+    engines: {node: '>=8'}
     dependencies:
-      '@babel/compat-data': 7.17.0
-      '@babel/core': 7.17.2
-      '@babel/helper-define-polyfill-provider': 0.3.1_@babel+core@7.17.2
-      semver: 6.3.0
-    transitivePeerDependencies:
-      - supports-color
+      webidl-conversions: 5.0.0
     dev: true
 
-  /babel-plugin-polyfill-corejs3/0.5.2_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
+  /domhandler/4.3.0:
+    resolution: {integrity: 
sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==}
+    engines: {node: '>= 4'}
     dependencies:
-      '@babel/core': 7.13.16
-      '@babel/helper-define-polyfill-provider': 0.3.1_@babel+core@7.13.16
-      core-js-compat: 3.21.0
-    transitivePeerDependencies:
-      - supports-color
+      domelementtype: 2.3.0
     dev: true
 
-  /babel-plugin-polyfill-corejs3/0.5.2_@babel+core@7.17.2:
-    resolution: {integrity: 
sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
+  /domhandler/5.0.3:
+    resolution: {integrity: 
sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
+    engines: {node: '>= 4'}
     dependencies:
-      '@babel/core': 7.17.2
-      '@babel/helper-define-polyfill-provider': 0.3.1_@babel+core@7.17.2
-      core-js-compat: 3.21.0
-    transitivePeerDependencies:
-      - supports-color
+      domelementtype: 2.3.0
     dev: true
 
-  /babel-plugin-polyfill-regenerator/0.3.1_@babel+core@7.13.16:
-    resolution: {integrity: 
sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
+  /domutils/1.7.0:
+    resolution: {integrity: 
sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==}
     dependencies:
-      '@babel/core': 7.13.16
-      '@babel/helper-define-polyfill-provider': 0.3.1_@babel+core@7.13.16
-    transitivePeerDependencies:
-      - supports-color
+      dom-serializer: 0.2.2
+      domelementtype: 1.3.1
     dev: true
 
-  /babel-plugin-polyfill-regenerator/0.3.1_@babel+core@7.17.2:
-    resolution: {integrity: 
sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A==}
+  /domutils/2.8.0:
+    resolution: {integrity: 
sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==}
+    dependencies:
+      dom-serializer: 1.3.2
+      domelementtype: 2.3.0
+      domhandler: 4.3.0
+    dev: true
+
+  /domutils/3.0.1:
+    resolution: {integrity: 
sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==}
+    dependencies:
+      dom-serializer: 2.0.0
+      domelementtype: 2.3.0
+      domhandler: 5.0.3
+    dev: true
+
+  /dot-case/3.0.4:
+    resolution: {integrity: 
sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==}
+    dependencies:
+      no-case: 3.0.4
+      tslib: 2.4.0
+    dev: true
+
+  /dot-prop/5.3.0:
+    resolution: {integrity: 
sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==}
+    engines: {node: '>=8'}
+    dependencies:
+      is-obj: 2.0.0
+    dev: true
+
+  /dotenv-defaults/1.1.1:
+    resolution: {integrity: 
sha512-6fPRo9o/3MxKvmRZBD3oNFdxODdhJtIy1zcJeUSCs6HCy4tarUpd+G67UTU9tF6OWXeSPqsm4fPAB+2eY9Rt9Q==}
+    dependencies:
+      dotenv: 6.2.0
+    dev: true
+
+  /dotenv-expand/5.1.0:
+    resolution: {integrity: 
sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==}
+    dev: true
+
+  /dotenv-webpack/1.8.0_webpack@4.46.0:
+    resolution: {integrity: 
sha512-o8pq6NLBehtrqA8Jv8jFQNtG9nhRtVqmoD4yWbgUyoU3+9WBlPe+c2EAiaJok9RB28QvrWvdWLZGeTT5aATDMg==}
     peerDependencies:
-      '@babel/core': ^7.0.0-0
+      webpack: ^1 || ^2 || ^3 || ^4
     dependencies:
-      '@babel/core': 7.17.2
-      '@babel/helper-define-polyfill-provider': 0.3.1_@babel+core@7.17.2
-    transitivePeerDependencies:
-      - supports-color
+      dotenv-defaults: 1.1.1
+      webpack: 4.46.0
     dev: true
 
-  /babel-plugin-syntax-jsx/6.18.0:
-    resolution: {integrity: sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=}
+  /dotenv/6.2.0:
+    resolution: {integrity: 
sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==}
+    engines: {node: '>=6'}
     dev: true
 
-  /babel-plugin-transform-react-jsx/6.24.1:
-    resolution: {integrity: sha1-hAoCjn30YN/DotKfDA2R9jduZqM=}
+  /dotenv/8.6.0:
+    resolution: {integrity: 
sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==}
+    engines: {node: '>=10'}
+    dev: true
+
+  /downshift/6.1.12:
+    resolution: {integrity: 
sha512-7XB/iaSJVS4T8wGFT3WRXmSF1UlBHAA40DshZtkrIscIN+VC+Lh363skLxFTvJwtNgHxAMDGEHT4xsyQFWL+UA==}
+    peerDependencies:
+      react: '>=16.12.0'
     dependencies:
-      babel-helper-builder-react-jsx: 6.26.0
-      babel-plugin-syntax-jsx: 6.18.0
-      babel-runtime: 6.26.0
+      '@babel/runtime': 7.17.8
+      compute-scroll-into-view: 1.0.17
+      prop-types: 15.8.1
+      react-is: 17.0.2
+      tslib: 2.4.0
+    dev: true
+
+  /downshift/6.1.12_react@16.14.0:
+    resolution: {integrity: 
sha512-7XB/iaSJVS4T8wGFT3WRXmSF1UlBHAA40DshZtkrIscIN+VC+Lh363skLxFTvJwtNgHxAMDGEHT4xsyQFWL+UA==}
+    peerDependencies:
+      react: '>=16.12.0'
+    dependencies:
+      '@babel/runtime': 7.17.8
+      compute-scroll-into-view: 1.0.17
+      prop-types: 15.8.1
+      react: 16.14.0
+      react-is: 17.0.2
+      tslib: 2.4.0
     dev: true
 
-  /babel-plugin-transform-react-remove-prop-types/0.4.24:
-    resolution: {integrity: 
sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==}
+  /duplexer/0.1.2:
+    resolution: {integrity: 
sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==}
     dev: true
 
-  /babel-runtime/6.26.0:
-    resolution: {integrity: sha1-llxwWGaOgrVde/4E/yM3vItWR/4=}
-    dependencies:
-      core-js: 2.6.12
-      regenerator-runtime: 0.11.1
+  /duplexer3/0.1.4:
+    resolution: {integrity: 
sha512-CEj8FwwNA4cVH2uFCoHUrmojhYh1vmCdOaneKJXwkeY1i9jnlslVo9dx+hQ5Hl9GnH/Bwy/IjxAyOePyPKYnzA==}
     dev: true
 
-  /babel-types/6.26.0:
-    resolution: {integrity: sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=}
+  /duplexify/3.7.1:
+    resolution: {integrity: 
sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==}
     dependencies:
-      babel-runtime: 6.26.0
-      esutils: 2.0.3
-      lodash: 4.17.21
-      to-fast-properties: 1.0.3
+      end-of-stream: 1.4.4
+      inherits: 2.0.4
+      readable-stream: 2.3.7
+      stream-shift: 1.0.1
     dev: true
 
-  /balanced-match/1.0.2:
-    resolution: {integrity: 
sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
-
-  /base/0.11.2:
-    resolution: {integrity: 
sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==}
-    engines: {node: '>=0.10.0'}
-    dependencies:
-      cache-base: 1.0.1
-      class-utils: 0.3.6
-      component-emitter: 1.3.0
-      define-property: 1.0.0
-      isobject: 3.0.1
-      mixin-deep: 1.3.2
-      pascalcase: 0.1.1
+  /eastasianwidth/0.2.0:
+    resolution: {integrity: 
sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
     dev: true
 
-  /base64-js/1.5.1:
-    resolution: {integrity: 
sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
+  /ecc-jsbn/0.1.2:
+    resolution: {integrity: 
sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==}
+    dependencies:
+      jsbn: 0.1.1
+      safer-buffer: 2.1.2
     dev: true
 
-  /batch/0.6.1:
-    resolution: {integrity: sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=}
+  /ee-first/1.1.1:
+    resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=}
     dev: true
 
-  /bcrypt-pbkdf/1.0.2:
-    resolution: {integrity: sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=}
+  /ejs-loader/0.5.0:
+    resolution: {integrity: 
sha512-iirFqlP3tiFoedNZ7dQcjvechunl054VbW6Ki38T/pabgXMAncduSE0ZXLeVGn1NbmcUJF9Z5TC0EvQ4RIpP9Q==}
     dependencies:
-      tweetnacl: 0.14.5
+      loader-utils: 2.0.2
+      lodash: 4.17.21
     dev: true
 
-  /big-integer/1.6.51:
-    resolution: {integrity: 
sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==}
-    engines: {node: '>=0.6'}
-    dev: false
-
-  /big.js/3.2.0:
-    resolution: {integrity: 
sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==}
+  /ejs/2.7.4:
+    resolution: {integrity: 
sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==}
+    engines: {node: '>=0.10.0'}
+    requiresBuild: true
     dev: true
 
-  /big.js/5.2.2:
-    resolution: {integrity: 
sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==}
+  /ejs/3.1.6:
+    resolution: {integrity: 
sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==}
+    engines: {node: '>=0.10.0'}
+    hasBin: true
+    dependencies:
+      jake: 10.8.2
     dev: true
 
-  /binary-extensions/1.13.1:
-    resolution: {integrity: 
sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==}
-    engines: {node: '>=0.10.0'}
+  /electron-to-chromium/1.4.284:
+    resolution: {integrity: 
sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==}
     dev: true
-    optional: true
 
-  /binary-extensions/2.2.0:
-    resolution: {integrity: 
sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
-    engines: {node: '>=8'}
+  /electron-to-chromium/1.4.68:
+    resolution: {integrity: 
sha512-cId+QwWrV8R1UawO6b9BR1hnkJ4EJPCPAr4h315vliHUtVUJDk39Sg1PMNnaWKfj5x+93ssjeJ9LKL6r8LaMiA==}
     dev: true
 
-  /bindings/1.5.0:
-    resolution: {integrity: 
sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}
-    requiresBuild: true
+  /element-resize-detector/1.2.4:
+    resolution: {integrity: 
sha512-Fl5Ftk6WwXE0wqCgNoseKWndjzZlDCwuPTcoVZfCP9R3EHQF8qUtr3YUPNETegRBOKqQKPW3n4kiIWngGi8tKg==}
     dependencies:
-      file-uri-to-path: 1.0.0
+      batch-processor: 1.0.0
     dev: true
-    optional: true
 
-  /bl/4.1.0:
-    resolution: {integrity: 
sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
+  /elliptic/6.5.4:
+    resolution: {integrity: 
sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==}
     dependencies:
-      buffer: 5.7.1
+      bn.js: 4.12.0
+      brorand: 1.1.0
+      hash.js: 1.1.7
+      hmac-drbg: 1.0.1
       inherits: 2.0.4
-      readable-stream: 3.6.0
+      minimalistic-assert: 1.0.1
+      minimalistic-crypto-utils: 1.0.1
     dev: true
 
-  /bluebird/3.7.2:
-    resolution: {integrity: 
sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==}
+  /emittery/0.10.2:
+    resolution: {integrity: 
sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==}
+    engines: {node: '>=12'}
     dev: true
 
-  /blueimp-md5/2.19.0:
-    resolution: {integrity: 
sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==}
+  /emittery/0.11.0:
+    resolution: {integrity: 
sha512-S/7tzL6v5i+4iJd627Nhv9cLFIo5weAIlGccqJFpnBoDB8U1TF2k5tez4J/QNuxyyhWuFqHg1L84Kd3m7iXg6g==}
+    engines: {node: '>=12'}
     dev: true
 
-  /bn.js/4.12.0:
-    resolution: {integrity: 
sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==}
+  /emittery/0.7.2:
+    resolution: {integrity: 
sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==}
+    engines: {node: '>=10'}
     dev: true
 
-  /bn.js/5.2.0:
-    resolution: {integrity: 
sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==}
+  /emittery/0.8.1:
+    resolution: {integrity: 
sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==}
+    engines: {node: '>=10'}
     dev: true
 
-  /body-parser/1.19.1:
-    resolution: {integrity: 
sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==}
-    engines: {node: '>= 0.8'}
-    dependencies:
-      bytes: 3.1.1
-      content-type: 1.0.4
-      debug: 2.6.9
-      depd: 1.1.2
-      http-errors: 1.8.1
-      iconv-lite: 0.4.24
-      on-finished: 2.3.0
-      qs: 6.9.6
-      raw-body: 2.4.2
-      type-is: 1.6.18
-    transitivePeerDependencies:
-      - supports-color
+  /emoji-regex/7.0.3:
+    resolution: {integrity: 
sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==}
     dev: true
 
-  /bonjour/3.5.0:
-    resolution: {integrity: sha1-jokKGD2O6aI5OzhExpGkK897yfU=}
-    dependencies:
-      array-flatten: 2.1.2
-      deep-equal: 1.1.1
-      dns-equal: 1.0.0
-      dns-txt: 2.0.2
-      multicast-dns: 6.2.3
-      multicast-dns-service-types: 1.1.0
+  /emoji-regex/8.0.0:
+    resolution: {integrity: 
sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
     dev: true
 
-  /boolbase/1.0.0:
-    resolution: {integrity: sha1-aN/1++YMUes3cl6p4+0xDcwed24=}
+  /emoji-regex/9.2.2:
+    resolution: {integrity: 
sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
     dev: true
 
-  /boxen/5.1.2:
-    resolution: {integrity: 
sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==}
-    engines: {node: '>=10'}
-    dependencies:
-      ansi-align: 3.0.1
-      camelcase: 6.3.0
-      chalk: 4.1.2
-      cli-boxes: 2.2.1
-      string-width: 4.2.3
-      type-fest: 0.20.2
-      widest-line: 3.1.0
-      wrap-ansi: 7.0.0
+  /emojis-list/2.1.0:
+    resolution: {integrity: 
sha512-knHEZMgs8BB+MInokmNTg/OyPlAddghe1YBgNwJBc5zsJi/uyIcXoSDsL/W9ymOsBoBGdPIHXYJ9+qKFwRwDng==}
+    engines: {node: '>= 0.10'}
     dev: true
 
-  /brace-expansion/1.1.11:
-    resolution: {integrity: 
sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
-    dependencies:
-      balanced-match: 1.0.2
-      concat-map: 0.0.1
-
-  /brace-expansion/2.0.1:
-    resolution: {integrity: 
sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
-    dependencies:
-      balanced-match: 1.0.2
-    dev: true
+  /emojis-list/3.0.0:
+    resolution: {integrity: 
sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==}
+    engines: {node: '>= 4'}
 
-  /braces/2.3.2:
-    resolution: {integrity: 
sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==}
-    engines: {node: '>=0.10.0'}
+  /emotion-theming/10.3.0_@emotion+core@10.3.1:
+    resolution: {integrity: 
sha512-mXiD2Oj7N9b6+h/dC6oLf9hwxbtKHQjoIqtodEyL8CpkN4F3V4IK/BT4D0C7zSs4BBFOu4UlPJbvvBLa88SGEA==}
+    peerDependencies:
+      '@emotion/core': ^10.0.27
+      react: '>=16.3.0'
     dependencies:
-      arr-flatten: 1.1.0
-      array-unique: 0.3.2
-      extend-shallow: 2.0.1
-      fill-range: 4.0.0
-      isobject: 3.0.1
-      repeat-element: 1.1.4
-      snapdragon: 0.8.2
-      snapdragon-node: 2.1.1
-      split-string: 3.1.0
-      to-regex: 3.0.2
-    transitivePeerDependencies:
-      - supports-color
+      '@babel/runtime': 7.17.8
+      '@emotion/core': 10.3.1
+      '@emotion/weak-memoize': 0.2.5
+      hoist-non-react-statics: 3.3.2
     dev: true
 
-  /braces/3.0.2:
-    resolution: {integrity: 
sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
-    engines: {node: '>=8'}
+  /emotion-theming/10.3.0_qzeatvug73zaio2r3dlvejynye:
+    resolution: {integrity: 
sha512-mXiD2Oj7N9b6+h/dC6oLf9hwxbtKHQjoIqtodEyL8CpkN4F3V4IK/BT4D0C7zSs4BBFOu4UlPJbvvBLa88SGEA==}
+    peerDependencies:
+      '@emotion/core': ^10.0.27
+      react: '>=16.3.0'
     dependencies:
-      fill-range: 7.0.1
-    dev: true
-
-  /brorand/1.1.0:
-    resolution: {integrity: sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=}
+      '@babel/runtime': 7.17.8
+      '@emotion/core': 10.3.1_react@16.14.0
+      '@emotion/weak-memoize': 0.2.5
+      hoist-non-react-statics: 3.3.2
+      react: 16.14.0
     dev: true
 
-  /browser-process-hrtime/1.0.0:
-    resolution: {integrity: 
sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==}
+  /encodeurl/1.0.2:
+    resolution: {integrity: 
sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==}
+    engines: {node: '>= 0.8'}
     dev: true
 
-  /browser-stdout/1.3.1:
-    resolution: {integrity: 
sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==}
+  /encoding/0.1.13:
+    resolution: {integrity: 
sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==}
+    dependencies:
+      iconv-lite: 0.6.3
     dev: true
 
-  /browserify-aes/1.2.0:
-    resolution: {integrity: 
sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==}
+  /end-of-stream/1.4.4:
+    resolution: {integrity: 
sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==}
     dependencies:
-      buffer-xor: 1.0.3
-      cipher-base: 1.0.4
-      create-hash: 1.2.0
-      evp_bytestokey: 1.0.3
-      inherits: 2.0.4
-      safe-buffer: 5.2.1
+      once: 1.4.0
     dev: true
 
-  /browserify-cipher/1.0.1:
-    resolution: {integrity: 
sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==}
+  /enhanced-resolve/4.5.0:
+    resolution: {integrity: 
sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==}
+    engines: {node: '>=6.9.0'}
     dependencies:
-      browserify-aes: 1.2.0
-      browserify-des: 1.0.2
-      evp_bytestokey: 1.0.3
+      graceful-fs: 4.2.10
+      memory-fs: 0.5.0
+      tapable: 1.1.3
     dev: true
 
-  /browserify-des/1.0.2:
-    resolution: {integrity: 
sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==}
+  /enhanced-resolve/5.8.2:
+    resolution: {integrity: 
sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==}
+    engines: {node: '>=10.13.0'}
     dependencies:
-      cipher-base: 1.0.4
-      des.js: 1.0.1
-      inherits: 2.0.4
-      safe-buffer: 5.2.1
+      graceful-fs: 4.2.10
+      tapable: 2.2.0
     dev: true
 
-  /browserify-rsa/4.1.0:
-    resolution: {integrity: 
sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==}
+  /enquirer/2.3.6:
+    resolution: {integrity: 
sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==}
+    engines: {node: '>=8.6'}
     dependencies:
-      bn.js: 5.2.0
-      randombytes: 2.1.0
+      ansi-colors: 4.1.1
     dev: true
 
-  /browserify-sign/4.2.1:
-    resolution: {integrity: 
sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==}
-    dependencies:
-      bn.js: 5.2.0
-      browserify-rsa: 4.1.0
-      create-hash: 1.2.0
-      create-hmac: 1.1.7
-      elliptic: 6.5.4
-      inherits: 2.0.4
-      parse-asn1: 5.1.6
-      readable-stream: 3.6.0
-      safe-buffer: 5.2.1
+  /entities/2.2.0:
+    resolution: {integrity: 
sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==}
     dev: true
 
-  /browserify-zlib/0.2.0:
-    resolution: {integrity: 
sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==}
-    dependencies:
-      pako: 1.0.11
+  /entities/4.4.0:
+    resolution: {integrity: 
sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==}
+    engines: {node: '>=0.12'}
     dev: true
 
-  /browserslist/4.19.1:
-    resolution: {integrity: 
sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==}
-    engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+  /envinfo/7.8.1:
+    resolution: {integrity: 
sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==}
+    engines: {node: '>=4'}
     hasBin: true
-    dependencies:
-      caniuse-lite: 1.0.30001311
-      electron-to-chromium: 1.4.68
-      escalade: 3.1.1
-      node-releases: 2.0.2
-      picocolors: 1.0.0
     dev: true
 
-  /buffer-from/1.1.2:
-    resolution: {integrity: 
sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
+  /enzyme-adapter-preact-pure/3.4.0_fh4cerfcdrs5uit63qwkqtrfyi:
+    resolution: {integrity: 
sha512-bP7HX8l5xoBG8d/nYZVIQgm2LFJWNHEl1+xfdQj02tYuveHg/C/iLtjzF/89LjgyTAhUEczGiWuXfn4/KhJeCw==}
+    peerDependencies:
+      enzyme: ^3.11.0
+      preact: ^10.0.0
+    dependencies:
+      array.prototype.flatmap: 1.2.5
+      enzyme: 3.11.0
+      preact: 10.6.5
+    dev: true
 
-  /buffer-indexof/1.1.1:
-    resolution: {integrity: 
sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==}
+  /enzyme-shallow-equal/1.0.4:
+    resolution: {integrity: 
sha512-MttIwB8kKxypwHvRynuC3ahyNc+cFbR8mjVIltnmzQ0uKGqmsfO4bfBuLxb0beLNPhjblUEYvEbsg+VSygvF1Q==}
+    dependencies:
+      has: 1.0.3
+      object-is: 1.1.5
     dev: true
 
-  /buffer-xor/1.0.3:
-    resolution: {integrity: sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=}
+  /enzyme/3.11.0:
+    resolution: {integrity: 
sha512-Dw8/Gs4vRjxY6/6i9wU0V+utmQO9kvh9XLnz3LIudviOnVYDEe2ec+0k+NQoMamn1VrjKgCUOWj5jG/5M5M0Qw==}
+    dependencies:
+      array.prototype.flat: 1.2.5
+      cheerio: 1.0.0-rc.12
+      enzyme-shallow-equal: 1.0.4
+      function.prototype.name: 1.1.5
+      has: 1.0.3
+      html-element-map: 1.3.1
+      is-boolean-object: 1.1.2
+      is-callable: 1.2.4
+      is-number-object: 1.0.6
+      is-regex: 1.1.4
+      is-string: 1.0.7
+      is-subset: 0.1.1
+      lodash.escape: 4.0.1
+      lodash.isequal: 4.5.0
+      object-inspect: 1.12.0
+      object-is: 1.1.5
+      object.assign: 4.1.2
+      object.entries: 1.1.5
+      object.values: 1.1.5
+      raf: 3.4.1
+      rst-selector-parser: 2.2.3
+      string.prototype.trim: 1.2.6
     dev: true
 
-  /buffer/4.9.2:
-    resolution: {integrity: 
sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==}
+  /errno/0.1.8:
+    resolution: {integrity: 
sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==}
+    hasBin: true
     dependencies:
-      base64-js: 1.5.1
-      ieee754: 1.2.1
-      isarray: 1.0.0
+      prr: 1.0.1
     dev: true
 
-  /buffer/5.7.1:
-    resolution: {integrity: 
sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
+  /error-ex/1.3.2:
+    resolution: {integrity: 
sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
     dependencies:
-      base64-js: 1.5.1
-      ieee754: 1.2.1
+      is-arrayish: 0.2.1
     dev: true
 
-  /builtin-modules/3.3.0:
-    resolution: {integrity: 
sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==}
-    engines: {node: '>=6'}
+  /es-abstract/1.19.1:
+    resolution: {integrity: 
sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.2
+      es-to-primitive: 1.2.1
+      function-bind: 1.1.1
+      get-intrinsic: 1.1.1
+      get-symbol-description: 1.0.0
+      has: 1.0.3
+      has-symbols: 1.0.2
+      internal-slot: 1.0.3
+      is-callable: 1.2.4
+      is-negative-zero: 2.0.2
+      is-regex: 1.1.4
+      is-shared-array-buffer: 1.0.1
+      is-string: 1.0.7
+      is-weakref: 1.0.2
+      object-inspect: 1.12.0
+      object-keys: 1.1.1
+      object.assign: 4.1.2
+      string.prototype.trimend: 1.0.4
+      string.prototype.trimstart: 1.0.4
+      unbox-primitive: 1.0.1
     dev: true
 
-  /builtin-status-codes/3.0.0:
-    resolution: {integrity: sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=}
+  /es-abstract/1.20.4:
+    resolution: {integrity: 
sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.2
+      es-to-primitive: 1.2.1
+      function-bind: 1.1.1
+      function.prototype.name: 1.1.5
+      get-intrinsic: 1.1.3
+      get-symbol-description: 1.0.0
+      has: 1.0.3
+      has-property-descriptors: 1.0.0
+      has-symbols: 1.0.3
+      internal-slot: 1.0.3
+      is-callable: 1.2.7
+      is-negative-zero: 2.0.2
+      is-regex: 1.1.4
+      is-shared-array-buffer: 1.0.2
+      is-string: 1.0.7
+      is-weakref: 1.0.2
+      object-inspect: 1.12.2
+      object-keys: 1.1.1
+      object.assign: 4.1.4
+      regexp.prototype.flags: 1.4.3
+      safe-regex-test: 1.0.0
+      string.prototype.trimend: 1.0.5
+      string.prototype.trimstart: 1.0.5
+      unbox-primitive: 1.0.2
     dev: true
 
-  /builtins/1.0.3:
-    resolution: {integrity: sha1-y5T662HIaWRR2zZTThQi+U8K7og=}
+  /es-array-method-boxes-properly/1.0.0:
+    resolution: {integrity: 
sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==}
     dev: true
 
-  /bulma-checkbox/1.2.1:
-    resolution: {integrity: 
sha512-Ad7kSzwYwHLYyow92IJPz9jgolDDo5ivlFdSBe7W4LR9WnLt/Gd2iE07m3uhoU/g37oIZcMHNC33ZxJKqAuSzQ==}
+  /es-get-iterator/1.1.2:
+    resolution: {integrity: 
sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ==}
     dependencies:
-      bulma: 0.9.3
+      call-bind: 1.0.2
+      get-intrinsic: 1.1.3
+      has-symbols: 1.0.3
+      is-arguments: 1.1.1
+      is-map: 2.0.2
+      is-set: 2.0.2
+      is-string: 1.0.7
+      isarray: 2.0.5
     dev: true
 
-  /bulma-radio/1.2.0:
-    resolution: {integrity: 
sha512-rIzqALGakpKf9Eju4sGMt2Pwnn7X+AdYh6itjsCxLCJ/Ext4Cdd/M7uevQlXDy0MSwrQBMBLR8buSToBCuI+zA==}
+  /es-to-primitive/1.2.1:
+    resolution: {integrity: 
sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==}
+    engines: {node: '>= 0.4'}
     dependencies:
-      bulma: 0.9.3
+      is-callable: 1.2.7
+      is-date-object: 1.0.5
+      is-symbol: 1.0.4
     dev: true
 
-  /bulma/0.9.3:
-    resolution: {integrity: 
sha512-0d7GNW1PY4ud8TWxdNcP6Cc8Bu7MxcntD/RRLGWuiw/s0a9P+XlH/6QoOIrmbj6o8WWJzJYhytiu9nFjTszk1g==}
+  /es5-shim/4.6.7:
+    resolution: {integrity: 
sha512-jg21/dmlrNQI7JyyA2w7n+yifSxBng0ZralnSfVZjoCawgNTCnS+yBCyVM9DL5itm7SUnDGgv7hcq2XCZX4iRQ==}
+    engines: {node: '>=0.4.0'}
     dev: true
 
-  /bytes/3.0.0:
-    resolution: {integrity: sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=}
-    engines: {node: '>= 0.8'}
+  /es6-error/4.1.1:
+    resolution: {integrity: 
sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==}
     dev: true
 
-  /bytes/3.1.1:
-    resolution: {integrity: 
sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==}
-    engines: {node: '>= 0.8'}
+  /es6-shim/0.35.6:
+    resolution: {integrity: 
sha512-EmTr31wppcaIAgblChZiuN/l9Y7DPyw8Xtbg7fIVngn6zMW+IEBJDJngeKC3x6wr0V/vcA2wqeFnaw1bFJbDdA==}
     dev: true
 
-  /c8/7.11.0:
-    resolution: {integrity: 
sha512-XqPyj1uvlHMr+Y1IeRndC2X5P7iJzJlEJwBpCdBbq2JocXOgJfr+JVfJkyNMGROke5LfKrhSFXGFXnwnRJAUJw==}
-    engines: {node: '>=10.12.0'}
-    hasBin: true
-    dependencies:
-      '@bcoe/v8-coverage': 0.2.3
-      '@istanbuljs/schema': 0.1.3
-      find-up: 5.0.0
-      foreground-child: 2.0.0
-      istanbul-lib-coverage: 3.2.0
-      istanbul-lib-report: 3.0.0
-      istanbul-reports: 3.1.3
-      rimraf: 3.0.2
-      test-exclude: 6.0.0
-      v8-to-istanbul: 8.1.1
-      yargs: 16.2.0
-      yargs-parser: 20.2.9
+  /esbuild-android-arm64/0.14.21:
+    resolution: {integrity: 
sha512-Bqgld1TY0wZv8TqiQmVxQFgYzz8ZmyzT7clXBDZFkOOdRybzsnj8AZuK1pwcLVA7Ya6XncHgJqIao7NFd3s0RQ==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [android]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /cacache/12.0.4:
-    resolution: {integrity: 
sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==}
-    dependencies:
-      bluebird: 3.7.2
-      chownr: 1.1.4
-      figgy-pudding: 3.5.2
-      glob: 7.2.0
-      graceful-fs: 4.2.9
-      infer-owner: 1.0.4
-      lru-cache: 5.1.1
-      mississippi: 3.0.0
-      mkdirp: 0.5.5
-      move-concurrently: 1.0.1
-      promise-inflight: 1.0.1_bluebird@3.7.2
-      rimraf: 2.7.1
-      ssri: 6.0.2
-      unique-filename: 1.1.1
-      y18n: 4.0.3
+  /esbuild-darwin-64/0.14.21:
+    resolution: {integrity: 
sha512-j+Eg+e13djzyYINVvAbOo2/zvZ2DivuJJTaBrJnJHSD7kUNuGHRkHoSfFjbI80KHkn091w350wdmXDNSgRjfYQ==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [darwin]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /cacache/15.3.0:
-    resolution: {integrity: 
sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==}
-    engines: {node: '>= 10'}
-    dependencies:
-      '@npmcli/fs': 1.1.0
-      '@npmcli/move-file': 1.1.2
-      chownr: 2.0.0
-      fs-minipass: 2.1.0
-      glob: 7.2.0
-      infer-owner: 1.0.4
-      lru-cache: 6.0.0
-      minipass: 3.1.6
-      minipass-collect: 1.0.2
-      minipass-flush: 1.0.5
-      minipass-pipeline: 1.2.4
-      mkdirp: 1.0.4
-      p-map: 4.0.0
-      promise-inflight: 1.0.1_bluebird@3.7.2
-      rimraf: 3.0.2
-      ssri: 8.0.1
-      tar: 6.1.11
-      unique-filename: 1.1.1
-    transitivePeerDependencies:
-      - bluebird
+  /esbuild-darwin-arm64/0.14.21:
+    resolution: {integrity: 
sha512-nDNTKWDPI0RuoPj5BhcSB2z5EmZJJAyRtZLIjyXSqSpAyoB8eyAKXl4lB8U2P78Fnh4Lh1le/fmpewXE04JhBQ==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [darwin]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /cache-base/1.0.1:
-    resolution: {integrity: 
sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==}
-    engines: {node: '>=0.10.0'}
-    dependencies:
-      collection-visit: 1.0.0
-      component-emitter: 1.3.0
-      get-value: 2.0.6
-      has-value: 1.0.0
-      isobject: 3.0.1
-      set-value: 2.0.1
-      to-object-path: 0.3.0
-      union-value: 1.0.1
-      unset-value: 1.0.0
+  /esbuild-freebsd-64/0.14.21:
+    resolution: {integrity: 
sha512-zIurkCHXhxELiDZtLGiexi8t8onQc2LtuE+S7457H/pP0g0MLRKMrsn/IN4LDkNe6lvBjuoZZi2OfelOHn831g==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [freebsd]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /cacheable-request/6.1.0:
-    resolution: {integrity: 
sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==}
-    engines: {node: '>=8'}
-    dependencies:
-      clone-response: 1.0.2
-      get-stream: 5.2.0
-      http-cache-semantics: 4.1.0
-      keyv: 3.1.0
-      lowercase-keys: 2.0.0
-      normalize-url: 4.5.1
-      responselike: 1.0.2
+  /esbuild-freebsd-arm64/0.14.21:
+    resolution: {integrity: 
sha512-wdxMmkJfbwcN+q85MpeUEamVZ40FNsBa9mPq8tAszDn8TRT2HoJvVRADPIIBa9SWWwlDChIMjkDKAnS3KS/sPA==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [freebsd]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /caching-transform/4.0.0:
-    resolution: {integrity: 
sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==}
-    engines: {node: '>=8'}
-    dependencies:
-      hasha: 5.2.2
-      make-dir: 3.1.0
-      package-hash: 4.0.0
-      write-file-atomic: 3.0.3
+  /esbuild-linux-32/0.14.21:
+    resolution: {integrity: 
sha512-fmxvyzOPPh2xiEHojpCeIQP6pXcoKsWbz3ryDDIKLOsk4xp3GbpHIEAWP0xTeuhEbendmvBDVKbAVv3PnODXLg==}
+    engines: {node: '>=12'}
+    cpu: [ia32]
+    os: [linux]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /call-bind/1.0.2:
-    resolution: {integrity: 
sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==}
-    dependencies:
-      function-bind: 1.1.1
-      get-intrinsic: 1.1.1
+  /esbuild-linux-64/0.14.21:
+    resolution: {integrity: 
sha512-edZyNOv1ql+kpmlzdqzzDjRQYls+tSyi4QFi+PdBhATJFUqHsnNELWA9vMSzAaInPOEaVUTA5Ml28XFChcy4DA==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [linux]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /caller-callsite/2.0.0:
-    resolution: {integrity: sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=}
-    engines: {node: '>=4'}
-    dependencies:
-      callsites: 2.0.0
+  /esbuild-linux-arm/0.14.21:
+    resolution: {integrity: 
sha512-aSU5pUueK6afqmLQsbU+QcFBT62L+4G9hHMJDHWfxgid6hzhSmfRH9U/f+ymvxsSTr/HFRU4y7ox8ZyhlVl98w==}
+    engines: {node: '>=12'}
+    cpu: [arm]
+    os: [linux]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /caller-path/2.0.0:
-    resolution: {integrity: sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=}
-    engines: {node: '>=4'}
-    dependencies:
-      caller-callsite: 2.0.0
+  /esbuild-linux-arm64/0.14.21:
+    resolution: {integrity: 
sha512-t5qxRkq4zdQC0zXpzSB2bTtfLgOvR0C6BXYaRE/6/k8/4SrkZcTZBeNu+xGvwCU4b5dU9ST9pwIWkK6T1grS8g==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [linux]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /callsites/2.0.0:
-    resolution: {integrity: sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=}
-    engines: {node: '>=4'}
+  /esbuild-linux-mips64le/0.14.21:
+    resolution: {integrity: 
sha512-jLZLQGCNlUsmIHtGqNvBs3zN+7a4D9ckf0JZ+jQTwHdZJ1SgV9mAjbB980OFo66LoY+WeM7t3WEnq3FjI1zw4A==}
+    engines: {node: '>=12'}
+    cpu: [mips64el]
+    os: [linux]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /callsites/3.1.0:
-    resolution: {integrity: 
sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
-    engines: {node: '>=6'}
+  /esbuild-linux-ppc64le/0.14.21:
+    resolution: {integrity: 
sha512-4TWxpK391en2UBUw6GSrukToTDu6lL9vkm3Ll40HrI08WG3qcnJu7bl8e1+GzelDsiw1QmfAY/nNvJ6iaHRpCQ==}
+    engines: {node: '>=12'}
+    cpu: [ppc64]
+    os: [linux]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /callsites/4.0.0:
-    resolution: {integrity: 
sha512-y3jRROutgpKdz5vzEhWM34TidDU8vkJppF8dszITeb1PQmSqV3DTxyV8G/lyO/DNvtE1YTedehmw9MPZsCBHxQ==}
-    engines: {node: '>=12.20'}
+  /esbuild-linux-riscv64/0.14.21:
+    resolution: {integrity: 
sha512-fElngqOaOfTsF+u+oetDLHsPG74vB2ZaGZUqmGefAJn3a5z9Z2pNa4WpVbbKgHpaAAy5tWM1m1sbGohj6Ki6+Q==}
+    engines: {node: '>=12'}
+    cpu: [riscv64]
+    os: [linux]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /camel-case/3.0.0:
-    resolution: {integrity: sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=}
-    dependencies:
-      no-case: 2.3.2
-      upper-case: 1.1.3
+  /esbuild-linux-s390x/0.14.21:
+    resolution: {integrity: 
sha512-brleZ6R5fYv0qQ7ZBwenQmP6i9TdvJCB092c/3D3pTLQHBGHJb5zWgKxOeS7bdHzmLy6a6W7GbFk6QKpjyD6QA==}
+    engines: {node: '>=12'}
+    cpu: [s390x]
+    os: [linux]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /camelcase/5.3.1:
-    resolution: {integrity: 
sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
-    engines: {node: '>=6'}
+  /esbuild-netbsd-64/0.14.21:
+    resolution: {integrity: 
sha512-nCEgsLCQ8RoFWVV8pVI+kX66ICwbPP/M9vEa0NJGIEB/Vs5sVGMqkf67oln90XNSkbc0bPBDuo4G6FxlF7PN8g==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [netbsd]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /camelcase/6.3.0:
-    resolution: {integrity: 
sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
-    engines: {node: '>=10'}
+  /esbuild-openbsd-64/0.14.21:
+    resolution: {integrity: 
sha512-h9zLMyVD0T73MDTVYIb/qUTokwI6EJH9O6wESuTNq6+XpMSr6C5aYZ4fvFKdNELW+Xsod+yDS2hV2JTUAbFrLA==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [openbsd]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /caniuse-api/3.0.0:
-    resolution: {integrity: 
sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==}
-    dependencies:
-      browserslist: 4.19.1
-      caniuse-lite: 1.0.30001311
-      lodash.memoize: 4.1.2
-      lodash.uniq: 4.5.0
+  /esbuild-sunos-64/0.14.21:
+    resolution: {integrity: 
sha512-Kl+7Cot32qd9oqpLdB1tEGXEkjBlijrIxMJ0+vlDFaqsODutif25on0IZlFxEBtL2Gosd4p5WCV1U7UskNQfXA==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [sunos]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /caniuse-lite/1.0.30001311:
-    resolution: {integrity: 
sha512-mleTFtFKfykEeW34EyfhGIFjGCqzhh38Y0LhdQ9aWF+HorZTtdgKV/1hEE0NlFkG2ubvisPV6l400tlbPys98A==}
+  /esbuild-windows-32/0.14.21:
+    resolution: {integrity: 
sha512-V7vnTq67xPBUCk/9UtlolmQ798Ecjdr1ZoI1vcSgw7M82aSSt0eZdP6bh5KAFZU8pxDcx3qoHyWQfHYr11f22A==}
+    engines: {node: '>=12'}
+    cpu: [ia32]
+    os: [win32]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /caseless/0.12.0:
-    resolution: {integrity: sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=}
+  /esbuild-windows-64/0.14.21:
+    resolution: {integrity: 
sha512-kDgHjKOHwjfJDCyRGELzVxiP/RBJBTA+wyspf78MTTJQkyPuxH2vChReNdWc+dU2S4gIZFHMdP1Qrl/k22ZmaA==}
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [win32]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /cbor/8.1.0:
-    resolution: {integrity: 
sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==}
-    engines: {node: '>=12.19'}
-    dependencies:
-      nofilter: 3.1.0
+  /esbuild-windows-arm64/0.14.21:
+    resolution: {integrity: 
sha512-8Sbo0zpzgwWrwjQYLmHF78f7E2xg5Ve63bjB2ng3V2aManilnnTGaliq2snYg+NOX60+hEvJHRdVnuIAHW0lVw==}
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [win32]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /chai/4.3.6:
-    resolution: {integrity: 
sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==}
-    engines: {node: '>=4'}
-    dependencies:
-      assertion-error: 1.1.0
-      check-error: 1.0.2
-      deep-eql: 3.0.1
-      get-func-name: 2.0.0
-      loupe: 2.3.4
-      pathval: 1.1.1
-      type-detect: 4.0.8
-
-  /chalk/0.4.0:
-    resolution: {integrity: sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=}
-    engines: {node: '>=0.8.0'}
-    dependencies:
-      ansi-styles: 1.0.0
-      has-color: 0.1.7
-      strip-ansi: 0.1.1
+  /esbuild/0.12.29:
+    resolution: {integrity: 
sha512-w/XuoBCSwepyiZtIRsKsetiLDUVGPVw1E/R3VTFSecIy8UR7Cq3SOtwKHJMFoVqqVG36aGkzh4e8BvpO1Fdc7g==}
+    hasBin: true
+    requiresBuild: true
     dev: true
 
-  /chalk/2.4.1:
-    resolution: {integrity: 
sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==}
-    engines: {node: '>=4'}
-    dependencies:
-      ansi-styles: 3.2.1
-      escape-string-regexp: 1.0.5
-      supports-color: 5.5.0
+  /esbuild/0.14.21:
+    resolution: {integrity: 
sha512-7WEoNMBJdLN993dr9h0CpFHPRc3yFZD+EAVY9lg6syJJ12gc5fHq8d75QRExuhnMkT2DaRiIKFThRvDWP+fO+A==}
+    engines: {node: '>=12'}
+    hasBin: true
+    requiresBuild: true
+    optionalDependencies:
+      esbuild-android-arm64: 0.14.21
+      esbuild-darwin-64: 0.14.21
+      esbuild-darwin-arm64: 0.14.21
+      esbuild-freebsd-64: 0.14.21
+      esbuild-freebsd-arm64: 0.14.21
+      esbuild-linux-32: 0.14.21
+      esbuild-linux-64: 0.14.21
+      esbuild-linux-arm: 0.14.21
+      esbuild-linux-arm64: 0.14.21
+      esbuild-linux-mips64le: 0.14.21
+      esbuild-linux-ppc64le: 0.14.21
+      esbuild-linux-riscv64: 0.14.21
+      esbuild-linux-s390x: 0.14.21
+      esbuild-netbsd-64: 0.14.21
+      esbuild-openbsd-64: 0.14.21
+      esbuild-sunos-64: 0.14.21
+      esbuild-windows-32: 0.14.21
+      esbuild-windows-64: 0.14.21
+      esbuild-windows-arm64: 0.14.21
     dev: true
 
-  /chalk/2.4.2:
-    resolution: {integrity: 
sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
-    engines: {node: '>=4'}
-    dependencies:
-      ansi-styles: 3.2.1
-      escape-string-regexp: 1.0.5
-      supports-color: 5.5.0
+  /escalade/3.1.1:
+    resolution: {integrity: 
sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
+    engines: {node: '>=6'}
     dev: true
 
-  /chalk/3.0.0:
-    resolution: {integrity: 
sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==}
+  /escape-goat/2.1.1:
+    resolution: {integrity: 
sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==}
     engines: {node: '>=8'}
-    dependencies:
-      ansi-styles: 4.3.0
-      supports-color: 7.2.0
     dev: true
 
-  /chalk/4.1.2:
-    resolution: {integrity: 
sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
-    engines: {node: '>=10'}
-    dependencies:
-      ansi-styles: 4.3.0
-      supports-color: 7.2.0
+  /escape-html/1.0.3:
+    resolution: {integrity: 
sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
     dev: true
 
-  /chalk/5.1.2:
-    resolution: {integrity: 
sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ==}
-    engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
+  /escape-string-regexp/1.0.5:
+    resolution: {integrity: 
sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
+    engines: {node: '>=0.8.0'}
     dev: true
 
-  /charcodes/0.2.0:
-    resolution: {integrity: 
sha512-Y4kiDb+AM4Ecy58YkuZrrSRJBDQdQ2L+NyS1vHHFtNtUjgutcZfx3yp1dAONI/oPaPmyGfCLx5CxL+zauIMyKQ==}
-    engines: {node: '>=6'}
+  /escape-string-regexp/2.0.0:
+    resolution: {integrity: 
sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==}
+    engines: {node: '>=8'}
     dev: true
 
-  /check-error/1.0.2:
-    resolution: {integrity: 
sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==}
-
-  /chokidar/2.1.8:
-    resolution: {integrity: 
sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==}
-    deprecated: Chokidar 2 does not receive security updates since 2019. 
Upgrade to chokidar 3 with 15x fewer dependencies
-    dependencies:
-      anymatch: 2.0.0
-      async-each: 1.0.3
-      braces: 2.3.2
-      glob-parent: 3.1.0
-      inherits: 2.0.4
-      is-binary-path: 1.0.1
-      is-glob: 4.0.3
-      normalize-path: 3.0.0
-      path-is-absolute: 1.0.1
-      readdirp: 2.2.1
-      upath: 1.2.0
-    optionalDependencies:
-      fsevents: 1.2.13
-    transitivePeerDependencies:
-      - supports-color
+  /escape-string-regexp/4.0.0:
+    resolution: {integrity: 
sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
+    engines: {node: '>=10'}
     dev: true
-    optional: true
 
-  /chokidar/3.5.3:
-    resolution: {integrity: 
sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
-    engines: {node: '>= 8.10.0'}
+  /escape-string-regexp/5.0.0:
+    resolution: {integrity: 
sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
+    engines: {node: '>=12'}
+    dev: true
+
+  /escodegen/1.14.3:
+    resolution: {integrity: 
sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==}
+    engines: {node: '>=4.0'}
+    hasBin: true
     dependencies:
-      anymatch: 3.1.2
-      braces: 3.0.2
-      glob-parent: 5.1.2
-      is-binary-path: 2.1.0
-      is-glob: 4.0.3
-      normalize-path: 3.0.0
-      readdirp: 3.6.0
+      esprima: 4.0.1
+      estraverse: 4.3.0
+      esutils: 2.0.3
+      optionator: 0.8.3
     optionalDependencies:
-      fsevents: 2.3.2
+      source-map: 0.6.1
     dev: true
 
-  /chownr/1.1.4:
-    resolution: {integrity: 
sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
+  /escodegen/2.0.0:
+    resolution: {integrity: 
sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==}
+    engines: {node: '>=6.0'}
+    hasBin: true
+    dependencies:
+      esprima: 4.0.1
+      estraverse: 5.3.0
+      esutils: 2.0.3
+      optionator: 0.8.3
+    optionalDependencies:
+      source-map: 0.6.1
     dev: true
 
-  /chownr/2.0.0:
-    resolution: {integrity: 
sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==}
-    engines: {node: '>=10'}
+  /eslint-config-airbnb-base/15.0.0_hexytdhmo422l55jsqymxqfu6q:
+    resolution: {integrity: 
sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==}
+    engines: {node: ^10.12.0 || >=12.0.0}
+    peerDependencies:
+      eslint: ^7.32.0 || ^8.2.0
+      eslint-plugin-import: ^2.25.2
+    dependencies:
+      confusing-browser-globals: 1.0.11
+      eslint: 8.8.0
+      eslint-plugin-import: 2.25.4_r2xatzqf7unmty2b7kgqnez6uu
+      object.assign: 4.1.2
+      object.entries: 1.1.5
+      semver: 6.3.0
     dev: true
 
-  /chrome-trace-event/1.0.3:
-    resolution: {integrity: 
sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==}
-    engines: {node: '>=6.0'}
+  /eslint-config-airbnb-typescript/16.1.0_fqyt75ttx5czzyyhmxfbzg22fu:
+    resolution: {integrity: 
sha512-W5Cq20KpEx5ZLC54bnVrC37zq2+WD956Kp/Ma3nYFRjT1v9KM63v+DPkrrmmrVqrlDKaD0ivm/qeYmyHV6qKlw==}
+    peerDependencies:
+      '@typescript-eslint/eslint-plugin': ^5.0.0
+      '@typescript-eslint/parser': ^5.0.0
+    dependencies:
+      '@typescript-eslint/eslint-plugin': 5.36.1_gjcw3hhr2cxnngiu5lw4bi633m
+      '@typescript-eslint/parser': 5.36.1_o2nrgn6wwxunlqlzzokx4es3q4
+      eslint-config-airbnb-base: 15.0.0_hexytdhmo422l55jsqymxqfu6q
+    transitivePeerDependencies:
+      - eslint
+      - eslint-plugin-import
     dev: true
 
-  /chunkd/2.0.1:
-    resolution: {integrity: 
sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==}
+  /eslint-config-preact/1.3.0_nxlzr75jbqkso2fds5zjovs2ii:
+    resolution: {integrity: 
sha512-yHYXg5qNzEJd3D/30AmsIW0W8MuY858KpApXp7xxBF08IYUljSKCOqMx+dVucXHQnAm7+11wOnMkgVHIBAechw==}
+    peerDependencies:
+      eslint: 6.x || 7.x || 8.x
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/eslint-parser': 7.19.1_ifghgpypvdmamphfg2ieta34qe
+      '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.17.2
+      '@babel/plugin-syntax-decorators': 7.17.0_@babel+core@7.17.2
+      '@babel/plugin-syntax-jsx': 7.16.7_@babel+core@7.17.2
+      eslint: 7.32.0
+      eslint-plugin-compat: 4.0.2_eslint@7.32.0
+      eslint-plugin-jest: 25.7.0_nxlzr75jbqkso2fds5zjovs2ii
+      eslint-plugin-react: 7.28.0_eslint@7.32.0
+      eslint-plugin-react-hooks: 4.3.0_eslint@7.32.0
+    transitivePeerDependencies:
+      - '@typescript-eslint/eslint-plugin'
+      - jest
+      - supports-color
+      - typescript
     dev: true
 
-  /ci-env/1.17.0:
-    resolution: {integrity: 
sha512-NtTjhgSEqv4Aj90TUYHQLxHdnCPXnjdtuGG1X8lTfp/JqeXTdw0FTWl/vUAPuvbWZTF8QVpv6ASe/XacE+7R2A==}
+  /eslint-config-preact/1.3.0_w4k36q7phb5aratcwbohw6kmxe:
+    resolution: {integrity: 
sha512-yHYXg5qNzEJd3D/30AmsIW0W8MuY858KpApXp7xxBF08IYUljSKCOqMx+dVucXHQnAm7+11wOnMkgVHIBAechw==}
+    peerDependencies:
+      eslint: 6.x || 7.x || 8.x
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/eslint-parser': 7.19.1_rakzipanemow5i3hc6etgvncsm
+      '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.17.2
+      '@babel/plugin-syntax-decorators': 7.17.0_@babel+core@7.17.2
+      '@babel/plugin-syntax-jsx': 7.16.7_@babel+core@7.17.2
+      eslint: 8.8.0
+      eslint-plugin-compat: 4.0.2_eslint@8.8.0
+      eslint-plugin-jest: 25.7.0_w4k36q7phb5aratcwbohw6kmxe
+      eslint-plugin-react: 7.28.0_eslint@8.8.0
+      eslint-plugin-react-hooks: 4.3.0_eslint@8.8.0
+    transitivePeerDependencies:
+      - '@typescript-eslint/eslint-plugin'
+      - jest
+      - supports-color
+      - typescript
     dev: true
 
-  /ci-info/2.0.0:
-    resolution: {integrity: 
sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==}
+  /eslint-import-resolver-node/0.3.6:
+    resolution: {integrity: 
sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==}
+    dependencies:
+      debug: 3.2.7
+      resolve: 1.21.0
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /ci-info/3.5.0:
-    resolution: {integrity: 
sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==}
+  /eslint-module-utils/2.7.2_632zrvmnhpkgiajg2zqauquf6u:
+    resolution: {integrity: 
sha512-zquepFnWCY2ISMFwD/DqzaM++H+7PDzOpUvotJWm/y1BAFt5R4oeULgdrTejKqLkz7MA/tgstsUMNYc7wNdTrg==}
+    engines: {node: '>=4'}
+    peerDependencies:
+      '@typescript-eslint/parser': '*'
+      eslint-import-resolver-node: '*'
+      eslint-import-resolver-typescript: '*'
+      eslint-import-resolver-webpack: '*'
+    peerDependenciesMeta:
+      '@typescript-eslint/parser':
+        optional: true
+      eslint-import-resolver-node:
+        optional: true
+      eslint-import-resolver-typescript:
+        optional: true
+      eslint-import-resolver-webpack:
+        optional: true
+    dependencies:
+      '@typescript-eslint/parser': 5.36.1_o2nrgn6wwxunlqlzzokx4es3q4
+      debug: 3.2.7
+      eslint-import-resolver-node: 0.3.6
+      find-up: 2.1.0
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /ci-parallel-vars/1.0.1:
-    resolution: {integrity: 
sha512-uvzpYrpmidaoxvIQHM+rKSrigjOe9feHYbw4uOI2gdfe1C3xIlxO+kVXq83WQWNniTf8bAxVpy+cQeFQsMERKg==}
+  /eslint-plugin-compat/4.0.2_eslint@7.32.0:
+    resolution: {integrity: 
sha512-xqvoO54CLTVaEYGMzhu35Wzwk/As7rCvz/2dqwnFiWi0OJccEtGIn+5qq3zqIu9nboXlpdBN579fZcItC73Ycg==}
+    engines: {node: '>=9.x'}
+    peerDependencies:
+      eslint: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0
+    dependencies:
+      '@mdn/browser-compat-data': 4.2.1
+      ast-metadata-inferer: 0.7.0
+      browserslist: 4.19.1
+      caniuse-lite: 1.0.30001311
+      core-js: 3.26.0
+      eslint: 7.32.0
+      find-up: 5.0.0
+      lodash.memoize: 4.1.2
+      semver: 7.3.5
     dev: true
 
-  /cipher-base/1.0.4:
-    resolution: {integrity: 
sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==}
+  /eslint-plugin-compat/4.0.2_eslint@8.8.0:
+    resolution: {integrity: 
sha512-xqvoO54CLTVaEYGMzhu35Wzwk/As7rCvz/2dqwnFiWi0OJccEtGIn+5qq3zqIu9nboXlpdBN579fZcItC73Ycg==}
+    engines: {node: '>=9.x'}
+    peerDependencies:
+      eslint: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0
     dependencies:
-      inherits: 2.0.4
-      safe-buffer: 5.2.1
+      '@mdn/browser-compat-data': 4.2.1
+      ast-metadata-inferer: 0.7.0
+      browserslist: 4.19.1
+      caniuse-lite: 1.0.30001311
+      core-js: 3.26.0
+      eslint: 8.8.0
+      find-up: 5.0.0
+      lodash.memoize: 4.1.2
+      semver: 7.3.5
     dev: true
 
-  /class-utils/0.3.6:
-    resolution: {integrity: 
sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==}
-    engines: {node: '>=0.10.0'}
+  /eslint-plugin-header/3.1.1:
+    resolution: {integrity: 
sha512-9vlKxuJ4qf793CmeeSrZUvVClw6amtpghq3CuWcB5cUNnWHQhgcqy5eF8oVKFk1G3Y/CbchGfEaw3wiIJaNmVg==}
+    peerDependencies:
+      eslint: '>=7.7.0'
+    dev: true
+
+  /eslint-plugin-header/3.1.1_eslint@7.32.0:
+    resolution: {integrity: 
sha512-9vlKxuJ4qf793CmeeSrZUvVClw6amtpghq3CuWcB5cUNnWHQhgcqy5eF8oVKFk1G3Y/CbchGfEaw3wiIJaNmVg==}
+    peerDependencies:
+      eslint: '>=7.7.0'
     dependencies:
-      arr-union: 3.1.0
-      define-property: 0.2.5
-      isobject: 3.0.1
-      static-extend: 0.1.2
+      eslint: 7.32.0
     dev: true
 
-  /clean-css/4.2.4:
-    resolution: {integrity: 
sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==}
-    engines: {node: '>= 4.0'}
+  /eslint-plugin-import/2.25.4_r2xatzqf7unmty2b7kgqnez6uu:
+    resolution: {integrity: 
sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==}
+    engines: {node: '>=4'}
+    peerDependencies:
+      '@typescript-eslint/parser': '*'
+      eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8
+    peerDependenciesMeta:
+      '@typescript-eslint/parser':
+        optional: true
     dependencies:
-      source-map: 0.6.1
+      '@typescript-eslint/parser': 5.36.1_o2nrgn6wwxunlqlzzokx4es3q4
+      array-includes: 3.1.4
+      array.prototype.flat: 1.2.5
+      debug: 2.6.9
+      doctrine: 2.1.0
+      eslint: 8.8.0
+      eslint-import-resolver-node: 0.3.6
+      eslint-module-utils: 2.7.2_632zrvmnhpkgiajg2zqauquf6u
+      has: 1.0.3
+      is-core-module: 2.8.0
+      is-glob: 4.0.3
+      minimatch: 3.0.4
+      object.values: 1.1.5
+      resolve: 1.21.0
+      tsconfig-paths: 3.12.0
+    transitivePeerDependencies:
+      - eslint-import-resolver-typescript
+      - eslint-import-resolver-webpack
+      - supports-color
     dev: true
 
-  /clean-stack/2.2.0:
-    resolution: {integrity: 
sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==}
-    engines: {node: '>=6'}
+  /eslint-plugin-jest/25.7.0_nxlzr75jbqkso2fds5zjovs2ii:
+    resolution: {integrity: 
sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==}
+    engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
+    peerDependencies:
+      '@typescript-eslint/eslint-plugin': ^4.0.0 || ^5.0.0
+      eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
+      jest: '*'
+    peerDependenciesMeta:
+      '@typescript-eslint/eslint-plugin':
+        optional: true
+      jest:
+        optional: true
+    dependencies:
+      '@typescript-eslint/eslint-plugin': 4.33.0_k4l66av2tbo6kxzw52jzgbfzii
+      '@typescript-eslint/experimental-utils': 
5.40.1_3rubbgt5ekhqrcgx4uwls3neim
+      eslint: 7.32.0
+      jest: 26.6.3
+    transitivePeerDependencies:
+      - supports-color
+      - typescript
     dev: true
 
-  /clean-stack/4.2.0:
-    resolution: {integrity: 
sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==}
-    engines: {node: '>=12'}
+  /eslint-plugin-jest/25.7.0_w4k36q7phb5aratcwbohw6kmxe:
+    resolution: {integrity: 
sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==}
+    engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
+    peerDependencies:
+      '@typescript-eslint/eslint-plugin': ^4.0.0 || ^5.0.0
+      eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
+      jest: '*'
+    peerDependenciesMeta:
+      '@typescript-eslint/eslint-plugin':
+        optional: true
+      jest:
+        optional: true
     dependencies:
-      escape-string-regexp: 5.0.0
+      '@typescript-eslint/eslint-plugin': 5.36.1_gjcw3hhr2cxnngiu5lw4bi633m
+      '@typescript-eslint/experimental-utils': 
5.40.1_o2nrgn6wwxunlqlzzokx4es3q4
+      eslint: 8.8.0
+      jest: 27.5.1
+    transitivePeerDependencies:
+      - supports-color
+      - typescript
     dev: true
 
-  /clean-yaml-object/0.1.0:
-    resolution: {integrity: 
sha512-3yONmlN9CSAkzNwnRCiJQ7Q2xK5mWuEfL3PuTZcAUzhObbXsfsnMptJzXwz93nc5zn9V9TwCVMmV7w4xsm43dw==}
-    engines: {node: '>=0.10.0'}
+  /eslint-plugin-jsx-a11y/6.5.1_eslint@8.8.0:
+    resolution: {integrity: 
sha512-sVCFKX9fllURnXT2JwLN5Qgo24Ug5NF6dxhkmxsMEUZhXRcGg+X3e1JbJ84YePQKBl5E0ZjAH5Q4rkdcGY99+g==}
+    engines: {node: '>=4.0'}
+    peerDependencies:
+      eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8
+    dependencies:
+      '@babel/runtime': 7.16.7
+      aria-query: 4.2.2
+      array-includes: 3.1.4
+      ast-types-flow: 0.0.7
+      axe-core: 4.3.5
+      axobject-query: 2.2.0
+      damerau-levenshtein: 1.0.7
+      emoji-regex: 9.2.2
+      eslint: 8.8.0
+      has: 1.0.3
+      jsx-ast-utils: 3.2.1
+      language-tags: 1.0.5
+      minimatch: 3.0.4
     dev: true
 
-  /cli-boxes/2.2.1:
-    resolution: {integrity: 
sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==}
-    engines: {node: '>=6'}
+  /eslint-plugin-react-hooks/4.3.0_eslint@7.32.0:
+    resolution: {integrity: 
sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA==}
+    engines: {node: '>=10'}
+    peerDependencies:
+      eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0
+    dependencies:
+      eslint: 7.32.0
     dev: true
 
-  /cli-cursor/3.1.0:
-    resolution: {integrity: 
sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==}
-    engines: {node: '>=8'}
+  /eslint-plugin-react-hooks/4.3.0_eslint@8.8.0:
+    resolution: {integrity: 
sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA==}
+    engines: {node: '>=10'}
+    peerDependencies:
+      eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0
     dependencies:
-      restore-cursor: 3.1.0
+      eslint: 8.8.0
     dev: true
 
-  /cli-spinners/2.6.1:
-    resolution: {integrity: 
sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==}
-    engines: {node: '>=6'}
+  /eslint-plugin-react/7.28.0_eslint@7.32.0:
+    resolution: {integrity: 
sha512-IOlFIRHzWfEQQKcAD4iyYDndHwTQiCMcJVJjxempf203jnNLUnW34AXLrV33+nEXoifJE2ZEGmcjKPL8957eSw==}
+    engines: {node: '>=4'}
+    peerDependencies:
+      eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8
+    dependencies:
+      array-includes: 3.1.4
+      array.prototype.flatmap: 1.2.5
+      doctrine: 2.1.0
+      eslint: 7.32.0
+      estraverse: 5.3.0
+      jsx-ast-utils: 3.2.1
+      minimatch: 3.0.5
+      object.entries: 1.1.5
+      object.fromentries: 2.0.5
+      object.hasown: 1.1.0
+      object.values: 1.1.5
+      prop-types: 15.8.1
+      resolve: 2.0.0-next.3
+      semver: 6.3.0
+      string.prototype.matchall: 4.0.6
     dev: true
 
-  /cli-truncate/3.1.0:
-    resolution: {integrity: 
sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==}
-    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+  /eslint-plugin-react/7.28.0_eslint@8.8.0:
+    resolution: {integrity: 
sha512-IOlFIRHzWfEQQKcAD4iyYDndHwTQiCMcJVJjxempf203jnNLUnW34AXLrV33+nEXoifJE2ZEGmcjKPL8957eSw==}
+    engines: {node: '>=4'}
+    peerDependencies:
+      eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8
     dependencies:
-      slice-ansi: 5.0.0
-      string-width: 5.1.2
+      array-includes: 3.1.4
+      array.prototype.flatmap: 1.2.5
+      doctrine: 2.1.0
+      eslint: 8.8.0
+      estraverse: 5.3.0
+      jsx-ast-utils: 3.2.1
+      minimatch: 3.0.5
+      object.entries: 1.1.5
+      object.fromentries: 2.0.5
+      object.hasown: 1.1.0
+      object.values: 1.1.5
+      prop-types: 15.8.1
+      resolve: 2.0.0-next.3
+      semver: 6.3.0
+      string.prototype.matchall: 4.0.6
     dev: true
 
-  /cliui/6.0.0:
-    resolution: {integrity: 
sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==}
+  /eslint-scope/4.0.3:
+    resolution: {integrity: 
sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==}
+    engines: {node: '>=4.0.0'}
     dependencies:
-      string-width: 4.2.3
-      strip-ansi: 6.0.1
-      wrap-ansi: 6.2.0
+      esrecurse: 4.3.0
+      estraverse: 4.3.0
     dev: true
 
-  /cliui/7.0.4:
-    resolution: {integrity: 
sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==}
+  /eslint-scope/5.1.1:
+    resolution: {integrity: 
sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==}
+    engines: {node: '>=8.0.0'}
     dependencies:
-      string-width: 4.2.3
-      strip-ansi: 6.0.1
-      wrap-ansi: 7.0.0
+      esrecurse: 4.3.0
+      estraverse: 4.3.0
     dev: true
 
-  /cliui/8.0.1:
-    resolution: {integrity: 
sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
-    engines: {node: '>=12'}
+  /eslint-scope/7.1.0:
+    resolution: {integrity: 
sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dependencies:
-      string-width: 4.2.3
-      strip-ansi: 6.0.1
-      wrap-ansi: 7.0.0
+      esrecurse: 4.3.0
+      estraverse: 5.3.0
     dev: true
 
-  /clone-deep/4.0.1:
-    resolution: {integrity: 
sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==}
+  /eslint-utils/2.1.0:
+    resolution: {integrity: 
sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==}
     engines: {node: '>=6'}
     dependencies:
-      is-plain-object: 2.0.4
-      kind-of: 6.0.3
-      shallow-clone: 3.0.1
+      eslint-visitor-keys: 1.3.0
     dev: true
 
-  /clone-response/1.0.2:
-    resolution: {integrity: sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=}
+  /eslint-utils/3.0.0_eslint@7.32.0:
+    resolution: {integrity: 
sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==}
+    engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0}
+    peerDependencies:
+      eslint: '>=5'
     dependencies:
-      mimic-response: 1.0.1
+      eslint: 7.32.0
+      eslint-visitor-keys: 2.1.0
     dev: true
 
-  /clone/1.0.4:
-    resolution: {integrity: sha1-2jCcwmPfFZlMaIypAheco8fNfH4=}
-    engines: {node: '>=0.8'}
+  /eslint-utils/3.0.0_eslint@8.8.0:
+    resolution: {integrity: 
sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==}
+    engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0}
+    peerDependencies:
+      eslint: '>=5'
+    dependencies:
+      eslint: 8.8.0
+      eslint-visitor-keys: 2.1.0
     dev: true
 
-  /coa/2.0.2:
-    resolution: {integrity: 
sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==}
-    engines: {node: '>= 4.0'}
-    dependencies:
-      '@types/q': 1.5.5
-      chalk: 2.4.2
-      q: 1.5.1
+  /eslint-visitor-keys/1.3.0:
+    resolution: {integrity: 
sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==}
+    engines: {node: '>=4'}
     dev: true
 
-  /code-excerpt/4.0.0:
-    resolution: {integrity: 
sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==}
-    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
-    dependencies:
-      convert-to-spaces: 2.0.1
+  /eslint-visitor-keys/2.1.0:
+    resolution: {integrity: 
sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==}
+    engines: {node: '>=10'}
     dev: true
 
-  /collection-visit/1.0.0:
-    resolution: {integrity: sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=}
-    engines: {node: '>=0.10.0'}
-    dependencies:
-      map-visit: 1.0.0
-      object-visit: 1.0.1
+  /eslint-visitor-keys/3.2.0:
+    resolution: {integrity: 
sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dev: true
 
-  /color-convert/1.9.3:
-    resolution: {integrity: 
sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
-    dependencies:
-      color-name: 1.1.3
+  /eslint-visitor-keys/3.3.0:
+    resolution: {integrity: 
sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dev: true
 
-  /color-convert/2.0.1:
-    resolution: {integrity: 
sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
-    engines: {node: '>=7.0.0'}
+  /eslint/7.32.0:
+    resolution: {integrity: 
sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==}
+    engines: {node: ^10.12.0 || >=12.0.0}
+    hasBin: true
     dependencies:
-      color-name: 1.1.4
+      '@babel/code-frame': 7.12.11
+      '@eslint/eslintrc': 0.4.3
+      '@humanwhocodes/config-array': 0.5.0
+      ajv: 6.12.6
+      chalk: 4.1.2
+      cross-spawn: 7.0.3
+      debug: 4.3.4
+      doctrine: 3.0.0
+      enquirer: 2.3.6
+      escape-string-regexp: 4.0.0
+      eslint-scope: 5.1.1
+      eslint-utils: 2.1.0
+      eslint-visitor-keys: 2.1.0
+      espree: 7.3.1
+      esquery: 1.4.0
+      esutils: 2.0.3
+      fast-deep-equal: 3.1.3
+      file-entry-cache: 6.0.1
+      functional-red-black-tree: 1.0.1
+      glob-parent: 5.1.2
+      globals: 13.12.1
+      ignore: 4.0.6
+      import-fresh: 3.3.0
+      imurmurhash: 0.1.4
+      is-glob: 4.0.3
+      js-yaml: 3.14.1
+      json-stable-stringify-without-jsonify: 1.0.1
+      levn: 0.4.1
+      lodash.merge: 4.6.2
+      minimatch: 3.1.2
+      natural-compare: 1.4.0
+      optionator: 0.9.1
+      progress: 2.0.3
+      regexpp: 3.2.0
+      semver: 7.3.8
+      strip-ansi: 6.0.1
+      strip-json-comments: 3.1.1
+      table: 6.8.0
+      text-table: 0.2.0
+      v8-compile-cache: 2.3.0
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /color-name/1.1.3:
-    resolution: {integrity: 
sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
+  /eslint/8.8.0:
+    resolution: {integrity: 
sha512-H3KXAzQGBH1plhYS3okDix2ZthuYJlQQEGE5k0IKuEqUSiyu4AmxxlJ2MtTYeJ3xB4jDhcYCwGOg2TXYdnDXlQ==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    hasBin: true
+    dependencies:
+      '@eslint/eslintrc': 1.0.5
+      '@humanwhocodes/config-array': 0.9.3
+      ajv: 6.12.6
+      chalk: 4.1.2
+      cross-spawn: 7.0.3
+      debug: 4.3.3
+      doctrine: 3.0.0
+      escape-string-regexp: 4.0.0
+      eslint-scope: 7.1.0
+      eslint-utils: 3.0.0_eslint@8.8.0
+      eslint-visitor-keys: 3.2.0
+      espree: 9.3.0
+      esquery: 1.4.0
+      esutils: 2.0.3
+      fast-deep-equal: 3.1.3
+      file-entry-cache: 6.0.1
+      functional-red-black-tree: 1.0.1
+      glob-parent: 6.0.2
+      globals: 13.12.1
+      ignore: 5.2.0
+      import-fresh: 3.3.0
+      imurmurhash: 0.1.4
+      is-glob: 4.0.3
+      js-yaml: 4.1.0
+      json-stable-stringify-without-jsonify: 1.0.1
+      levn: 0.4.1
+      lodash.merge: 4.6.2
+      minimatch: 3.0.5
+      natural-compare: 1.4.0
+      optionator: 0.9.1
+      regexpp: 3.2.0
+      strip-ansi: 6.0.1
+      strip-json-comments: 3.1.1
+      text-table: 0.2.0
+      v8-compile-cache: 2.3.0
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /color-name/1.1.4:
-    resolution: {integrity: 
sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+  /esm/3.2.25:
+    resolution: {integrity: 
sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==}
+    engines: {node: '>=6'}
     dev: true
 
-  /color-string/1.9.0:
-    resolution: {integrity: 
sha512-9Mrz2AQLefkH1UvASKj6v6hj/7eWgjnT/cVsR8CumieLoT+g900exWeNogqtweI8dxloXN9BDQTYro1oWu/5CQ==}
+  /espree/7.3.1:
+    resolution: {integrity: 
sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==}
+    engines: {node: ^10.12.0 || >=12.0.0}
     dependencies:
-      color-name: 1.1.4
-      simple-swizzle: 0.2.2
+      acorn: 7.4.1
+      acorn-jsx: 5.3.2_acorn@7.4.1
+      eslint-visitor-keys: 1.3.0
     dev: true
 
-  /color/3.2.1:
-    resolution: {integrity: 
sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==}
+  /espree/9.3.0:
+    resolution: {integrity: 
sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dependencies:
-      color-convert: 1.9.3
-      color-string: 1.9.0
+      acorn: 8.7.0
+      acorn-jsx: 5.3.2_acorn@8.7.0
+      eslint-visitor-keys: 3.2.0
     dev: true
 
-  /colord/2.9.2:
-    resolution: {integrity: 
sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ==}
+  /esprima/4.0.1:
+    resolution: {integrity: 
sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
+    engines: {node: '>=4'}
+    hasBin: true
     dev: true
 
-  /colorette/2.0.16:
-    resolution: {integrity: 
sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==}
+  /esquery/1.4.0:
+    resolution: {integrity: 
sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==}
+    engines: {node: '>=0.10'}
+    dependencies:
+      estraverse: 5.3.0
     dev: true
 
-  /combined-stream/1.0.8:
-    resolution: {integrity: 
sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
-    engines: {node: '>= 0.8'}
+  /esrecurse/4.3.0:
+    resolution: {integrity: 
sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
+    engines: {node: '>=4.0'}
     dependencies:
-      delayed-stream: 1.0.0
+      estraverse: 5.3.0
+    dev: true
 
-  /commander/2.17.1:
-    resolution: {integrity: 
sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==}
+  /estraverse/4.3.0:
+    resolution: {integrity: 
sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==}
+    engines: {node: '>=4.0'}
     dev: true
 
-  /commander/2.19.0:
-    resolution: {integrity: 
sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==}
+  /estraverse/5.3.0:
+    resolution: {integrity: 
sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
+    engines: {node: '>=4.0'}
     dev: true
 
-  /commander/2.20.3:
-    resolution: {integrity: 
sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
+  /estree-walker/0.6.1:
+    resolution: {integrity: 
sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==}
     dev: true
 
-  /commander/7.2.0:
-    resolution: {integrity: 
sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
-    engines: {node: '>= 10'}
+  /estree-walker/1.0.1:
+    resolution: {integrity: 
sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==}
     dev: true
 
-  /common-path-prefix/3.0.0:
-    resolution: {integrity: 
sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==}
+  /estree-walker/2.0.2:
+    resolution: {integrity: 
sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
     dev: true
 
-  /common-tags/1.8.2:
-    resolution: {integrity: 
sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==}
-    engines: {node: '>=4.0.0'}
+  /esutils/2.0.3:
+    resolution: {integrity: 
sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
+    engines: {node: '>=0.10.0'}
     dev: true
 
-  /commondir/1.0.1:
-    resolution: {integrity: 
sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==}
+  /etag/1.8.1:
+    resolution: {integrity: 
sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
+    engines: {node: '>= 0.6'}
     dev: true
 
-  /component-emitter/1.3.0:
-    resolution: {integrity: 
sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==}
+  /eventemitter3/4.0.7:
+    resolution: {integrity: 
sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==}
     dev: true
 
-  /compressible/2.0.18:
-    resolution: {integrity: 
sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==}
-    engines: {node: '>= 0.6'}
-    dependencies:
-      mime-db: 1.51.0
+  /events/3.3.0:
+    resolution: {integrity: 
sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
+    engines: {node: '>=0.8.x'}
     dev: true
 
-  /compression-webpack-plugin/6.1.1_webpack@4.46.0:
-    resolution: {integrity: 
sha512-BEHft9M6lwOqVIQFMS/YJGmeCYXVOakC5KzQk05TFpMBlODByh1qNsZCWjUBxCQhUP9x0WfGidxTbGkjbWO/TQ==}
-    engines: {node: '>= 10.13.0'}
-    peerDependencies:
-      webpack: ^4.0.0 || ^5.0.0
-    dependencies:
-      cacache: 15.3.0
-      find-cache-dir: 3.3.2
-      schema-utils: 3.1.1
-      serialize-javascript: 5.0.1
-      webpack: 4.46.0
-      webpack-sources: 1.4.3
-    transitivePeerDependencies:
-      - bluebird
+  /eventsource/2.0.2:
+    resolution: {integrity: 
sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==}
+    engines: {node: '>=12.0.0'}
     dev: true
 
-  /compression/1.7.4:
-    resolution: {integrity: 
sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==}
-    engines: {node: '>= 0.8.0'}
+  /evp_bytestokey/1.0.3:
+    resolution: {integrity: 
sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==}
     dependencies:
-      accepts: 1.3.8
-      bytes: 3.0.0
-      compressible: 2.0.18
-      debug: 2.6.9
-      on-headers: 1.0.2
-      safe-buffer: 5.1.2
-      vary: 1.1.2
-    transitivePeerDependencies:
-      - supports-color
+      md5.js: 1.3.5
+      safe-buffer: 5.2.1
     dev: true
 
-  /concat-map/0.0.1:
-    resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
+  /exec-sh/0.3.6:
+    resolution: {integrity: 
sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==}
+    dev: true
 
-  /concat-stream/1.6.2:
-    resolution: {integrity: 
sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==}
-    engines: {'0': node >= 0.8}
+  /execa/1.0.0:
+    resolution: {integrity: 
sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==}
+    engines: {node: '>=6'}
     dependencies:
-      buffer-from: 1.1.2
-      inherits: 2.0.4
-      readable-stream: 2.3.7
-      typedarray: 0.0.6
+      cross-spawn: 6.0.5
+      get-stream: 4.1.0
+      is-stream: 1.1.0
+      npm-run-path: 2.0.2
+      p-finally: 1.0.0
+      signal-exit: 3.0.7
+      strip-eof: 1.0.0
     dev: true
 
-  /concordance/5.0.4:
-    resolution: {integrity: 
sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==}
-    engines: {node: '>=10.18.0 <11 || >=12.14.0 <13 || >=14'}
+  /execa/4.1.0:
+    resolution: {integrity: 
sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==}
+    engines: {node: '>=10'}
     dependencies:
-      date-time: 3.1.0
-      esutils: 2.0.3
-      fast-diff: 1.2.0
-      js-string-escape: 1.0.1
-      lodash: 4.17.21
-      md5-hex: 3.0.1
-      semver: 7.3.8
-      well-known-symbols: 2.0.0
+      cross-spawn: 7.0.3
+      get-stream: 5.2.0
+      human-signals: 1.1.1
+      is-stream: 2.0.1
+      merge-stream: 2.0.0
+      npm-run-path: 4.0.1
+      onetime: 5.1.2
+      signal-exit: 3.0.7
+      strip-final-newline: 2.0.0
     dev: true
 
-  /configstore/5.0.1:
-    resolution: {integrity: 
sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==}
-    engines: {node: '>=8'}
+  /execa/5.1.1:
+    resolution: {integrity: 
sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
+    engines: {node: '>=10'}
     dependencies:
-      dot-prop: 5.3.0
-      graceful-fs: 4.2.9
-      make-dir: 3.1.0
-      unique-string: 2.0.0
-      write-file-atomic: 3.0.3
-      xdg-basedir: 4.0.0
+      cross-spawn: 7.0.3
+      get-stream: 6.0.1
+      human-signals: 2.1.0
+      is-stream: 2.0.1
+      merge-stream: 2.0.0
+      npm-run-path: 4.0.1
+      onetime: 5.1.2
+      signal-exit: 3.0.7
+      strip-final-newline: 2.0.0
     dev: true
 
-  /confusing-browser-globals/1.0.11:
-    resolution: {integrity: 
sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==}
+  /exit/0.1.2:
+    resolution: {integrity: 
sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==}
+    engines: {node: '>= 0.8.0'}
     dev: true
 
-  /connect-history-api-fallback/1.6.0:
-    resolution: {integrity: 
sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==}
-    engines: {node: '>=0.8'}
+  /expand-brackets/2.1.4:
+    resolution: {integrity: 
sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      debug: 2.6.9
+      define-property: 0.2.5
+      extend-shallow: 2.0.1
+      posix-character-classes: 0.1.1
+      regex-not: 1.0.2
+      snapdragon: 0.8.2
+      to-regex: 3.0.2
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /console-browserify/1.2.0:
-    resolution: {integrity: 
sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==}
+  /expand-brackets/2.1.4_supports-color@6.1.0:
+    resolution: {integrity: 
sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      debug: 2.6.9_supports-color@6.1.0
+      define-property: 0.2.5
+      extend-shallow: 2.0.1
+      posix-character-classes: 0.1.1
+      regex-not: 1.0.2
+      snapdragon: 0.8.2_supports-color@6.1.0
+      to-regex: 3.0.2
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /console-clear/1.1.1:
-    resolution: {integrity: 
sha512-pMD+MVR538ipqkG5JXeOEbKWS5um1H4LUUccUQG68qpeqBYbzYy79Gh55jkd2TtPdRfUaLWdv6LPP//5Zt0aPQ==}
-    engines: {node: '>=4'}
+  /expect/26.6.2:
+    resolution: {integrity: 
sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==}
+    engines: {node: '>= 10.14.2'}
+    dependencies:
+      '@jest/types': 26.6.2
+      ansi-styles: 4.3.0
+      jest-get-type: 26.3.0
+      jest-matcher-utils: 26.6.2
+      jest-message-util: 26.6.2
+      jest-regex-util: 26.0.0
     dev: true
 
-  /constants-browserify/1.0.0:
-    resolution: {integrity: sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=}
+  /expect/27.5.1:
+    resolution: {integrity: 
sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    dependencies:
+      '@jest/types': 27.5.1
+      jest-get-type: 27.5.1
+      jest-matcher-utils: 27.5.1
+      jest-message-util: 27.5.1
     dev: true
 
-  /content-disposition/0.5.4:
-    resolution: {integrity: 
sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==}
-    engines: {node: '>= 0.6'}
+  /express/4.17.2:
+    resolution: {integrity: 
sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg==}
+    engines: {node: '>= 0.10.0'}
     dependencies:
+      accepts: 1.3.8
+      array-flatten: 1.1.1
+      body-parser: 1.19.1
+      content-disposition: 0.5.4
+      content-type: 1.0.4
+      cookie: 0.4.1
+      cookie-signature: 1.0.6
+      debug: 2.6.9
+      depd: 1.1.2
+      encodeurl: 1.0.2
+      escape-html: 1.0.3
+      etag: 1.8.1
+      finalhandler: 1.1.2
+      fresh: 0.5.2
+      merge-descriptors: 1.0.1
+      methods: 1.1.2
+      on-finished: 2.3.0
+      parseurl: 1.3.3
+      path-to-regexp: 0.1.7
+      proxy-addr: 2.0.7
+      qs: 6.9.6
+      range-parser: 1.2.1
       safe-buffer: 5.2.1
+      send: 0.17.2
+      serve-static: 1.14.2
+      setprototypeof: 1.2.0
+      statuses: 1.5.0
+      type-is: 1.6.18
+      utils-merge: 1.0.1
+      vary: 1.1.2
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /content-type/1.0.4:
-    resolution: {integrity: 
sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==}
-    engines: {node: '>= 0.6'}
-    dev: true
-
-  /convert-source-map/1.8.0:
-    resolution: {integrity: 
sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==}
+  /express/4.17.2_supports-color@6.1.0:
+    resolution: {integrity: 
sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg==}
+    engines: {node: '>= 0.10.0'}
     dependencies:
-      safe-buffer: 5.1.2
-    dev: true
-
-  /convert-to-spaces/2.0.1:
-    resolution: {integrity: 
sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==}
-    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
-    dev: true
-
-  /cookie-signature/1.0.6:
-    resolution: {integrity: sha1-4wOogrNCzD7oylE6eZmXNNqzriw=}
+      accepts: 1.3.8
+      array-flatten: 1.1.1
+      body-parser: 1.19.1_supports-color@6.1.0
+      content-disposition: 0.5.4
+      content-type: 1.0.4
+      cookie: 0.4.1
+      cookie-signature: 1.0.6
+      debug: 2.6.9_supports-color@6.1.0
+      depd: 1.1.2
+      encodeurl: 1.0.2
+      escape-html: 1.0.3
+      etag: 1.8.1
+      finalhandler: 1.1.2_supports-color@6.1.0
+      fresh: 0.5.2
+      merge-descriptors: 1.0.1
+      methods: 1.1.2
+      on-finished: 2.3.0
+      parseurl: 1.3.3
+      path-to-regexp: 0.1.7
+      proxy-addr: 2.0.7
+      qs: 6.9.6
+      range-parser: 1.2.1
+      safe-buffer: 5.2.1
+      send: 0.17.2_supports-color@6.1.0
+      serve-static: 1.14.2_supports-color@6.1.0
+      setprototypeof: 1.2.0
+      statuses: 1.5.0
+      type-is: 1.6.18
+      utils-merge: 1.0.1
+      vary: 1.1.2
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /cookie/0.4.1:
-    resolution: {integrity: 
sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==}
-    engines: {node: '>= 0.6'}
+  /extend-shallow/2.0.1:
+    resolution: {integrity: 
sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      is-extendable: 0.1.1
     dev: true
 
-  /copy-concurrently/1.0.5:
-    resolution: {integrity: 
sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==}
+  /extend-shallow/3.0.2:
+    resolution: {integrity: 
sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==}
+    engines: {node: '>=0.10.0'}
     dependencies:
-      aproba: 1.2.0
-      fs-write-stream-atomic: 1.0.10
-      iferr: 0.1.5
-      mkdirp: 0.5.5
-      rimraf: 2.7.1
-      run-queue: 1.0.3
+      assign-symbols: 1.0.0
+      is-extendable: 1.0.1
     dev: true
 
-  /copy-descriptor/0.1.1:
-    resolution: {integrity: sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=}
-    engines: {node: '>=0.10.0'}
+  /extend/3.0.2:
+    resolution: {integrity: 
sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
     dev: true
 
-  /copy-webpack-plugin/6.4.1_webpack@4.46.0:
-    resolution: {integrity: 
sha512-MXyPCjdPVx5iiWyl40Va3JGh27bKzOTNY3NjUTrosD2q7dR/cLD0013uqJ3BpFbUjyONINjb6qI7nDIJujrMbA==}
-    engines: {node: '>= 10.13.0'}
-    peerDependencies:
-      webpack: ^4.37.0 || ^5.0.0
+  /extglob/2.0.4:
+    resolution: {integrity: 
sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==}
+    engines: {node: '>=0.10.0'}
     dependencies:
-      cacache: 15.3.0
-      fast-glob: 3.2.11
-      find-cache-dir: 3.3.2
-      glob-parent: 5.1.2
-      globby: 11.1.0
-      loader-utils: 2.0.2
-      normalize-path: 3.0.0
-      p-limit: 3.1.0
-      schema-utils: 3.1.1
-      serialize-javascript: 5.0.1
-      webpack: 4.46.0
-      webpack-sources: 1.4.3
+      array-unique: 0.3.2
+      define-property: 1.0.0
+      expand-brackets: 2.1.4
+      extend-shallow: 2.0.1
+      fragment-cache: 0.2.1
+      regex-not: 1.0.2
+      snapdragon: 0.8.2
+      to-regex: 3.0.2
     transitivePeerDependencies:
-      - bluebird
+      - supports-color
     dev: true
 
-  /core-js-compat/3.21.0:
-    resolution: {integrity: 
sha512-OSXseNPSK2OPJa6GdtkMz/XxeXx8/CJvfhQWTqd6neuUraujcL4jVsjkLQz1OWnax8xVQJnRPe0V2jqNWORA+A==}
+  /extglob/2.0.4_supports-color@6.1.0:
+    resolution: {integrity: 
sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==}
+    engines: {node: '>=0.10.0'}
     dependencies:
-      browserslist: 4.19.1
-      semver: 7.0.0
+      array-unique: 0.3.2
+      define-property: 1.0.0
+      expand-brackets: 2.1.4_supports-color@6.1.0
+      extend-shallow: 2.0.1
+      fragment-cache: 0.2.1
+      regex-not: 1.0.2
+      snapdragon: 0.8.2_supports-color@6.1.0
+      to-regex: 3.0.2
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /core-js-pure/3.20.2:
-    resolution: {integrity: 
sha512-CmWHvSKn2vNL6p6StNp1EmMIfVY/pqn3JLAjfZQ8WZGPOlGoO92EkX9/Mk81i6GxvoPXjUqEQnpM3rJ5QxxIOg==}
-    requiresBuild: true
+  /extsprintf/1.3.0:
+    resolution: {integrity: 
sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==}
+    engines: {'0': node >=0.6.0}
     dev: true
 
-  /core-js/2.6.12:
-    resolution: {integrity: 
sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==}
-    deprecated: core-js@<3.4 is no longer maintained and not recommended for 
usage due to the number of issues. Because of the V8 engine whims, feature 
detection in old core-js versions could cause a slowdown up to 100x even if 
nothing is polyfilled. Please, upgrade your dependencies to the actual version 
of core-js.
-    requiresBuild: true
+  /fast-async/6.3.8:
+    resolution: {integrity: 
sha512-TjlooyqrYm/gOXjD2UHNwfrWkvTbzU105Nk4bvcRTeRoL+wIeK6rqbqDg3CN9z5p37cE2iXhP6SxQFz8OVIaUg==}
+    dependencies:
+      nodent-compiler: 3.2.13
+      nodent-runtime: 3.2.1
     dev: true
 
-  /core-util-is/1.0.2:
-    resolution: {integrity: sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=}
-    dev: true
+  /fast-deep-equal/3.1.3:
+    resolution: {integrity: 
sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
 
-  /core-util-is/1.0.3:
-    resolution: {integrity: 
sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
+  /fast-diff/1.2.0:
+    resolution: {integrity: 
sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==}
     dev: true
 
-  /cosmiconfig/5.2.1:
-    resolution: {integrity: 
sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==}
-    engines: {node: '>=4'}
+  /fast-glob/2.2.7:
+    resolution: {integrity: 
sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==}
+    engines: {node: '>=4.0.0'}
     dependencies:
-      import-fresh: 2.0.0
-      is-directory: 0.3.1
-      js-yaml: 3.14.1
-      parse-json: 4.0.0
+      '@mrmlnc/readdir-enhanced': 2.2.1
+      '@nodelib/fs.stat': 1.1.3
+      glob-parent: 3.1.0
+      is-glob: 4.0.3
+      merge2: 1.4.1
+      micromatch: 3.1.10
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /cosmiconfig/7.0.1:
-    resolution: {integrity: 
sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==}
-    engines: {node: '>=10'}
+  /fast-glob/3.2.11:
+    resolution: {integrity: 
sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==}
+    engines: {node: '>=8.6.0'}
     dependencies:
-      '@types/parse-json': 4.0.0
-      import-fresh: 3.3.0
-      parse-json: 5.2.0
-      path-type: 4.0.0
-      yaml: 1.10.2
+      '@nodelib/fs.stat': 2.0.5
+      '@nodelib/fs.walk': 1.2.8
+      glob-parent: 5.1.2
+      merge2: 1.4.1
+      micromatch: 4.0.5
     dev: true
 
-  /create-ecdh/4.0.4:
-    resolution: {integrity: 
sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==}
+  /fast-glob/3.2.12:
+    resolution: {integrity: 
sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==}
+    engines: {node: '>=8.6.0'}
     dependencies:
-      bn.js: 4.12.0
-      elliptic: 6.5.4
+      '@nodelib/fs.stat': 2.0.5
+      '@nodelib/fs.walk': 1.2.8
+      glob-parent: 5.1.2
+      merge2: 1.4.1
+      micromatch: 4.0.5
     dev: true
 
-  /create-hash/1.2.0:
-    resolution: {integrity: 
sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==}
-    dependencies:
-      cipher-base: 1.0.4
-      inherits: 2.0.4
-      md5.js: 1.3.5
-      ripemd160: 2.0.2
-      sha.js: 2.4.11
+  /fast-json-stable-stringify/2.1.0:
+    resolution: {integrity: 
sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
+
+  /fast-levenshtein/2.0.6:
+    resolution: {integrity: sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=}
     dev: true
 
-  /create-hmac/1.1.7:
-    resolution: {integrity: 
sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==}
+  /fastq/1.13.0:
+    resolution: {integrity: 
sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==}
     dependencies:
-      cipher-base: 1.0.4
-      create-hash: 1.2.0
-      inherits: 2.0.4
-      ripemd160: 2.0.2
-      safe-buffer: 5.2.1
-      sha.js: 2.4.11
+      reusify: 1.0.4
     dev: true
 
-  /critters-webpack-plugin/2.5.0_html-webpack-plugin@3.2.0:
-    resolution: {integrity: 
sha512-O41TSPV2orAfrV6kSVC0SivZCtVkeypCNKb7xtrbqE/CfjrHeRaFaGuxglcjOI2IGf+oNg6E+ZoOktdlhXPTIQ==}
-    peerDependencies:
-      html-webpack-plugin: '*'
-    peerDependenciesMeta:
-      html-webpack-plugin:
-        optional: true
+  /fault/1.0.4:
+    resolution: {integrity: 
sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==}
     dependencies:
-      css: 2.2.4
-      cssnano: 4.1.11
-      html-webpack-plugin: 3.2.0_webpack@4.46.0
-      jsdom: 12.2.0
-      minimatch: 3.0.5
-      parse5: 4.0.0
-      postcss: 7.0.39
-      pretty-bytes: 4.0.2
-      webpack-log: 2.0.0
-      webpack-sources: 1.4.3
-    transitivePeerDependencies:
-      - bufferutil
-      - utf-8-validate
+      format: 0.2.2
     dev: true
 
-  /cross-spawn-promise/0.10.2:
-    resolution: {integrity: 
sha512-74PXJf6DYaab2klRS+D+9qxKJL1Weo3/ao9OPoH6NFzxtINSa/HE2mcyAPu1fpEmRTPD4Gdmpg3xEXQSgI8lpg==}
-    engines: {node: '>=4'}
+  /faye-websocket/0.11.4:
+    resolution: {integrity: 
sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==}
+    engines: {node: '>=0.8.0'}
     dependencies:
-      cross-spawn: 5.1.0
+      websocket-driver: 0.7.4
     dev: true
 
-  /cross-spawn/5.1.0:
-    resolution: {integrity: sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=}
+  /fb-watchman/2.0.2:
+    resolution: {integrity: 
sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==}
     dependencies:
-      lru-cache: 4.1.5
-      shebang-command: 1.2.0
-      which: 1.3.1
+      bser: 2.1.1
     dev: true
 
-  /cross-spawn/7.0.3:
-    resolution: {integrity: 
sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
-    engines: {node: '>= 8'}
+  /fetch-blob/3.1.4:
+    resolution: {integrity: 
sha512-Eq5Xv5+VlSrYWEqKrusxY1C3Hm/hjeAsCGVG3ft7pZahlUAChpGZT/Ms1WmSLnEAisEXszjzu/s+ce6HZB2VHA==}
+    engines: {node: ^12.20 || >= 14.13}
     dependencies:
-      path-key: 3.1.1
-      shebang-command: 2.0.0
-      which: 2.0.2
-    dev: true
+      node-domexception: 1.0.0
+      web-streams-polyfill: 3.2.0
+    dev: false
 
-  /crypto-browserify/3.12.0:
-    resolution: {integrity: 
sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==}
+  /fetch-ponyfill/7.1.0:
+    resolution: {integrity: 
sha512-FhbbL55dj/qdVO3YNK7ZEkshvj3eQ7EuIGV2I6ic/2YiocvyWv+7jg2s4AyS0wdRU75s3tA8ZxI/xPigb0v5Aw==}
     dependencies:
-      browserify-cipher: 1.0.1
-      browserify-sign: 4.2.1
-      create-ecdh: 4.0.4
-      create-hash: 1.2.0
-      create-hmac: 1.1.7
-      diffie-hellman: 5.0.3
-      inherits: 2.0.4
-      pbkdf2: 3.1.2
-      public-encrypt: 4.0.3
-      randombytes: 2.1.0
-      randomfill: 1.0.4
+      node-fetch: 2.6.7
+    transitivePeerDependencies:
+      - encoding
+    dev: false
+
+  /fetch-retry/5.0.3:
+    resolution: {integrity: 
sha512-uJQyMrX5IJZkhoEUBQ3EjxkeiZkppBd5jS/fMTJmfZxLSiaQjv2zD0kTvuvkSH89uFvgSlB6ueGpjD3HWN7Bxw==}
     dev: true
 
-  /crypto-random-string/2.0.0:
-    resolution: {integrity: 
sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==}
-    engines: {node: '>=8'}
+  /fflate/0.7.4:
+    resolution: {integrity: 
sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==}
+    dev: false
+
+  /figgy-pudding/3.5.2:
+    resolution: {integrity: 
sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==}
     dev: true
 
-  /css-color-names/0.0.4:
-    resolution: {integrity: sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=}
+  /figures/4.0.1:
+    resolution: {integrity: 
sha512-rElJwkA/xS04Vfg+CaZodpso7VqBknOYbzi6I76hI4X80RUjkSxO2oAyPmGbuXUppywjqndOrQDl817hDnI++w==}
+    engines: {node: '>=12'}
+    dependencies:
+      escape-string-regexp: 5.0.0
+      is-unicode-supported: 1.3.0
     dev: true
 
-  /css-declaration-sorter/4.0.1:
-    resolution: {integrity: 
sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==}
-    engines: {node: '>4'}
+  /file-entry-cache/6.0.1:
+    resolution: {integrity: 
sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
+    engines: {node: ^10.12.0 || >=12.0.0}
     dependencies:
-      postcss: 7.0.39
-      timsort: 0.3.0
+      flat-cache: 3.0.4
     dev: true
 
-  /css-declaration-sorter/6.1.4_postcss@8.4.6:
-    resolution: {integrity: 
sha512-lpfkqS0fctcmZotJGhnxkIyJWvBXgpyi2wsFd4J8VB7wzyrT6Ch/3Q+FMNJpjK4gu1+GN5khOnpU2ZVKrLbhCw==}
-    engines: {node: '>= 10'}
+  /file-loader/1.1.11:
+    resolution: {integrity: 
sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg==}
+    engines: {node: '>= 4.3 < 5.0.0 || >= 5.10'}
     peerDependencies:
-      postcss: ^8.0.9
+      webpack: ^2.0.0 || ^3.0.0 || ^4.0.0
     dependencies:
-      postcss: 8.4.6
-      timsort: 0.3.0
-    dev: true
+      loader-utils: 1.4.0
+      schema-utils: 0.4.7
 
-  /css-loader/5.2.7_webpack@4.46.0:
-    resolution: {integrity: 
sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg==}
+  /file-loader/6.2.0_webpack@4.46.0:
+    resolution: {integrity: 
sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==}
     engines: {node: '>= 10.13.0'}
     peerDependencies:
-      webpack: ^4.27.0 || ^5.0.0
+      webpack: ^4.0.0 || ^5.0.0
     dependencies:
-      icss-utils: 5.1.0_postcss@8.4.6
       loader-utils: 2.0.2
-      postcss: 8.4.6
-      postcss-modules-extract-imports: 3.0.0_postcss@8.4.6
-      postcss-modules-local-by-default: 4.0.0_postcss@8.4.6
-      postcss-modules-scope: 3.0.0_postcss@8.4.6
-      postcss-modules-values: 4.0.0_postcss@8.4.6
-      postcss-value-parser: 4.2.0
       schema-utils: 3.1.1
-      semver: 7.3.5
       webpack: 4.46.0
     dev: true
 
-  /css-select-base-adapter/0.1.1:
-    resolution: {integrity: 
sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==}
-    dev: true
-
-  /css-select/2.1.0:
-    resolution: {integrity: 
sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==}
+  /file-system-cache/1.1.0:
+    resolution: {integrity: 
sha512-IzF5MBq+5CR0jXx5RxPe4BICl/oEhBSXKaL9fLhAXrIfIUS77Hr4vzrYyqYMHN6uTt+BOqi3fDCTjjEBCjERKw==}
     dependencies:
-      boolbase: 1.0.0
-      css-what: 3.4.2
-      domutils: 1.7.0
-      nth-check: 1.0.2
+      fs-extra: 10.1.0
+      ramda: 0.28.0
     dev: true
 
-  /css-select/4.2.1:
-    resolution: {integrity: 
sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==}
-    dependencies:
-      boolbase: 1.0.0
-      css-what: 5.1.0
-      domhandler: 4.3.0
-      domutils: 2.8.0
-      nth-check: 2.0.1
+  /file-uri-to-path/1.0.0:
+    resolution: {integrity: 
sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /css-tree/1.0.0-alpha.37:
-    resolution: {integrity: 
sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==}
-    engines: {node: '>=8.0.0'}
+  /filelist/1.0.2:
+    resolution: {integrity: 
sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==}
     dependencies:
-      mdn-data: 2.0.4
-      source-map: 0.6.1
+      minimatch: 3.1.2
     dev: true
 
-  /css-tree/1.1.3:
-    resolution: {integrity: 
sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==}
-    engines: {node: '>=8.0.0'}
-    dependencies:
-      mdn-data: 2.0.14
-      source-map: 0.6.1
+  /filesize/3.6.1:
+    resolution: {integrity: 
sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==}
+    engines: {node: '>= 0.4.0'}
     dev: true
 
-  /css-what/3.4.2:
-    resolution: {integrity: 
sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==}
-    engines: {node: '>= 6'}
+  /filesize/6.1.0:
+    resolution: {integrity: 
sha512-LpCHtPQ3sFx67z+uh2HnSyWSLLu5Jxo21795uRDuar/EOuYWXib5EmPaGIBuSnRqH2IODiKA2k5re/K9OnN/Yg==}
+    engines: {node: '>= 0.4.0'}
     dev: true
 
-  /css-what/5.1.0:
-    resolution: {integrity: 
sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==}
-    engines: {node: '>= 6'}
+  /fill-range/4.0.0:
+    resolution: {integrity: 
sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      extend-shallow: 2.0.1
+      is-number: 3.0.0
+      repeat-string: 1.6.1
+      to-regex-range: 2.1.1
     dev: true
 
-  /css/2.2.4:
-    resolution: {integrity: 
sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==}
+  /fill-range/7.0.1:
+    resolution: {integrity: 
sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
+    engines: {node: '>=8'}
     dependencies:
-      inherits: 2.0.4
-      source-map: 0.6.1
-      source-map-resolve: 0.5.3
-      urix: 0.1.0
+      to-regex-range: 5.0.1
     dev: true
 
-  /cssesc/3.0.0:
-    resolution: {integrity: 
sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
-    engines: {node: '>=4'}
-    hasBin: true
+  /finalhandler/1.1.2:
+    resolution: {integrity: 
sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==}
+    engines: {node: '>= 0.8'}
+    dependencies:
+      debug: 2.6.9
+      encodeurl: 1.0.2
+      escape-html: 1.0.3
+      on-finished: 2.3.0
+      parseurl: 1.3.3
+      statuses: 1.5.0
+      unpipe: 1.0.0
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /cssnano-preset-default/4.0.8:
-    resolution: {integrity: 
sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==}
-    engines: {node: '>=6.9.0'}
+  /finalhandler/1.1.2_supports-color@6.1.0:
+    resolution: {integrity: 
sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==}
+    engines: {node: '>= 0.8'}
     dependencies:
-      css-declaration-sorter: 4.0.1
-      cssnano-util-raw-cache: 4.0.1
-      postcss: 7.0.39
-      postcss-calc: 7.0.5
-      postcss-colormin: 4.0.3
-      postcss-convert-values: 4.0.1
-      postcss-discard-comments: 4.0.2
-      postcss-discard-duplicates: 4.0.2
-      postcss-discard-empty: 4.0.1
-      postcss-discard-overridden: 4.0.1
-      postcss-merge-longhand: 4.0.11
-      postcss-merge-rules: 4.0.3
-      postcss-minify-font-values: 4.0.2
-      postcss-minify-gradients: 4.0.2
-      postcss-minify-params: 4.0.2
-      postcss-minify-selectors: 4.0.2
-      postcss-normalize-charset: 4.0.1
-      postcss-normalize-display-values: 4.0.2
-      postcss-normalize-positions: 4.0.2
-      postcss-normalize-repeat-style: 4.0.2
-      postcss-normalize-string: 4.0.2
-      postcss-normalize-timing-functions: 4.0.2
-      postcss-normalize-unicode: 4.0.1
-      postcss-normalize-url: 4.0.1
-      postcss-normalize-whitespace: 4.0.2
-      postcss-ordered-values: 4.1.2
-      postcss-reduce-initial: 4.0.3
-      postcss-reduce-transforms: 4.0.2
-      postcss-svgo: 4.0.3
-      postcss-unique-selectors: 4.0.1
+      debug: 2.6.9_supports-color@6.1.0
+      encodeurl: 1.0.2
+      escape-html: 1.0.3
+      on-finished: 2.3.0
+      parseurl: 1.3.3
+      statuses: 1.5.0
+      unpipe: 1.0.0
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /cssnano-preset-default/5.1.12_postcss@8.4.6:
-    resolution: {integrity: 
sha512-rO/JZYyjW1QNkWBxMGV28DW7d98UDLaF759frhli58QFehZ+D/LSmwQ2z/ylBAe2hUlsIWTq6NYGfQPq65EF9w==}
-    engines: {node: ^10 || ^12 || >=14.0}
-    peerDependencies:
-      postcss: ^8.2.15
+  /find-cache-dir/2.1.0:
+    resolution: {integrity: 
sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==}
+    engines: {node: '>=6'}
     dependencies:
-      css-declaration-sorter: 6.1.4_postcss@8.4.6
-      cssnano-utils: 3.0.2_postcss@8.4.6
-      postcss: 8.4.6
-      postcss-calc: 8.2.4_postcss@8.4.6
-      postcss-colormin: 5.2.5_postcss@8.4.6
-      postcss-convert-values: 5.0.4_postcss@8.4.6
-      postcss-discard-comments: 5.0.3_postcss@8.4.6
-      postcss-discard-duplicates: 5.0.3_postcss@8.4.6
-      postcss-discard-empty: 5.0.3_postcss@8.4.6
-      postcss-discard-overridden: 5.0.4_postcss@8.4.6
-      postcss-merge-longhand: 5.0.6_postcss@8.4.6
-      postcss-merge-rules: 5.0.6_postcss@8.4.6
-      postcss-minify-font-values: 5.0.4_postcss@8.4.6
-      postcss-minify-gradients: 5.0.6_postcss@8.4.6
-      postcss-minify-params: 5.0.5_postcss@8.4.6
-      postcss-minify-selectors: 5.1.3_postcss@8.4.6
-      postcss-normalize-charset: 5.0.3_postcss@8.4.6
-      postcss-normalize-display-values: 5.0.3_postcss@8.4.6
-      postcss-normalize-positions: 5.0.4_postcss@8.4.6
-      postcss-normalize-repeat-style: 5.0.4_postcss@8.4.6
-      postcss-normalize-string: 5.0.4_postcss@8.4.6
-      postcss-normalize-timing-functions: 5.0.3_postcss@8.4.6
-      postcss-normalize-unicode: 5.0.4_postcss@8.4.6
-      postcss-normalize-url: 5.0.5_postcss@8.4.6
-      postcss-normalize-whitespace: 5.0.4_postcss@8.4.6
-      postcss-ordered-values: 5.0.5_postcss@8.4.6
-      postcss-reduce-initial: 5.0.3_postcss@8.4.6
-      postcss-reduce-transforms: 5.0.4_postcss@8.4.6
-      postcss-svgo: 5.0.4_postcss@8.4.6
-      postcss-unique-selectors: 5.0.4_postcss@8.4.6
+      commondir: 1.0.1
+      make-dir: 2.1.0
+      pkg-dir: 3.0.0
     dev: true
 
-  /cssnano-util-get-arguments/4.0.0:
-    resolution: {integrity: sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=}
-    engines: {node: '>=6.9.0'}
+  /find-cache-dir/3.3.2:
+    resolution: {integrity: 
sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==}
+    engines: {node: '>=8'}
+    dependencies:
+      commondir: 1.0.1
+      make-dir: 3.1.0
+      pkg-dir: 4.2.0
     dev: true
 
-  /cssnano-util-get-match/4.0.0:
-    resolution: {integrity: sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=}
-    engines: {node: '>=6.9.0'}
+  /find-root/1.1.0:
+    resolution: {integrity: 
sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==}
     dev: true
 
-  /cssnano-util-raw-cache/4.0.1:
-    resolution: {integrity: 
sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==}
-    engines: {node: '>=6.9.0'}
+  /find-up/1.1.2:
+    resolution: {integrity: 
sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==}
+    engines: {node: '>=0.10.0'}
     dependencies:
-      postcss: 7.0.39
-    dev: true
-
-  /cssnano-util-same-parent/4.0.1:
-    resolution: {integrity: 
sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==}
-    engines: {node: '>=6.9.0'}
+      path-exists: 2.1.0
+      pinkie-promise: 2.0.1
     dev: true
+    optional: true
 
-  /cssnano-utils/3.0.2_postcss@8.4.6:
-    resolution: {integrity: 
sha512-KhprijuQv2sP4kT92sSQwhlK3SJTbDIsxcfIEySB0O+3m9esFOai7dP9bMx5enHAh2MwarVIcnwiWoOm01RIbQ==}
-    engines: {node: ^10 || ^12 || >=14.0}
-    peerDependencies:
-      postcss: ^8.2.15
+  /find-up/2.1.0:
+    resolution: {integrity: sha1-RdG35QbHF93UgndaK3eSCjwMV6c=}
+    engines: {node: '>=4'}
     dependencies:
-      postcss: 8.4.6
+      locate-path: 2.0.0
     dev: true
 
-  /cssnano/4.1.11:
-    resolution: {integrity: 
sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==}
-    engines: {node: '>=6.9.0'}
+  /find-up/3.0.0:
+    resolution: {integrity: 
sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==}
+    engines: {node: '>=6'}
     dependencies:
-      cosmiconfig: 5.2.1
-      cssnano-preset-default: 4.0.8
-      is-resolvable: 1.1.0
-      postcss: 7.0.39
+      locate-path: 3.0.0
     dev: true
 
-  /cssnano/5.0.17_postcss@8.4.6:
-    resolution: {integrity: 
sha512-fmjLP7k8kL18xSspeXTzRhaFtRI7DL9b8IcXR80JgtnWBpvAzHT7sCR/6qdn0tnxIaINUN6OEQu83wF57Gs3Xw==}
-    engines: {node: ^10 || ^12 || >=14.0}
-    peerDependencies:
-      postcss: ^8.2.15
+  /find-up/4.1.0:
+    resolution: {integrity: 
sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
+    engines: {node: '>=8'}
     dependencies:
-      cssnano-preset-default: 5.1.12_postcss@8.4.6
-      lilconfig: 2.0.4
-      postcss: 8.4.6
-      yaml: 1.10.2
+      locate-path: 5.0.0
+      path-exists: 4.0.0
     dev: true
 
-  /csso/4.2.0:
-    resolution: {integrity: 
sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==}
-    engines: {node: '>=8.0.0'}
+  /find-up/5.0.0:
+    resolution: {integrity: 
sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
+    engines: {node: '>=10'}
     dependencies:
-      css-tree: 1.1.3
+      locate-path: 6.0.0
+      path-exists: 4.0.0
     dev: true
 
-  /cssom/0.3.8:
-    resolution: {integrity: 
sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==}
+  /find-up/6.3.0:
+    resolution: {integrity: 
sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==}
+    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+    dependencies:
+      locate-path: 7.1.1
+      path-exists: 5.0.0
     dev: true
 
-  /cssstyle/1.4.0:
-    resolution: {integrity: 
sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==}
+  /find-yarn-workspace-root/1.2.1:
+    resolution: {integrity: 
sha512-dVtfb0WuQG+8Ag2uWkbG79hOUzEsRrhBzgfn86g2sJPkzmcpGdghbNTfUKGTxymFrY/tLIodDzLoW9nOJ4FY8Q==}
     dependencies:
-      cssom: 0.3.8
+      fs-extra: 4.0.3
+      micromatch: 3.1.10
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /currently-unhandled/0.4.1:
-    resolution: {integrity: 
sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==}
-    engines: {node: '>=0.10.0'}
+  /flat-cache/3.0.4:
+    resolution: {integrity: 
sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==}
+    engines: {node: ^10.12.0 || >=12.0.0}
     dependencies:
-      array-find-index: 1.0.2
+      flatted: 3.2.5
+      rimraf: 3.0.2
     dev: true
 
-  /cyclist/1.0.1:
-    resolution: {integrity: sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=}
+  /flat/5.0.2:
+    resolution: {integrity: 
sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==}
+    hasBin: true
     dev: true
 
-  /damerau-levenshtein/1.0.7:
-    resolution: {integrity: 
sha512-VvdQIPGdWP0SqFXghj79Wf/5LArmreyMsGLa6FG6iC4t3j7j5s71TrwWmT/4akbDQIqjfACkLZmjXhA7g2oUZw==}
+  /flatted/3.2.5:
+    resolution: {integrity: 
sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==}
     dev: true
 
-  /dashdash/1.14.1:
-    resolution: {integrity: sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=}
-    engines: {node: '>=0.10'}
+  /flush-write-stream/1.1.1:
+    resolution: {integrity: 
sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==}
     dependencies:
-      assert-plus: 1.0.0
+      inherits: 2.0.4
+      readable-stream: 2.3.7
     dev: true
 
-  /data-uri-to-buffer/4.0.0:
-    resolution: {integrity: 
sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==}
-    engines: {node: '>= 12'}
-    dev: false
+  /follow-redirects/1.15.2:
+    resolution: {integrity: 
sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
+    engines: {node: '>=4.0'}
+    peerDependencies:
+      debug: '*'
+    peerDependenciesMeta:
+      debug:
+        optional: true
 
-  /data-urls/1.1.0:
-    resolution: {integrity: 
sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==}
+  /for-each/0.3.3:
+    resolution: {integrity: 
sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
     dependencies:
-      abab: 2.0.5
-      whatwg-mimetype: 2.3.0
-      whatwg-url: 7.1.0
+      is-callable: 1.2.7
     dev: true
 
-  /date-fns/2.29.2:
-    resolution: {integrity: 
sha512-0VNbwmWJDS/G3ySwFSJA3ayhbURMTJLtwM2DTxf9CWondCnh6DTNlO9JgRSq6ibf4eD0lfMJNBxUdEAHHix+bA==}
-    engines: {node: '>=0.11'}
-    dev: false
+  /for-in/1.0.2:
+    resolution: {integrity: 
sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==}
+    engines: {node: '>=0.10.0'}
+    dev: true
 
-  /date-time/3.1.0:
-    resolution: {integrity: 
sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==}
-    engines: {node: '>=6'}
+  /foreground-child/2.0.0:
+    resolution: {integrity: 
sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==}
+    engines: {node: '>=8.0.0'}
     dependencies:
-      time-zone: 1.0.0
+      cross-spawn: 7.0.3
+      signal-exit: 3.0.6
     dev: true
 
-  /debug/2.6.9:
-    resolution: {integrity: 
sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
+  /forever-agent/0.6.1:
+    resolution: {integrity: 
sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==}
+    dev: true
+
+  /fork-ts-checker-webpack-plugin/4.1.6_3awoqomffoooecyduzzbrfpye4:
+    resolution: {integrity: 
sha512-DUxuQaKoqfNne8iikd14SAkh5uw4+8vNifp6gmA73yYNS6ywLIWSLD/n/mBzHQRpW3J7rbATEakmiA8JvkTyZw==}
+    engines: {node: '>=6.11.5', yarn: '>=1.0.0'}
     peerDependencies:
-      supports-color: '*'
+      eslint: '>= 6'
+      typescript: '>= 2.7'
+      vue-template-compiler: '*'
+      webpack: '>= 4'
     peerDependenciesMeta:
-      supports-color:
+      eslint:
+        optional: true
+      vue-template-compiler:
         optional: true
     dependencies:
-      ms: 2.0.0
+      '@babel/code-frame': 7.16.7
+      chalk: 2.4.2
+      eslint: 8.8.0
+      micromatch: 3.1.10
+      minimatch: 3.1.2
+      semver: 5.7.1
+      tapable: 1.1.3
+      typescript: 3.9.10
+      webpack: 4.46.0
+      worker-rpc: 0.1.1
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /debug/3.2.7:
-    resolution: {integrity: 
sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
+  /fork-ts-checker-webpack-plugin/4.1.6_3n2x3j6farblcaf52bherr6og4:
+    resolution: {integrity: 
sha512-DUxuQaKoqfNne8iikd14SAkh5uw4+8vNifp6gmA73yYNS6ywLIWSLD/n/mBzHQRpW3J7rbATEakmiA8JvkTyZw==}
+    engines: {node: '>=6.11.5', yarn: '>=1.0.0'}
     peerDependencies:
-      supports-color: '*'
+      eslint: '>= 6'
+      typescript: '>= 2.7'
+      vue-template-compiler: '*'
+      webpack: '>= 4'
     peerDependenciesMeta:
-      supports-color:
+      eslint:
+        optional: true
+      vue-template-compiler:
         optional: true
     dependencies:
-      ms: 2.1.3
+      '@babel/code-frame': 7.16.7
+      chalk: 2.4.2
+      eslint: 7.32.0
+      micromatch: 3.1.10
+      minimatch: 3.1.2
+      semver: 5.7.1
+      tapable: 1.1.3
+      typescript: 4.8.4
+      webpack: 4.46.0
+      worker-rpc: 0.1.1
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /debug/4.3.2:
-    resolution: {integrity: 
sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==}
-    engines: {node: '>=6.0'}
+  /fork-ts-checker-webpack-plugin/4.1.6_e7hrjdrs22zc4syxbltzlwluhe:
+    resolution: {integrity: 
sha512-DUxuQaKoqfNne8iikd14SAkh5uw4+8vNifp6gmA73yYNS6ywLIWSLD/n/mBzHQRpW3J7rbATEakmiA8JvkTyZw==}
+    engines: {node: '>=6.11.5', yarn: '>=1.0.0'}
     peerDependencies:
-      supports-color: '*'
+      eslint: '>= 6'
+      typescript: '>= 2.7'
+      vue-template-compiler: '*'
+      webpack: '>= 4'
     peerDependenciesMeta:
-      supports-color:
+      eslint:
+        optional: true
+      vue-template-compiler:
         optional: true
     dependencies:
-      ms: 2.1.2
+      '@babel/code-frame': 7.16.7
+      chalk: 2.4.2
+      micromatch: 3.1.10
+      minimatch: 3.1.2
+      semver: 5.7.1
+      tapable: 1.1.3
+      typescript: 4.2.4
+      webpack: 4.46.0
+      worker-rpc: 0.1.1
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /debug/4.3.3:
-    resolution: {integrity: 
sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==}
-    engines: {node: '>=6.0'}
+  /fork-ts-checker-webpack-plugin/4.1.6_ef2lra3u3fsnrdrpybbvbgzate:
+    resolution: {integrity: 
sha512-DUxuQaKoqfNne8iikd14SAkh5uw4+8vNifp6gmA73yYNS6ywLIWSLD/n/mBzHQRpW3J7rbATEakmiA8JvkTyZw==}
+    engines: {node: '>=6.11.5', yarn: '>=1.0.0'}
     peerDependencies:
-      supports-color: '*'
+      eslint: '>= 6'
+      typescript: '>= 2.7'
+      vue-template-compiler: '*'
+      webpack: '>= 4'
     peerDependenciesMeta:
-      supports-color:
+      eslint:
+        optional: true
+      vue-template-compiler:
         optional: true
     dependencies:
-      ms: 2.1.2
+      '@babel/code-frame': 7.16.7
+      chalk: 2.4.2
+      eslint: 8.8.0
+      micromatch: 3.1.10
+      minimatch: 3.1.2
+      semver: 5.7.1
+      tapable: 1.1.3
+      typescript: 4.8.4
+      webpack: 4.46.0
+      worker-rpc: 0.1.1
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /debug/4.3.3_supports-color@8.1.1:
-    resolution: {integrity: 
sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==}
-    engines: {node: '>=6.0'}
+  /fork-ts-checker-webpack-plugin/4.1.6_whfidqbq6inl26rhdbd2ot7yoa:
+    resolution: {integrity: 
sha512-DUxuQaKoqfNne8iikd14SAkh5uw4+8vNifp6gmA73yYNS6ywLIWSLD/n/mBzHQRpW3J7rbATEakmiA8JvkTyZw==}
+    engines: {node: '>=6.11.5', yarn: '>=1.0.0'}
     peerDependencies:
-      supports-color: '*'
+      eslint: '>= 6'
+      typescript: '>= 2.7'
+      vue-template-compiler: '*'
+      webpack: '>= 4'
     peerDependenciesMeta:
-      supports-color:
+      eslint:
+        optional: true
+      vue-template-compiler:
         optional: true
     dependencies:
-      ms: 2.1.2
-      supports-color: 8.1.1
+      '@babel/code-frame': 7.16.7
+      chalk: 2.4.2
+      eslint: 7.32.0
+      micromatch: 3.1.10
+      minimatch: 3.1.2
+      semver: 5.7.1
+      tapable: 1.1.3
+      typescript: 4.2.4
+      webpack: 4.46.0
+      worker-rpc: 0.1.1
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /debug/4.3.4:
-    resolution: {integrity: 
sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
-    engines: {node: '>=6.0'}
+  /fork-ts-checker-webpack-plugin/6.5.2_3n2x3j6farblcaf52bherr6og4:
+    resolution: {integrity: 
sha512-m5cUmF30xkZ7h4tWUgTAcEaKmUW7tfyUyTqNNOz7OxWJ0v1VWKTcOvH8FWHUwSjlW/356Ijc9vi3XfcPstpQKA==}
+    engines: {node: '>=10', yarn: '>=1.0.0'}
     peerDependencies:
-      supports-color: '*'
+      eslint: '>= 6'
+      typescript: '>= 2.7'
+      vue-template-compiler: '*'
+      webpack: '>= 4'
     peerDependenciesMeta:
-      supports-color:
+      eslint:
+        optional: true
+      vue-template-compiler:
         optional: true
     dependencies:
-      ms: 2.1.2
-    dev: true
-
-  /decamelize/1.2.0:
-    resolution: {integrity: sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=}
-    engines: {node: '>=0.10.0'}
-    dev: true
-
-  /decamelize/4.0.0:
-    resolution: {integrity: 
sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==}
-    engines: {node: '>=10'}
-    dev: true
-
-  /decode-uri-component/0.2.0:
-    resolution: {integrity: 
sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==}
-    engines: {node: '>=0.10'}
+      '@babel/code-frame': 7.16.7
+      '@types/json-schema': 7.0.11
+      chalk: 4.1.2
+      chokidar: 3.5.3
+      cosmiconfig: 6.0.0
+      deepmerge: 4.2.2
+      eslint: 7.32.0
+      fs-extra: 9.1.0
+      glob: 7.2.3
+      memfs: 3.4.1
+      minimatch: 3.1.2
+      schema-utils: 2.7.0
+      semver: 7.3.8
+      tapable: 1.1.3
+      typescript: 4.8.4
+      webpack: 4.46.0
     dev: true
 
-  /decompress-response/3.3.0:
-    resolution: {integrity: sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=}
-    engines: {node: '>=4'}
+  /fork-ts-checker-webpack-plugin/6.5.2_ef2lra3u3fsnrdrpybbvbgzate:
+    resolution: {integrity: 
sha512-m5cUmF30xkZ7h4tWUgTAcEaKmUW7tfyUyTqNNOz7OxWJ0v1VWKTcOvH8FWHUwSjlW/356Ijc9vi3XfcPstpQKA==}
+    engines: {node: '>=10', yarn: '>=1.0.0'}
+    peerDependencies:
+      eslint: '>= 6'
+      typescript: '>= 2.7'
+      vue-template-compiler: '*'
+      webpack: '>= 4'
+    peerDependenciesMeta:
+      eslint:
+        optional: true
+      vue-template-compiler:
+        optional: true
     dependencies:
-      mimic-response: 1.0.1
+      '@babel/code-frame': 7.16.7
+      '@types/json-schema': 7.0.11
+      chalk: 4.1.2
+      chokidar: 3.5.3
+      cosmiconfig: 6.0.0
+      deepmerge: 4.2.2
+      eslint: 8.8.0
+      fs-extra: 9.1.0
+      glob: 7.2.3
+      memfs: 3.4.1
+      minimatch: 3.1.2
+      schema-utils: 2.7.0
+      semver: 7.3.8
+      tapable: 1.1.3
+      typescript: 4.8.4
+      webpack: 4.46.0
     dev: true
 
-  /deep-eql/3.0.1:
-    resolution: {integrity: 
sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==}
-    engines: {node: '>=0.12'}
+  /form-data/2.3.3:
+    resolution: {integrity: 
sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==}
+    engines: {node: '>= 0.12'}
     dependencies:
-      type-detect: 4.0.8
+      asynckit: 0.4.0
+      combined-stream: 1.0.8
+      mime-types: 2.1.35
+    dev: true
 
-  /deep-equal/1.1.1:
-    resolution: {integrity: 
sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==}
+  /form-data/3.0.1:
+    resolution: {integrity: 
sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==}
+    engines: {node: '>= 6'}
     dependencies:
-      is-arguments: 1.1.1
-      is-date-object: 1.0.5
-      is-regex: 1.1.4
-      object-is: 1.1.5
-      object-keys: 1.1.1
-      regexp.prototype.flags: 1.4.1
+      asynckit: 0.4.0
+      combined-stream: 1.0.8
+      mime-types: 2.1.35
     dev: true
 
-  /deep-extend/0.6.0:
-    resolution: {integrity: 
sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==}
-    engines: {node: '>=4.0.0'}
-    dev: true
+  /form-data/4.0.0:
+    resolution: {integrity: 
sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
+    engines: {node: '>= 6'}
+    dependencies:
+      asynckit: 0.4.0
+      combined-stream: 1.0.8
+      mime-types: 2.1.35
+    dev: false
 
-  /deep-is/0.1.4:
-    resolution: {integrity: 
sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
+  /format/0.2.2:
+    resolution: {integrity: 
sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==}
+    engines: {node: '>=0.4.x'}
     dev: true
 
-  /deepcopy/1.0.0:
-    resolution: {integrity: 
sha512-WJrecobaoqqgQHtvRI2/VCzWoWXPAnFYyAkF/spmL46lZMnd0gW0gLGuyeFVSrqt2B3s0oEEj6i+j2L/2QiS4g==}
+  /formdata-polyfill/4.0.10:
+    resolution: {integrity: 
sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
+    engines: {node: '>=12.20.0'}
     dependencies:
-      type-detect: 4.0.8
-    dev: true
+      fetch-blob: 3.1.4
+    dev: false
 
-  /deepmerge/4.2.2:
-    resolution: {integrity: 
sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==}
-    engines: {node: '>=0.10.0'}
+  /forwarded/0.2.0:
+    resolution: {integrity: 
sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
+    engines: {node: '>= 0.6'}
     dev: true
 
-  /default-gateway/6.0.3:
-    resolution: {integrity: 
sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==}
-    engines: {node: '>= 10'}
-    dependencies:
-      execa: 5.1.1
+  /fraction.js/4.1.3:
+    resolution: {integrity: 
sha512-pUHWWt6vHzZZiQJcM6S/0PXfS+g6FM4BF5rj9wZyreivhQPdsh5PpE25VtSNxq80wHS5RfY51Ii+8Z0Zl/pmzg==}
     dev: true
 
-  /default-require-extensions/3.0.0:
-    resolution: {integrity: 
sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==}
-    engines: {node: '>=8'}
+  /fragment-cache/0.2.1:
+    resolution: {integrity: 
sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==}
+    engines: {node: '>=0.10.0'}
     dependencies:
-      strip-bom: 4.0.0
+      map-cache: 0.2.2
     dev: true
 
-  /defaults/1.0.3:
-    resolution: {integrity: sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=}
-    dependencies:
-      clone: 1.0.4
+  /fresh/0.5.2:
+    resolution: {integrity: sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=}
+    engines: {node: '>= 0.6'}
     dev: true
 
-  /defer-to-connect/1.1.3:
-    resolution: {integrity: 
sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==}
+  /from2/2.3.0:
+    resolution: {integrity: 
sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==}
+    dependencies:
+      inherits: 2.0.4
+      readable-stream: 2.3.7
     dev: true
 
-  /define-lazy-prop/2.0.0:
-    resolution: {integrity: 
sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==}
-    engines: {node: '>=8'}
+  /fromentries/1.3.2:
+    resolution: {integrity: 
sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==}
     dev: true
 
-  /define-properties/1.1.3:
-    resolution: {integrity: 
sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==}
-    engines: {node: '>= 0.4'}
+  /fs-extra/10.1.0:
+    resolution: {integrity: 
sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==}
+    engines: {node: '>=12'}
     dependencies:
-      object-keys: 1.1.1
+      graceful-fs: 4.2.10
+      jsonfile: 6.1.0
+      universalify: 2.0.0
     dev: true
 
-  /define-property/0.2.5:
-    resolution: {integrity: sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=}
-    engines: {node: '>=0.10.0'}
+  /fs-extra/4.0.3:
+    resolution: {integrity: 
sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==}
     dependencies:
-      is-descriptor: 0.1.6
+      graceful-fs: 4.2.10
+      jsonfile: 4.0.0
+      universalify: 0.1.2
     dev: true
 
-  /define-property/1.0.0:
-    resolution: {integrity: sha1-dp66rz9KY6rTr56NMEybvnm/sOY=}
-    engines: {node: '>=0.10.0'}
+  /fs-extra/8.1.0:
+    resolution: {integrity: 
sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==}
+    engines: {node: '>=6 <7 || >=8'}
     dependencies:
-      is-descriptor: 1.0.2
+      graceful-fs: 4.2.10
+      jsonfile: 4.0.0
+      universalify: 0.1.2
     dev: true
 
-  /define-property/2.0.2:
-    resolution: {integrity: 
sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==}
-    engines: {node: '>=0.10.0'}
+  /fs-extra/9.1.0:
+    resolution: {integrity: 
sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==}
+    engines: {node: '>=10'}
     dependencies:
-      is-descriptor: 1.0.2
-      isobject: 3.0.1
+      at-least-node: 1.0.0
+      graceful-fs: 4.2.10
+      jsonfile: 6.1.0
+      universalify: 2.0.0
     dev: true
 
-  /del/6.0.0:
-    resolution: {integrity: 
sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ==}
-    engines: {node: '>=10'}
+  /fs-minipass/1.2.7:
+    resolution: {integrity: 
sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==}
     dependencies:
-      globby: 11.1.0
-      graceful-fs: 4.2.9
-      is-glob: 4.0.3
-      is-path-cwd: 2.2.0
-      is-path-inside: 3.0.3
-      p-map: 4.0.0
-      rimraf: 3.0.2
-      slash: 3.0.0
+      minipass: 2.9.0
     dev: true
 
-  /del/6.1.1:
-    resolution: {integrity: 
sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==}
-    engines: {node: '>=10'}
+  /fs-minipass/2.1.0:
+    resolution: {integrity: 
sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==}
+    engines: {node: '>= 8'}
     dependencies:
-      globby: 11.1.0
-      graceful-fs: 4.2.10
-      is-glob: 4.0.3
-      is-path-cwd: 2.2.0
-      is-path-inside: 3.0.3
-      p-map: 4.0.0
-      rimraf: 3.0.2
-      slash: 3.0.0
+      minipass: 3.1.6
     dev: true
 
-  /delayed-stream/1.0.0:
-    resolution: {integrity: 
sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
-    engines: {node: '>=0.4.0'}
-
-  /depd/1.1.2:
-    resolution: {integrity: sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=}
-    engines: {node: '>= 0.6'}
+  /fs-monkey/1.0.3:
+    resolution: {integrity: 
sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==}
     dev: true
 
-  /des.js/1.0.1:
-    resolution: {integrity: 
sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==}
+  /fs-write-stream-atomic/1.0.10:
+    resolution: {integrity: 
sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA==}
     dependencies:
-      inherits: 2.0.4
-      minimalistic-assert: 1.0.1
+      graceful-fs: 4.2.10
+      iferr: 0.1.5
+      imurmurhash: 0.1.4
+      readable-stream: 2.3.7
     dev: true
 
-  /destroy/1.0.4:
-    resolution: {integrity: sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=}
+  /fs.realpath/1.0.0:
+    resolution: {integrity: 
sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
+
+  /fsevents/1.2.13:
+    resolution: {integrity: 
sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==}
+    engines: {node: '>= 4.0'}
+    os: [darwin]
+    deprecated: fsevents 1 will break on node v14+ and could be using insecure 
binaries. Upgrade to fsevents 2.
+    requiresBuild: true
+    dependencies:
+      bindings: 1.5.0
+      nan: 2.17.0
     dev: true
+    optional: true
 
-  /detect-node/2.1.0:
-    resolution: {integrity: 
sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==}
+  /fsevents/2.3.2:
+    resolution: {integrity: 
sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
+    engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+    os: [darwin]
+    requiresBuild: true
     dev: true
+    optional: true
 
-  /diff/5.0.0:
-    resolution: {integrity: 
sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==}
-    engines: {node: '>=0.3.1'}
+  /function-bind/1.1.1:
+    resolution: {integrity: 
sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
     dev: true
 
-  /diffie-hellman/5.0.3:
-    resolution: {integrity: 
sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==}
+  /function.prototype.name/1.1.5:
+    resolution: {integrity: 
sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==}
+    engines: {node: '>= 0.4'}
     dependencies:
-      bn.js: 4.12.0
-      miller-rabin: 4.0.1
-      randombytes: 2.1.0
+      call-bind: 1.0.2
+      define-properties: 1.1.3
+      es-abstract: 1.19.1
+      functions-have-names: 1.2.3
     dev: true
 
-  /dir-glob/3.0.1:
-    resolution: {integrity: 
sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
-    engines: {node: '>=8'}
-    dependencies:
-      path-type: 4.0.0
+  /functional-red-black-tree/1.0.1:
+    resolution: {integrity: 
sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==}
     dev: true
 
-  /dns-equal/1.0.0:
-    resolution: {integrity: sha1-s55/HabrCnW6nBcySzR1PEfgZU0=}
+  /functions-have-names/1.2.3:
+    resolution: {integrity: 
sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
     dev: true
 
-  /dns-packet/1.3.4:
-    resolution: {integrity: 
sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==}
-    dependencies:
-      ip: 1.1.5
-      safe-buffer: 5.2.1
+  /fuse.js/3.6.1:
+    resolution: {integrity: 
sha512-hT9yh/tiinkmirKrlv4KWOjztdoZo1mx9Qh4KvWqC7isoXwdUY3PNWUxceF4/qO9R6riA2C29jdTOeQOIROjgw==}
+    engines: {node: '>=6'}
     dev: true
 
-  /dns-txt/2.0.2:
-    resolution: {integrity: sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=}
+  /gauge/2.7.4:
+    resolution: {integrity: 
sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==}
     dependencies:
-      buffer-indexof: 1.1.1
+      aproba: 1.2.0
+      console-control-strings: 1.1.0
+      has-unicode: 2.0.1
+      object-assign: 4.1.1
+      signal-exit: 3.0.7
+      string-width: 1.0.2
+      strip-ansi: 3.0.1
+      wide-align: 1.1.5
     dev: true
 
-  /doctrine/2.1.0:
-    resolution: {integrity: 
sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==}
-    engines: {node: '>=0.10.0'}
+  /gauge/3.0.2:
+    resolution: {integrity: 
sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==}
+    engines: {node: '>=10'}
     dependencies:
-      esutils: 2.0.3
+      aproba: 1.2.0
+      color-support: 1.1.3
+      console-control-strings: 1.1.0
+      has-unicode: 2.0.1
+      object-assign: 4.1.1
+      signal-exit: 3.0.7
+      string-width: 4.2.3
+      strip-ansi: 6.0.1
+      wide-align: 1.1.5
     dev: true
 
-  /doctrine/3.0.0:
-    resolution: {integrity: 
sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
-    engines: {node: '>=6.0.0'}
-    dependencies:
-      esutils: 2.0.3
+  /gensync/1.0.0-beta.2:
+    resolution: {integrity: 
sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
+    engines: {node: '>=6.9.0'}
     dev: true
 
-  /dom-accessibility-api/0.5.7:
-    resolution: {integrity: 
sha512-ml3lJIq9YjUfM9TUnEPvEYWFSwivwIGBPKpewX7tii7fwCazA8yCioGdqQcNsItPpfFvSJ3VIdMQPj60LJhcQA==}
+  /get-caller-file/2.0.5:
+    resolution: {integrity: 
sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
+    engines: {node: 6.* || 8.* || >= 10.*}
     dev: true
 
-  /dom-converter/0.2.0:
-    resolution: {integrity: 
sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==}
+  /get-func-name/2.0.0:
+    resolution: {integrity: 
sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==}
+
+  /get-intrinsic/1.1.1:
+    resolution: {integrity: 
sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==}
     dependencies:
-      utila: 0.4.0
+      function-bind: 1.1.1
+      has: 1.0.3
+      has-symbols: 1.0.3
     dev: true
 
-  /dom-serializer/0.2.2:
-    resolution: {integrity: 
sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==}
+  /get-intrinsic/1.1.3:
+    resolution: {integrity: 
sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==}
     dependencies:
-      domelementtype: 2.2.0
-      entities: 2.2.0
+      function-bind: 1.1.1
+      has: 1.0.3
+      has-symbols: 1.0.3
     dev: true
 
-  /dom-serializer/1.3.2:
-    resolution: {integrity: 
sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==}
-    dependencies:
-      domelementtype: 2.2.0
-      domhandler: 4.3.0
-      entities: 2.2.0
+  /get-own-enumerable-property-symbols/3.0.2:
+    resolution: {integrity: 
sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==}
     dev: true
 
-  /domain-browser/1.2.0:
-    resolution: {integrity: 
sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==}
-    engines: {node: '>=0.4', npm: '>=1.2'}
+  /get-package-type/0.1.0:
+    resolution: {integrity: 
sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==}
+    engines: {node: '>=8.0.0'}
     dev: true
 
-  /domelementtype/1.3.1:
-    resolution: {integrity: 
sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==}
+  /get-port/3.2.0:
+    resolution: {integrity: 
sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==}
+    engines: {node: '>=4'}
     dev: true
 
-  /domelementtype/2.2.0:
-    resolution: {integrity: 
sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==}
+  /get-port/5.1.1:
+    resolution: {integrity: 
sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==}
+    engines: {node: '>=8'}
     dev: true
 
-  /domexception/1.0.1:
-    resolution: {integrity: 
sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==}
-    dependencies:
-      webidl-conversions: 4.0.2
+  /get-stdin/4.0.1:
+    resolution: {integrity: 
sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw==}
+    engines: {node: '>=0.10.0'}
     dev: true
+    optional: true
 
-  /domhandler/4.3.0:
-    resolution: {integrity: 
sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==}
-    engines: {node: '>= 4'}
+  /get-stream/4.1.0:
+    resolution: {integrity: 
sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==}
+    engines: {node: '>=6'}
     dependencies:
-      domelementtype: 2.2.0
+      pump: 3.0.0
     dev: true
 
-  /domutils/1.7.0:
-    resolution: {integrity: 
sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==}
+  /get-stream/5.2.0:
+    resolution: {integrity: 
sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==}
+    engines: {node: '>=8'}
     dependencies:
-      dom-serializer: 0.2.2
-      domelementtype: 1.3.1
+      pump: 3.0.0
     dev: true
 
-  /domutils/2.8.0:
-    resolution: {integrity: 
sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==}
-    dependencies:
-      dom-serializer: 1.3.2
-      domelementtype: 2.2.0
-      domhandler: 4.3.0
+  /get-stream/6.0.1:
+    resolution: {integrity: 
sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
+    engines: {node: '>=10'}
     dev: true
 
-  /dot-prop/5.3.0:
-    resolution: {integrity: 
sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==}
-    engines: {node: '>=8'}
+  /get-symbol-description/1.0.0:
+    resolution: {integrity: 
sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==}
+    engines: {node: '>= 0.4'}
     dependencies:
-      is-obj: 2.0.0
+      call-bind: 1.0.2
+      get-intrinsic: 1.1.3
     dev: true
 
-  /duplexer/0.1.2:
-    resolution: {integrity: 
sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==}
+  /get-value/2.0.6:
+    resolution: {integrity: 
sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==}
+    engines: {node: '>=0.10.0'}
     dev: true
 
-  /duplexer3/0.1.4:
-    resolution: {integrity: sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=}
+  /getpass/0.1.7:
+    resolution: {integrity: 
sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==}
+    dependencies:
+      assert-plus: 1.0.0
     dev: true
 
-  /duplexify/3.7.1:
-    resolution: {integrity: 
sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==}
+  /gettext-parser/1.1.0:
+    resolution: {integrity: sha1-LFpmONiTk0ubVQN9CtgstwBLJnk=}
     dependencies:
-      end-of-stream: 1.4.4
-      inherits: 2.0.4
-      readable-stream: 2.3.7
-      stream-shift: 1.0.1
+      encoding: 0.1.13
     dev: true
 
-  /eastasianwidth/0.2.0:
-    resolution: {integrity: 
sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
+  /github-slugger/1.4.0:
+    resolution: {integrity: 
sha512-w0dzqw/nt51xMVmlaV1+JRzN+oCa1KfcgGEWhxUG16wbdA+Xnt/yoFO8Z8x/V82ZcZ0wy6ln9QDup5avbhiDhQ==}
     dev: true
 
-  /ecc-jsbn/0.1.2:
-    resolution: {integrity: sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=}
+  /gittar/0.1.1:
+    resolution: {integrity: 
sha512-p+XuqWJpW9ahUuNTptqeFjudFq31o6Jd+maMBarkMAR5U3K9c7zJB4sQ4BV8mIqrTOV29TtqikDhnZfCD4XNfQ==}
+    engines: {node: '>=4'}
     dependencies:
-      jsbn: 0.1.1
-      safer-buffer: 2.1.2
+      mkdirp: 0.5.5
+      tar: 4.4.19
     dev: true
 
-  /ee-first/1.1.1:
-    resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=}
+  /glob-base/0.3.0:
+    resolution: {integrity: 
sha512-ab1S1g1EbO7YzauaJLkgLp7DZVAqj9M/dvKlTt8DkXA2tiOIcSMrlVI2J1RZyB5iJVccEscjGn+kpOG9788MHA==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      glob-parent: 2.0.0
+      is-glob: 2.0.1
     dev: true
 
-  /ejs-loader/0.5.0:
-    resolution: {integrity: 
sha512-iirFqlP3tiFoedNZ7dQcjvechunl054VbW6Ki38T/pabgXMAncduSE0ZXLeVGn1NbmcUJF9Z5TC0EvQ4RIpP9Q==}
+  /glob-parent/2.0.0:
+    resolution: {integrity: 
sha512-JDYOvfxio/t42HKdxkAYaCiBN7oYiuxykOxKxdaUW5Qn0zaYN3gRQWolrwdnf0shM9/EP0ebuuTmyoXNr1cC5w==}
     dependencies:
-      loader-utils: 2.0.2
-      lodash: 4.17.21
+      is-glob: 2.0.1
     dev: true
 
-  /ejs/3.1.6:
-    resolution: {integrity: 
sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==}
-    engines: {node: '>=0.10.0'}
-    hasBin: true
+  /glob-parent/3.1.0:
+    resolution: {integrity: 
sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==}
     dependencies:
-      jake: 10.8.2
+      is-glob: 3.1.0
+      path-dirname: 1.0.2
     dev: true
 
-  /electron-to-chromium/1.4.68:
-    resolution: {integrity: 
sha512-cId+QwWrV8R1UawO6b9BR1hnkJ4EJPCPAr4h315vliHUtVUJDk39Sg1PMNnaWKfj5x+93ssjeJ9LKL6r8LaMiA==}
+  /glob-parent/5.1.2:
+    resolution: {integrity: 
sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+    engines: {node: '>= 6'}
+    dependencies:
+      is-glob: 4.0.3
     dev: true
 
-  /elliptic/6.5.4:
-    resolution: {integrity: 
sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==}
+  /glob-parent/6.0.2:
+    resolution: {integrity: 
sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
+    engines: {node: '>=10.13.0'}
     dependencies:
-      bn.js: 4.12.0
-      brorand: 1.1.0
-      hash.js: 1.1.7
-      hmac-drbg: 1.0.1
-      inherits: 2.0.4
-      minimalistic-assert: 1.0.1
-      minimalistic-crypto-utils: 1.0.1
+      is-glob: 4.0.3
     dev: true
 
-  /emittery/0.11.0:
-    resolution: {integrity: 
sha512-S/7tzL6v5i+4iJd627Nhv9cLFIo5weAIlGccqJFpnBoDB8U1TF2k5tez4J/QNuxyyhWuFqHg1L84Kd3m7iXg6g==}
-    engines: {node: '>=12'}
+  /glob-promise/3.4.0_glob@7.2.3:
+    resolution: {integrity: 
sha512-q08RJ6O+eJn+dVanerAndJwIcumgbDdYiUT7zFQl3Wm1xD6fBKtah7H8ZJChj4wP+8C+QfeVy8xautR7rdmKEw==}
+    engines: {node: '>=4'}
+    peerDependencies:
+      glob: '*'
+    dependencies:
+      '@types/glob': 8.0.0
+      glob: 7.2.3
     dev: true
 
-  /emoji-regex/8.0.0:
-    resolution: {integrity: 
sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
+  /glob-to-regexp/0.3.0:
+    resolution: {integrity: 
sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig==}
     dev: true
 
-  /emoji-regex/9.2.2:
-    resolution: {integrity: 
sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
+  /glob-to-regexp/0.4.1:
+    resolution: {integrity: 
sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==}
     dev: true
 
-  /emojis-list/2.1.0:
-    resolution: {integrity: sha1-TapNnbAPmBmIDHn6RXrlsJof04k=}
-    engines: {node: '>= 0.10'}
-    dev: true
+  /glob/7.2.0:
+    resolution: {integrity: 
sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==}
+    dependencies:
+      fs.realpath: 1.0.0
+      inflight: 1.0.6
+      inherits: 2.0.4
+      minimatch: 3.1.2
+      once: 1.4.0
+      path-is-absolute: 1.0.1
 
-  /emojis-list/3.0.0:
-    resolution: {integrity: 
sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==}
-    engines: {node: '>= 4'}
+  /glob/7.2.3:
+    resolution: {integrity: 
sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
+    dependencies:
+      fs.realpath: 1.0.0
+      inflight: 1.0.6
+      inherits: 2.0.4
+      minimatch: 3.1.2
+      once: 1.4.0
+      path-is-absolute: 1.0.1
     dev: true
 
-  /encodeurl/1.0.2:
-    resolution: {integrity: sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=}
-    engines: {node: '>= 0.8'}
+  /global-dirs/2.1.0:
+    resolution: {integrity: 
sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==}
+    engines: {node: '>=8'}
+    dependencies:
+      ini: 1.3.7
     dev: true
 
-  /encoding/0.1.13:
-    resolution: {integrity: 
sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==}
+  /global-dirs/3.0.0:
+    resolution: {integrity: 
sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==}
+    engines: {node: '>=10'}
     dependencies:
-      iconv-lite: 0.6.3
+      ini: 2.0.0
     dev: true
 
-  /end-of-stream/1.4.4:
-    resolution: {integrity: 
sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==}
+  /global-modules/2.0.0:
+    resolution: {integrity: 
sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==}
+    engines: {node: '>=6'}
     dependencies:
-      once: 1.4.0
+      global-prefix: 3.0.0
     dev: true
 
-  /enhanced-resolve/4.5.0:
-    resolution: {integrity: 
sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==}
-    engines: {node: '>=6.9.0'}
+  /global-prefix/3.0.0:
+    resolution: {integrity: 
sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==}
+    engines: {node: '>=6'}
     dependencies:
-      graceful-fs: 4.2.9
-      memory-fs: 0.5.0
-      tapable: 1.1.3
+      ini: 1.3.8
+      kind-of: 6.0.3
+      which: 1.3.1
     dev: true
 
-  /enhanced-resolve/5.8.2:
-    resolution: {integrity: 
sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==}
-    engines: {node: '>=10.13.0'}
+  /global/4.4.0:
+    resolution: {integrity: 
sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==}
     dependencies:
-      graceful-fs: 4.2.8
-      tapable: 2.2.0
+      min-document: 2.19.0
+      process: 0.11.10
     dev: true
 
-  /entities/2.2.0:
-    resolution: {integrity: 
sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==}
+  /globals/11.12.0:
+    resolution: {integrity: 
sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
+    engines: {node: '>=4'}
     dev: true
 
-  /envinfo/7.8.1:
-    resolution: {integrity: 
sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==}
-    engines: {node: '>=4'}
-    hasBin: true
+  /globals/13.12.1:
+    resolution: {integrity: 
sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==}
+    engines: {node: '>=8'}
+    dependencies:
+      type-fest: 0.20.2
     dev: true
 
-  /errno/0.1.8:
-    resolution: {integrity: 
sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==}
-    hasBin: true
+  /globalthis/1.0.3:
+    resolution: {integrity: 
sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==}
+    engines: {node: '>= 0.4'}
     dependencies:
-      prr: 1.0.1
+      define-properties: 1.1.4
     dev: true
 
-  /error-ex/1.3.2:
-    resolution: {integrity: 
sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
+  /globby/11.0.1:
+    resolution: {integrity: 
sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==}
+    engines: {node: '>=10'}
     dependencies:
-      is-arrayish: 0.2.1
+      array-union: 2.1.0
+      dir-glob: 3.0.1
+      fast-glob: 3.2.12
+      ignore: 5.2.0
+      merge2: 1.4.1
+      slash: 3.0.0
     dev: true
 
-  /es-abstract/1.19.1:
-    resolution: {integrity: 
sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==}
-    engines: {node: '>= 0.4'}
+  /globby/11.1.0:
+    resolution: {integrity: 
sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
+    engines: {node: '>=10'}
     dependencies:
-      call-bind: 1.0.2
-      es-to-primitive: 1.2.1
-      function-bind: 1.1.1
-      get-intrinsic: 1.1.1
-      get-symbol-description: 1.0.0
-      has: 1.0.3
-      has-symbols: 1.0.2
-      internal-slot: 1.0.3
-      is-callable: 1.2.4
-      is-negative-zero: 2.0.2
-      is-regex: 1.1.4
-      is-shared-array-buffer: 1.0.1
-      is-string: 1.0.7
-      is-weakref: 1.0.2
-      object-inspect: 1.12.0
-      object-keys: 1.1.1
-      object.assign: 4.1.2
-      string.prototype.trimend: 1.0.4
-      string.prototype.trimstart: 1.0.4
-      unbox-primitive: 1.0.1
+      array-union: 2.1.0
+      dir-glob: 3.0.1
+      fast-glob: 3.2.11
+      ignore: 5.2.0
+      merge2: 1.4.1
+      slash: 3.0.0
+    dev: true
+
+  /globby/13.1.2:
+    resolution: {integrity: 
sha512-LKSDZXToac40u8Q1PQtZihbNdTYSNMuWe+K5l+oa6KgDzSvVrHXlJy40hUP522RjAIoNLJYBJi7ow+rbFpIhHQ==}
+    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+    dependencies:
+      dir-glob: 3.0.1
+      fast-glob: 3.2.12
+      ignore: 5.2.0
+      merge2: 1.4.1
+      slash: 4.0.0
     dev: true
 
-  /es-to-primitive/1.2.1:
-    resolution: {integrity: 
sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==}
-    engines: {node: '>= 0.4'}
+  /globby/6.1.0:
+    resolution: {integrity: 
sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==}
+    engines: {node: '>=0.10.0'}
     dependencies:
-      is-callable: 1.2.4
-      is-date-object: 1.0.5
-      is-symbol: 1.0.4
+      array-union: 1.0.2
+      glob: 7.2.3
+      object-assign: 4.1.1
+      pify: 2.3.0
+      pinkie-promise: 2.0.1
     dev: true
 
-  /es6-error/4.1.1:
-    resolution: {integrity: 
sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==}
+  /globby/7.1.1:
+    resolution: {integrity: 
sha512-yANWAN2DUcBtuus5Cpd+SKROzXHs2iVXFZt/Ykrfz6SAXqacLX25NZpltE+39ceMexYF4TtEadjuSTw8+3wX4g==}
+    engines: {node: '>=4'}
+    dependencies:
+      array-union: 1.0.2
+      dir-glob: 2.2.2
+      glob: 7.2.3
+      ignore: 3.3.10
+      pify: 3.0.0
+      slash: 1.0.0
     dev: true
 
-  /esbuild-android-arm64/0.14.21:
-    resolution: {integrity: 
sha512-Bqgld1TY0wZv8TqiQmVxQFgYzz8ZmyzT7clXBDZFkOOdRybzsnj8AZuK1pwcLVA7Ya6XncHgJqIao7NFd3s0RQ==}
-    engines: {node: '>=12'}
-    cpu: [arm64]
-    os: [android]
-    requiresBuild: true
+  /globby/9.2.0:
+    resolution: {integrity: 
sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==}
+    engines: {node: '>=6'}
+    dependencies:
+      '@types/glob': 7.2.0
+      array-union: 1.0.2
+      dir-glob: 2.2.2
+      fast-glob: 2.2.7
+      glob: 7.2.3
+      ignore: 4.0.6
+      pify: 4.0.1
+      slash: 2.0.0
+    transitivePeerDependencies:
+      - supports-color
     dev: true
-    optional: true
 
-  /esbuild-darwin-64/0.14.21:
-    resolution: {integrity: 
sha512-j+Eg+e13djzyYINVvAbOo2/zvZ2DivuJJTaBrJnJHSD7kUNuGHRkHoSfFjbI80KHkn091w350wdmXDNSgRjfYQ==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [darwin]
-    requiresBuild: true
+  /got/9.6.0:
+    resolution: {integrity: 
sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==}
+    engines: {node: '>=8.6'}
+    dependencies:
+      '@sindresorhus/is': 0.14.0
+      '@szmarczak/http-timer': 1.1.2
+      '@types/keyv': 3.1.4
+      '@types/responselike': 1.0.0
+      cacheable-request: 6.1.0
+      decompress-response: 3.3.0
+      duplexer3: 0.1.4
+      get-stream: 4.1.0
+      lowercase-keys: 1.0.1
+      mimic-response: 1.0.1
+      p-cancelable: 1.1.0
+      to-readable-stream: 1.0.0
+      url-parse-lax: 3.0.0
     dev: true
-    optional: true
 
-  /esbuild-darwin-arm64/0.14.21:
-    resolution: {integrity: 
sha512-nDNTKWDPI0RuoPj5BhcSB2z5EmZJJAyRtZLIjyXSqSpAyoB8eyAKXl4lB8U2P78Fnh4Lh1le/fmpewXE04JhBQ==}
-    engines: {node: '>=12'}
-    cpu: [arm64]
-    os: [darwin]
-    requiresBuild: true
+  /graceful-fs/4.2.10:
+    resolution: {integrity: 
sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==}
     dev: true
-    optional: true
 
-  /esbuild-freebsd-64/0.14.21:
-    resolution: {integrity: 
sha512-zIurkCHXhxELiDZtLGiexi8t8onQc2LtuE+S7457H/pP0g0MLRKMrsn/IN4LDkNe6lvBjuoZZi2OfelOHn831g==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [freebsd]
-    requiresBuild: true
+  /graceful-fs/4.2.9:
+    resolution: {integrity: 
sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==}
     dev: true
-    optional: true
 
-  /esbuild-freebsd-arm64/0.14.21:
-    resolution: {integrity: 
sha512-wdxMmkJfbwcN+q85MpeUEamVZ40FNsBa9mPq8tAszDn8TRT2HoJvVRADPIIBa9SWWwlDChIMjkDKAnS3KS/sPA==}
-    engines: {node: '>=12'}
-    cpu: [arm64]
-    os: [freebsd]
-    requiresBuild: true
+  /growl/1.10.5:
+    resolution: {integrity: 
sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==}
+    engines: {node: '>=4.x'}
     dev: true
-    optional: true
 
-  /esbuild-linux-32/0.14.21:
-    resolution: {integrity: 
sha512-fmxvyzOPPh2xiEHojpCeIQP6pXcoKsWbz3ryDDIKLOsk4xp3GbpHIEAWP0xTeuhEbendmvBDVKbAVv3PnODXLg==}
-    engines: {node: '>=12'}
-    cpu: [ia32]
-    os: [linux]
-    requiresBuild: true
+  /growly/1.3.0:
+    resolution: {integrity: 
sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==}
     dev: true
     optional: true
 
-  /esbuild-linux-64/0.14.21:
-    resolution: {integrity: 
sha512-edZyNOv1ql+kpmlzdqzzDjRQYls+tSyi4QFi+PdBhATJFUqHsnNELWA9vMSzAaInPOEaVUTA5Ml28XFChcy4DA==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [linux]
-    requiresBuild: true
+  /gud/1.0.0:
+    resolution: {integrity: 
sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==}
     dev: true
-    optional: true
 
-  /esbuild-linux-arm/0.14.21:
-    resolution: {integrity: 
sha512-aSU5pUueK6afqmLQsbU+QcFBT62L+4G9hHMJDHWfxgid6hzhSmfRH9U/f+ymvxsSTr/HFRU4y7ox8ZyhlVl98w==}
-    engines: {node: '>=12'}
-    cpu: [arm]
-    os: [linux]
-    requiresBuild: true
+  /gzip-size/5.1.1:
+    resolution: {integrity: 
sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==}
+    engines: {node: '>=6'}
+    dependencies:
+      duplexer: 0.1.2
+      pify: 4.0.1
     dev: true
-    optional: true
 
-  /esbuild-linux-arm64/0.14.21:
-    resolution: {integrity: 
sha512-t5qxRkq4zdQC0zXpzSB2bTtfLgOvR0C6BXYaRE/6/k8/4SrkZcTZBeNu+xGvwCU4b5dU9ST9pwIWkK6T1grS8g==}
-    engines: {node: '>=12'}
-    cpu: [arm64]
-    os: [linux]
-    requiresBuild: true
+  /gzip-size/6.0.0:
+    resolution: {integrity: 
sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==}
+    engines: {node: '>=10'}
+    dependencies:
+      duplexer: 0.1.2
     dev: true
-    optional: true
 
-  /esbuild-linux-mips64le/0.14.21:
-    resolution: {integrity: 
sha512-jLZLQGCNlUsmIHtGqNvBs3zN+7a4D9ckf0JZ+jQTwHdZJ1SgV9mAjbB980OFo66LoY+WeM7t3WEnq3FjI1zw4A==}
-    engines: {node: '>=12'}
-    cpu: [mips64el]
-    os: [linux]
-    requiresBuild: true
+  /handle-thing/2.0.1:
+    resolution: {integrity: 
sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==}
     dev: true
-    optional: true
 
-  /esbuild-linux-ppc64le/0.14.21:
-    resolution: {integrity: 
sha512-4TWxpK391en2UBUw6GSrukToTDu6lL9vkm3Ll40HrI08WG3qcnJu7bl8e1+GzelDsiw1QmfAY/nNvJ6iaHRpCQ==}
-    engines: {node: '>=12'}
-    cpu: [ppc64]
-    os: [linux]
-    requiresBuild: true
+  /handlebars/4.7.7:
+    resolution: {integrity: 
sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==}
+    engines: {node: '>=0.4.7'}
+    hasBin: true
+    dependencies:
+      minimist: 1.2.5
+      neo-async: 2.6.2
+      source-map: 0.6.1
+      wordwrap: 1.0.0
+    optionalDependencies:
+      uglify-js: 3.4.10
     dev: true
-    optional: true
 
-  /esbuild-linux-riscv64/0.14.21:
-    resolution: {integrity: 
sha512-fElngqOaOfTsF+u+oetDLHsPG74vB2ZaGZUqmGefAJn3a5z9Z2pNa4WpVbbKgHpaAAy5tWM1m1sbGohj6Ki6+Q==}
-    engines: {node: '>=12'}
-    cpu: [riscv64]
-    os: [linux]
-    requiresBuild: true
+  /har-schema/2.0.0:
+    resolution: {integrity: 
sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==}
+    engines: {node: '>=4'}
     dev: true
-    optional: true
 
-  /esbuild-linux-s390x/0.14.21:
-    resolution: {integrity: 
sha512-brleZ6R5fYv0qQ7ZBwenQmP6i9TdvJCB092c/3D3pTLQHBGHJb5zWgKxOeS7bdHzmLy6a6W7GbFk6QKpjyD6QA==}
-    engines: {node: '>=12'}
-    cpu: [s390x]
-    os: [linux]
-    requiresBuild: true
+  /har-validator/5.1.5:
+    resolution: {integrity: 
sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==}
+    engines: {node: '>=6'}
+    deprecated: this library is no longer supported
+    dependencies:
+      ajv: 6.12.6
+      har-schema: 2.0.0
     dev: true
-    optional: true
 
-  /esbuild-netbsd-64/0.14.21:
-    resolution: {integrity: 
sha512-nCEgsLCQ8RoFWVV8pVI+kX66ICwbPP/M9vEa0NJGIEB/Vs5sVGMqkf67oln90XNSkbc0bPBDuo4G6FxlF7PN8g==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [netbsd]
-    requiresBuild: true
+  /harmony-reflect/1.6.2:
+    resolution: {integrity: 
sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==}
     dev: true
-    optional: true
 
-  /esbuild-openbsd-64/0.14.21:
-    resolution: {integrity: 
sha512-h9zLMyVD0T73MDTVYIb/qUTokwI6EJH9O6wESuTNq6+XpMSr6C5aYZ4fvFKdNELW+Xsod+yDS2hV2JTUAbFrLA==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [openbsd]
-    requiresBuild: true
+  /has-bigints/1.0.1:
+    resolution: {integrity: 
sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==}
     dev: true
-    optional: true
 
-  /esbuild-sunos-64/0.14.21:
-    resolution: {integrity: 
sha512-Kl+7Cot32qd9oqpLdB1tEGXEkjBlijrIxMJ0+vlDFaqsODutif25on0IZlFxEBtL2Gosd4p5WCV1U7UskNQfXA==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [sunos]
-    requiresBuild: true
+  /has-bigints/1.0.2:
+    resolution: {integrity: 
sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==}
     dev: true
-    optional: true
 
-  /esbuild-windows-32/0.14.21:
-    resolution: {integrity: 
sha512-V7vnTq67xPBUCk/9UtlolmQ798Ecjdr1ZoI1vcSgw7M82aSSt0eZdP6bh5KAFZU8pxDcx3qoHyWQfHYr11f22A==}
-    engines: {node: '>=12'}
-    cpu: [ia32]
-    os: [win32]
-    requiresBuild: true
+  /has-color/0.1.7:
+    resolution: {integrity: sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=}
+    engines: {node: '>=0.10.0'}
     dev: true
-    optional: true
 
-  /esbuild-windows-64/0.14.21:
-    resolution: {integrity: 
sha512-kDgHjKOHwjfJDCyRGELzVxiP/RBJBTA+wyspf78MTTJQkyPuxH2vChReNdWc+dU2S4gIZFHMdP1Qrl/k22ZmaA==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [win32]
-    requiresBuild: true
+  /has-flag/3.0.0:
+    resolution: {integrity: 
sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
+    engines: {node: '>=4'}
     dev: true
-    optional: true
 
-  /esbuild-windows-arm64/0.14.21:
-    resolution: {integrity: 
sha512-8Sbo0zpzgwWrwjQYLmHF78f7E2xg5Ve63bjB2ng3V2aManilnnTGaliq2snYg+NOX60+hEvJHRdVnuIAHW0lVw==}
-    engines: {node: '>=12'}
-    cpu: [arm64]
-    os: [win32]
-    requiresBuild: true
+  /has-flag/4.0.0:
+    resolution: {integrity: 
sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+    engines: {node: '>=8'}
     dev: true
-    optional: true
 
-  /esbuild/0.12.29:
-    resolution: {integrity: 
sha512-w/XuoBCSwepyiZtIRsKsetiLDUVGPVw1E/R3VTFSecIy8UR7Cq3SOtwKHJMFoVqqVG36aGkzh4e8BvpO1Fdc7g==}
-    hasBin: true
-    requiresBuild: true
+  /has-glob/1.0.0:
+    resolution: {integrity: 
sha512-D+8A457fBShSEI3tFCj65PAbT++5sKiFtdCdOam0gnfBgw9D277OERk+HM9qYJXmdVLZ/znez10SqHN0BBQ50g==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      is-glob: 3.1.0
     dev: true
 
-  /esbuild/0.14.21:
-    resolution: {integrity: 
sha512-7WEoNMBJdLN993dr9h0CpFHPRc3yFZD+EAVY9lg6syJJ12gc5fHq8d75QRExuhnMkT2DaRiIKFThRvDWP+fO+A==}
-    engines: {node: '>=12'}
-    hasBin: true
-    requiresBuild: true
-    optionalDependencies:
-      esbuild-android-arm64: 0.14.21
-      esbuild-darwin-64: 0.14.21
-      esbuild-darwin-arm64: 0.14.21
-      esbuild-freebsd-64: 0.14.21
-      esbuild-freebsd-arm64: 0.14.21
-      esbuild-linux-32: 0.14.21
-      esbuild-linux-64: 0.14.21
-      esbuild-linux-arm: 0.14.21
-      esbuild-linux-arm64: 0.14.21
-      esbuild-linux-mips64le: 0.14.21
-      esbuild-linux-ppc64le: 0.14.21
-      esbuild-linux-riscv64: 0.14.21
-      esbuild-linux-s390x: 0.14.21
-      esbuild-netbsd-64: 0.14.21
-      esbuild-openbsd-64: 0.14.21
-      esbuild-sunos-64: 0.14.21
-      esbuild-windows-32: 0.14.21
-      esbuild-windows-64: 0.14.21
-      esbuild-windows-arm64: 0.14.21
+  /has-property-descriptors/1.0.0:
+    resolution: {integrity: 
sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==}
+    dependencies:
+      get-intrinsic: 1.1.3
+    dev: true
+
+  /has-symbols/1.0.2:
+    resolution: {integrity: 
sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==}
+    engines: {node: '>= 0.4'}
     dev: true
 
-  /escalade/3.1.1:
-    resolution: {integrity: 
sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
-    engines: {node: '>=6'}
+  /has-symbols/1.0.3:
+    resolution: {integrity: 
sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
+    engines: {node: '>= 0.4'}
     dev: true
 
-  /escape-goat/2.1.1:
-    resolution: {integrity: 
sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==}
-    engines: {node: '>=8'}
+  /has-tostringtag/1.0.0:
+    resolution: {integrity: 
sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      has-symbols: 1.0.2
     dev: true
 
-  /escape-html/1.0.3:
-    resolution: {integrity: sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=}
+  /has-unicode/2.0.1:
+    resolution: {integrity: 
sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==}
     dev: true
 
-  /escape-string-regexp/1.0.5:
-    resolution: {integrity: 
sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
-    engines: {node: '>=0.8.0'}
+  /has-value/0.3.1:
+    resolution: {integrity: 
sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      get-value: 2.0.6
+      has-values: 0.1.4
+      isobject: 2.1.0
     dev: true
 
-  /escape-string-regexp/2.0.0:
-    resolution: {integrity: 
sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==}
-    engines: {node: '>=8'}
+  /has-value/1.0.0:
+    resolution: {integrity: 
sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      get-value: 2.0.6
+      has-values: 1.0.0
+      isobject: 3.0.1
     dev: true
 
-  /escape-string-regexp/4.0.0:
-    resolution: {integrity: 
sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
-    engines: {node: '>=10'}
+  /has-values/0.1.4:
+    resolution: {integrity: 
sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==}
+    engines: {node: '>=0.10.0'}
     dev: true
 
-  /escape-string-regexp/5.0.0:
-    resolution: {integrity: 
sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
-    engines: {node: '>=12'}
+  /has-values/1.0.0:
+    resolution: {integrity: 
sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      is-number: 3.0.0
+      kind-of: 4.0.0
     dev: true
 
-  /escodegen/1.14.3:
-    resolution: {integrity: 
sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==}
-    engines: {node: '>=4.0'}
-    hasBin: true
+  /has-yarn/2.1.0:
+    resolution: {integrity: 
sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==}
+    engines: {node: '>=8'}
+    dev: true
+
+  /has/1.0.3:
+    resolution: {integrity: 
sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
+    engines: {node: '>= 0.4.0'}
     dependencies:
-      esprima: 4.0.1
-      estraverse: 4.3.0
-      esutils: 2.0.3
-      optionator: 0.8.3
-    optionalDependencies:
-      source-map: 0.6.1
+      function-bind: 1.1.1
     dev: true
 
-  /eslint-config-airbnb-base/15.0.0_hexytdhmo422l55jsqymxqfu6q:
-    resolution: {integrity: 
sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==}
-    engines: {node: ^10.12.0 || >=12.0.0}
-    peerDependencies:
-      eslint: ^7.32.0 || ^8.2.0
-      eslint-plugin-import: ^2.25.2
+  /hash-base/3.1.0:
+    resolution: {integrity: 
sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==}
+    engines: {node: '>=4'}
     dependencies:
-      confusing-browser-globals: 1.0.11
-      eslint: 8.8.0
-      eslint-plugin-import: 2.25.4_r2xatzqf7unmty2b7kgqnez6uu
-      object.assign: 4.1.2
-      object.entries: 1.1.5
-      semver: 6.3.0
+      inherits: 2.0.4
+      readable-stream: 3.6.0
+      safe-buffer: 5.2.1
     dev: true
 
-  /eslint-config-airbnb-typescript/16.1.0_fqyt75ttx5czzyyhmxfbzg22fu:
-    resolution: {integrity: 
sha512-W5Cq20KpEx5ZLC54bnVrC37zq2+WD956Kp/Ma3nYFRjT1v9KM63v+DPkrrmmrVqrlDKaD0ivm/qeYmyHV6qKlw==}
-    peerDependencies:
-      '@typescript-eslint/eslint-plugin': ^5.0.0
-      '@typescript-eslint/parser': ^5.0.0
+  /hash-wasm/4.9.0:
+    resolution: {integrity: 
sha512-7SW7ejyfnRxuOc7ptQHSf4LDoZaWOivfzqw+5rpcQku0nHfmicPKE51ra9BiRLAmT8+gGLestr1XroUkqdjL6w==}
+    dev: false
+
+  /hash.js/1.1.7:
+    resolution: {integrity: 
sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==}
     dependencies:
-      '@typescript-eslint/eslint-plugin': 5.36.1_gjcw3hhr2cxnngiu5lw4bi633m
-      '@typescript-eslint/parser': 5.36.1_o2nrgn6wwxunlqlzzokx4es3q4
-      eslint-config-airbnb-base: 15.0.0_hexytdhmo422l55jsqymxqfu6q
-    transitivePeerDependencies:
-      - eslint
-      - eslint-plugin-import
+      inherits: 2.0.4
+      minimalistic-assert: 1.0.1
     dev: true
 
-  /eslint-import-resolver-node/0.3.6:
-    resolution: {integrity: 
sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==}
+  /hasha/4.0.1:
+    resolution: {integrity: 
sha512-+wnvroCn3pq0CAKWfItGPyl0DJOob2qs/2D/Rh0a/O90LBzmo5GaKHwIRb6FInVvmEl1mCIHL5RqlfTLvh6FoQ==}
+    engines: {node: '>=8'}
     dependencies:
-      debug: 3.2.7
-      resolve: 1.21.0
-    transitivePeerDependencies:
-      - supports-color
+      is-stream: 1.1.0
     dev: true
 
-  /eslint-module-utils/2.7.2_632zrvmnhpkgiajg2zqauquf6u:
-    resolution: {integrity: 
sha512-zquepFnWCY2ISMFwD/DqzaM++H+7PDzOpUvotJWm/y1BAFt5R4oeULgdrTejKqLkz7MA/tgstsUMNYc7wNdTrg==}
-    engines: {node: '>=4'}
-    peerDependencies:
-      '@typescript-eslint/parser': '*'
-      eslint-import-resolver-node: '*'
-      eslint-import-resolver-typescript: '*'
-      eslint-import-resolver-webpack: '*'
-    peerDependenciesMeta:
-      '@typescript-eslint/parser':
-        optional: true
-      eslint-import-resolver-node:
-        optional: true
-      eslint-import-resolver-typescript:
-        optional: true
-      eslint-import-resolver-webpack:
-        optional: true
+  /hasha/5.2.2:
+    resolution: {integrity: 
sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==}
+    engines: {node: '>=8'}
     dependencies:
-      '@typescript-eslint/parser': 5.36.1_o2nrgn6wwxunlqlzzokx4es3q4
-      debug: 3.2.7
-      eslint-import-resolver-node: 0.3.6
-      find-up: 2.1.0
-    transitivePeerDependencies:
-      - supports-color
+      is-stream: 2.0.1
+      type-fest: 0.8.1
     dev: true
 
-  /eslint-plugin-header/3.1.1:
-    resolution: {integrity: 
sha512-9vlKxuJ4qf793CmeeSrZUvVClw6amtpghq3CuWcB5cUNnWHQhgcqy5eF8oVKFk1G3Y/CbchGfEaw3wiIJaNmVg==}
-    peerDependencies:
-      eslint: '>=7.7.0'
+  /hast-to-hyperscript/9.0.1:
+    resolution: {integrity: 
sha512-zQgLKqF+O2F72S1aa4y2ivxzSlko3MAvxkwG8ehGmNiqd98BIN3JM1rAJPmplEyLmGLO2QZYJtIneOSZ2YbJuA==}
+    dependencies:
+      '@types/unist': 2.0.6
+      comma-separated-tokens: 1.0.8
+      property-information: 5.6.0
+      space-separated-tokens: 1.1.5
+      style-to-object: 0.3.0
+      unist-util-is: 4.1.0
+      web-namespaces: 1.1.4
     dev: true
 
-  /eslint-plugin-import/2.25.4_r2xatzqf7unmty2b7kgqnez6uu:
-    resolution: {integrity: 
sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==}
-    engines: {node: '>=4'}
-    peerDependencies:
-      '@typescript-eslint/parser': '*'
-      eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8
-    peerDependenciesMeta:
-      '@typescript-eslint/parser':
-        optional: true
+  /hast-util-from-parse5/6.0.1:
+    resolution: {integrity: 
sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA==}
     dependencies:
-      '@typescript-eslint/parser': 5.36.1_o2nrgn6wwxunlqlzzokx4es3q4
-      array-includes: 3.1.4
-      array.prototype.flat: 1.2.5
-      debug: 2.6.9
-      doctrine: 2.1.0
-      eslint: 8.8.0
-      eslint-import-resolver-node: 0.3.6
-      eslint-module-utils: 2.7.2_632zrvmnhpkgiajg2zqauquf6u
-      has: 1.0.3
-      is-core-module: 2.8.0
-      is-glob: 4.0.3
-      minimatch: 3.0.4
-      object.values: 1.1.5
-      resolve: 1.21.0
-      tsconfig-paths: 3.12.0
-    transitivePeerDependencies:
-      - eslint-import-resolver-typescript
-      - eslint-import-resolver-webpack
-      - supports-color
+      '@types/parse5': 5.0.3
+      hastscript: 6.0.0
+      property-information: 5.6.0
+      vfile: 4.2.1
+      vfile-location: 3.2.0
+      web-namespaces: 1.1.4
     dev: true
 
-  /eslint-plugin-jsx-a11y/6.5.1_eslint@8.8.0:
-    resolution: {integrity: 
sha512-sVCFKX9fllURnXT2JwLN5Qgo24Ug5NF6dxhkmxsMEUZhXRcGg+X3e1JbJ84YePQKBl5E0ZjAH5Q4rkdcGY99+g==}
-    engines: {node: '>=4.0'}
-    peerDependencies:
-      eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8
+  /hast-util-parse-selector/2.2.5:
+    resolution: {integrity: 
sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==}
+    dev: true
+
+  /hast-util-raw/6.0.1:
+    resolution: {integrity: 
sha512-ZMuiYA+UF7BXBtsTBNcLBF5HzXzkyE6MLzJnL605LKE8GJylNjGc4jjxazAHUtcwT5/CEt6afRKViYB4X66dig==}
     dependencies:
-      '@babel/runtime': 7.16.7
-      aria-query: 4.2.2
-      array-includes: 3.1.4
-      ast-types-flow: 0.0.7
-      axe-core: 4.3.5
-      axobject-query: 2.2.0
-      damerau-levenshtein: 1.0.7
-      emoji-regex: 9.2.2
-      eslint: 8.8.0
-      has: 1.0.3
-      jsx-ast-utils: 3.2.1
-      language-tags: 1.0.5
-      minimatch: 3.0.4
+      '@types/hast': 2.3.4
+      hast-util-from-parse5: 6.0.1
+      hast-util-to-parse5: 6.0.0
+      html-void-elements: 1.0.5
+      parse5: 6.0.1
+      unist-util-position: 3.1.0
+      vfile: 4.2.1
+      web-namespaces: 1.1.4
+      xtend: 4.0.2
+      zwitch: 1.0.5
     dev: true
 
-  /eslint-plugin-react-hooks/4.3.0_eslint@8.8.0:
-    resolution: {integrity: 
sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA==}
-    engines: {node: '>=10'}
-    peerDependencies:
-      eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0
+  /hast-util-to-parse5/6.0.0:
+    resolution: {integrity: 
sha512-Lu5m6Lgm/fWuz8eWnrKezHtVY83JeRGaNQ2kn9aJgqaxvVkFCZQBEhgodZUDUvoodgyROHDb3r5IxAEdl6suJQ==}
     dependencies:
-      eslint: 8.8.0
+      hast-to-hyperscript: 9.0.1
+      property-information: 5.6.0
+      web-namespaces: 1.1.4
+      xtend: 4.0.2
+      zwitch: 1.0.5
     dev: true
 
-  /eslint-plugin-react/7.28.0_eslint@8.8.0:
-    resolution: {integrity: 
sha512-IOlFIRHzWfEQQKcAD4iyYDndHwTQiCMcJVJjxempf203jnNLUnW34AXLrV33+nEXoifJE2ZEGmcjKPL8957eSw==}
-    engines: {node: '>=4'}
-    peerDependencies:
-      eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8
+  /hastscript/6.0.0:
+    resolution: {integrity: 
sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==}
     dependencies:
-      array-includes: 3.1.4
-      array.prototype.flatmap: 1.2.5
-      doctrine: 2.1.0
-      eslint: 8.8.0
-      estraverse: 5.3.0
-      jsx-ast-utils: 3.2.1
-      minimatch: 3.0.5
-      object.entries: 1.1.5
-      object.fromentries: 2.0.5
-      object.hasown: 1.1.0
-      object.values: 1.1.5
-      prop-types: 15.8.1
-      resolve: 2.0.0-next.3
-      semver: 6.3.0
-      string.prototype.matchall: 4.0.6
+      '@types/hast': 2.3.4
+      comma-separated-tokens: 1.0.8
+      hast-util-parse-selector: 2.2.5
+      property-information: 5.6.0
+      space-separated-tokens: 1.1.5
     dev: true
 
-  /eslint-scope/4.0.3:
-    resolution: {integrity: 
sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==}
-    engines: {node: '>=4.0.0'}
+  /he/1.2.0:
+    resolution: {integrity: 
sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
+    hasBin: true
+    dev: true
+
+  /hex-color-regex/1.1.0:
+    resolution: {integrity: 
sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==}
+    dev: true
+
+  /highlight.js/10.7.3:
+    resolution: {integrity: 
sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==}
+    dev: true
+
+  /history/4.10.1:
+    resolution: {integrity: 
sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==}
     dependencies:
-      esrecurse: 4.3.0
-      estraverse: 4.3.0
+      '@babel/runtime': 7.15.3
+      loose-envify: 1.4.0
+      resolve-pathname: 3.0.0
+      tiny-invariant: 1.1.0
+      tiny-warning: 1.0.3
+      value-equal: 1.0.1
+    dev: false
+
+  /hmac-drbg/1.0.1:
+    resolution: {integrity: 
sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==}
+    dependencies:
+      hash.js: 1.1.7
+      minimalistic-assert: 1.0.1
+      minimalistic-crypto-utils: 1.0.1
     dev: true
 
-  /eslint-scope/5.1.1:
-    resolution: {integrity: 
sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==}
-    engines: {node: '>=8.0.0'}
+  /hoist-non-react-statics/3.3.2:
+    resolution: {integrity: 
sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==}
     dependencies:
-      esrecurse: 4.3.0
-      estraverse: 4.3.0
+      react-is: 16.13.1
+    dev: true
+
+  /hoopy/0.1.4:
+    resolution: {integrity: 
sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==}
+    engines: {node: '>= 6.0.0'}
     dev: true
 
-  /eslint-scope/7.1.0:
-    resolution: {integrity: 
sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
-    dependencies:
-      esrecurse: 4.3.0
-      estraverse: 5.3.0
+  /hosted-git-info/2.8.9:
+    resolution: {integrity: 
sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==}
     dev: true
 
-  /eslint-utils/3.0.0_eslint@8.8.0:
-    resolution: {integrity: 
sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==}
-    engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0}
-    peerDependencies:
-      eslint: '>=5'
+  /hpack.js/2.1.6:
+    resolution: {integrity: 
sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==}
     dependencies:
-      eslint: 8.8.0
-      eslint-visitor-keys: 2.1.0
+      inherits: 2.0.4
+      obuf: 1.1.2
+      readable-stream: 2.3.7
+      wbuf: 1.7.3
     dev: true
 
-  /eslint-visitor-keys/2.1.0:
-    resolution: {integrity: 
sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==}
-    engines: {node: '>=10'}
+  /hsl-regex/1.0.0:
+    resolution: {integrity: 
sha512-M5ezZw4LzXbBKMruP+BNANf0k+19hDQMgpzBIYnya//Al+fjNct9Wf3b1WedLqdEs2hKBvxq/jh+DsHJLj0F9A==}
     dev: true
 
-  /eslint-visitor-keys/3.2.0:
-    resolution: {integrity: 
sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+  /hsla-regex/1.0.0:
+    resolution: {integrity: 
sha512-7Wn5GMLuHBjZCb2bTmnDOycho0p/7UVaAeqXZGbHrBCl6Yd/xDhQJAXe6Ga9AXJH2I5zY1dEdYw2u1UptnSBJA==}
     dev: true
 
-  /eslint-visitor-keys/3.3.0:
-    resolution: {integrity: 
sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+  /html-element-map/1.3.1:
+    resolution: {integrity: 
sha512-6XMlxrAFX4UEEGxctfFnmrFaaZFNf9i5fNuV5wZ3WWQ4FVaNP1aX1LkX9j2mfEx1NpjeE/rL3nmgEn23GdFmrg==}
+    dependencies:
+      array.prototype.filter: 1.0.1
+      call-bind: 1.0.2
     dev: true
 
-  /eslint/8.8.0:
-    resolution: {integrity: 
sha512-H3KXAzQGBH1plhYS3okDix2ZthuYJlQQEGE5k0IKuEqUSiyu4AmxxlJ2MtTYeJ3xB4jDhcYCwGOg2TXYdnDXlQ==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
-    hasBin: true
+  /html-encoding-sniffer/1.0.2:
+    resolution: {integrity: 
sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==}
     dependencies:
-      '@eslint/eslintrc': 1.0.5
-      '@humanwhocodes/config-array': 0.9.3
-      ajv: 6.12.6
-      chalk: 4.1.2
-      cross-spawn: 7.0.3
-      debug: 4.3.3
-      doctrine: 3.0.0
-      escape-string-regexp: 4.0.0
-      eslint-scope: 7.1.0
-      eslint-utils: 3.0.0_eslint@8.8.0
-      eslint-visitor-keys: 3.2.0
-      espree: 9.3.0
-      esquery: 1.4.0
-      esutils: 2.0.3
-      fast-deep-equal: 3.1.3
-      file-entry-cache: 6.0.1
-      functional-red-black-tree: 1.0.1
-      glob-parent: 6.0.2
-      globals: 13.12.1
-      ignore: 5.2.0
-      import-fresh: 3.3.0
-      imurmurhash: 0.1.4
-      is-glob: 4.0.3
-      js-yaml: 4.1.0
-      json-stable-stringify-without-jsonify: 1.0.1
-      levn: 0.4.1
-      lodash.merge: 4.6.2
-      minimatch: 3.0.5
-      natural-compare: 1.4.0
-      optionator: 0.9.1
-      regexpp: 3.2.0
-      strip-ansi: 6.0.1
-      strip-json-comments: 3.1.1
-      text-table: 0.2.0
-      v8-compile-cache: 2.3.0
-    transitivePeerDependencies:
-      - supports-color
+      whatwg-encoding: 1.0.5
     dev: true
 
-  /esm/3.2.25:
-    resolution: {integrity: 
sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==}
-    engines: {node: '>=6'}
+  /html-encoding-sniffer/2.0.1:
+    resolution: {integrity: 
sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==}
+    engines: {node: '>=10'}
+    dependencies:
+      whatwg-encoding: 1.0.5
     dev: true
 
-  /espree/9.3.0:
-    resolution: {integrity: 
sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
-    dependencies:
-      acorn: 8.7.0
-      acorn-jsx: 5.3.2_acorn@8.7.0
-      eslint-visitor-keys: 3.2.0
+  /html-entities/1.4.0:
+    resolution: {integrity: 
sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==}
     dev: true
 
-  /esprima/4.0.1:
-    resolution: {integrity: 
sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
-    engines: {node: '>=4'}
-    hasBin: true
+  /html-entities/2.3.2:
+    resolution: {integrity: 
sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ==}
     dev: true
 
-  /esquery/1.4.0:
-    resolution: {integrity: 
sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==}
-    engines: {node: '>=0.10'}
-    dependencies:
-      estraverse: 5.3.0
+  /html-escaper/2.0.2:
+    resolution: {integrity: 
sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
     dev: true
 
-  /esrecurse/4.3.0:
-    resolution: {integrity: 
sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
-    engines: {node: '>=4.0'}
+  /html-minifier-terser/5.1.1:
+    resolution: {integrity: 
sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg==}
+    engines: {node: '>=6'}
+    hasBin: true
     dependencies:
-      estraverse: 5.3.0
+      camel-case: 4.1.2
+      clean-css: 4.2.4
+      commander: 4.1.1
+      he: 1.2.0
+      param-case: 3.0.4
+      relateurl: 0.2.7
+      terser: 4.8.0
     dev: true
 
-  /estraverse/4.3.0:
-    resolution: {integrity: 
sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==}
-    engines: {node: '>=4.0'}
+  /html-minifier/3.5.21:
+    resolution: {integrity: 
sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==}
+    engines: {node: '>=4'}
+    hasBin: true
+    dependencies:
+      camel-case: 3.0.0
+      clean-css: 4.2.4
+      commander: 2.17.1
+      he: 1.2.0
+      param-case: 2.1.1
+      relateurl: 0.2.7
+      uglify-js: 3.4.10
     dev: true
 
-  /estraverse/5.3.0:
-    resolution: {integrity: 
sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
-    engines: {node: '>=4.0'}
+  /html-tags/3.2.0:
+    resolution: {integrity: 
sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==}
+    engines: {node: '>=8'}
     dev: true
 
-  /estree-walker/1.0.1:
-    resolution: {integrity: 
sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==}
+  /html-void-elements/1.0.5:
+    resolution: {integrity: 
sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w==}
     dev: true
 
-  /estree-walker/2.0.2:
-    resolution: {integrity: 
sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+  /html-webpack-exclude-assets-plugin/0.0.7:
+    resolution: {integrity: 
sha512-gaYKMGBPDts3Fb1WXyDEEcS/0TSRg2IDl3EsbQL2AkKWTqdjSKwfQ8Iz0RhPiWErJfqhq5/wkhoYyjQoG55pug==}
+    engines: {node: '>=4.0.0'}
     dev: true
 
-  /esutils/2.0.3:
-    resolution: {integrity: 
sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
-    engines: {node: '>=0.10.0'}
+  /html-webpack-inline-chunk-plugin/1.1.1:
+    resolution: {integrity: 
sha512-0cor73re8PI/BG2W+jCkZxob8duoLG1COQLFZ3cT8G1VBzyKE7wQRpLkl79BjJw3epntnVg17n2z7Y6McJijaA==}
+    dependencies:
+      lodash: 4.17.21
+      source-map-url: 0.4.1
     dev: true
 
-  /etag/1.8.1:
-    resolution: {integrity: sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=}
-    engines: {node: '>= 0.6'}
+  /html-webpack-inline-source-plugin/0.0.10:
+    resolution: {integrity: 
sha512-0ZNU57u7283vrXSF5a4VDnVOMWiSwypKIp1z/XfXWoVHLA1r3Xmyxx5+Lz+mnthz/UvxL1OAf41w5UIF68Jngw==}
+    dependencies:
+      escape-string-regexp: 1.0.5
+      slash: 1.0.0
+      source-map-url: 0.4.1
     dev: true
 
-  /eventemitter3/4.0.7:
-    resolution: {integrity: 
sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==}
+  /html-webpack-plugin/3.2.0_webpack@4.46.0:
+    resolution: {integrity: 
sha512-Br4ifmjQojUP4EmHnRBoUIYcZ9J7M4bTMcm7u6xoIAIuq2Nte4TzXX0533owvkQKQD1WeMTTTyD4Ni4QKxS0Bg==}
+    engines: {node: '>=6.9'}
+    deprecated: 3.x is no longer supported
+    peerDependencies:
+      webpack: ^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.0
+    dependencies:
+      html-minifier: 3.5.21
+      loader-utils: 0.2.17
+      lodash: 4.17.21
+      pretty-error: 2.1.2
+      tapable: 1.1.3
+      toposort: 1.0.7
+      util.promisify: 1.0.0
+      webpack: 4.46.0
     dev: true
 
-  /events/3.3.0:
-    resolution: {integrity: 
sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
-    engines: {node: '>=0.8.x'}
+  /html-webpack-plugin/4.5.2_webpack@4.46.0:
+    resolution: {integrity: 
sha512-q5oYdzjKUIPQVjOosjgvCHQOv9Ett9CYYHlgvJeXG0qQvdSojnBq4vAdQBwn1+yGveAwHCoe/rMR86ozX3+c2A==}
+    engines: {node: '>=6.9'}
+    peerDependencies:
+      webpack: ^4.0.0 || ^5.0.0
+    dependencies:
+      '@types/html-minifier-terser': 5.1.2
+      '@types/tapable': 1.0.8
+      '@types/webpack': 4.41.32
+      html-minifier-terser: 5.1.1
+      loader-utils: 1.4.0
+      lodash: 4.17.21
+      pretty-error: 2.1.2
+      tapable: 1.1.3
+      util.promisify: 1.0.0
+      webpack: 4.46.0
     dev: true
 
-  /evp_bytestokey/1.0.3:
-    resolution: {integrity: 
sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==}
+  /html-webpack-skip-assets-plugin/1.0.3:
+    resolution: {integrity: 
sha512-vpdh+JZGlE1Df3IftH2gw5P7b6yfTsahcOIJnkkkj5iJU9dUStXgzgALoXWwl8+17wWgFm3edcJzeYTJBYfMAw==}
+    peerDependencies:
+      html-webpack-plugin: '>=3.0.0'
+      webpack: '>=3.0.0'
     dependencies:
-      md5.js: 1.3.5
-      safe-buffer: 5.2.1
+      minimatch: 3.0.4
     dev: true
 
-  /execa/5.1.1:
-    resolution: {integrity: 
sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
-    engines: {node: '>=10'}
+  /htmlparser2/6.1.0:
+    resolution: {integrity: 
sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==}
     dependencies:
-      cross-spawn: 7.0.3
-      get-stream: 6.0.1
-      human-signals: 2.1.0
-      is-stream: 2.0.1
-      merge-stream: 2.0.0
-      npm-run-path: 4.0.1
-      onetime: 5.1.2
-      signal-exit: 3.0.7
-      strip-final-newline: 2.0.0
+      domelementtype: 2.3.0
+      domhandler: 4.3.0
+      domutils: 2.8.0
+      entities: 2.2.0
     dev: true
 
-  /expand-brackets/2.1.4:
-    resolution: {integrity: sha1-t3c14xXOMPa27/D4OwQVGiJEliI=}
-    engines: {node: '>=0.10.0'}
+  /htmlparser2/8.0.1:
+    resolution: {integrity: 
sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==}
     dependencies:
-      debug: 2.6.9
-      define-property: 0.2.5
-      extend-shallow: 2.0.1
-      posix-character-classes: 0.1.1
-      regex-not: 1.0.2
-      snapdragon: 0.8.2
-      to-regex: 3.0.2
-    transitivePeerDependencies:
-      - supports-color
+      domelementtype: 2.3.0
+      domhandler: 5.0.3
+      domutils: 3.0.1
+      entities: 4.4.0
     dev: true
 
-  /express/4.17.2:
-    resolution: {integrity: 
sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg==}
-    engines: {node: '>= 0.10.0'}
-    dependencies:
-      accepts: 1.3.8
-      array-flatten: 1.1.1
-      body-parser: 1.19.1
-      content-disposition: 0.5.4
-      content-type: 1.0.4
-      cookie: 0.4.1
-      cookie-signature: 1.0.6
-      debug: 2.6.9
-      depd: 1.1.2
-      encodeurl: 1.0.2
-      escape-html: 1.0.3
-      etag: 1.8.1
-      finalhandler: 1.1.2
-      fresh: 0.5.2
-      merge-descriptors: 1.0.1
-      methods: 1.1.2
-      on-finished: 2.3.0
-      parseurl: 1.3.3
-      path-to-regexp: 0.1.7
-      proxy-addr: 2.0.7
-      qs: 6.9.6
-      range-parser: 1.2.1
-      safe-buffer: 5.2.1
-      send: 0.17.2
-      serve-static: 1.14.2
-      setprototypeof: 1.2.0
-      statuses: 1.5.0
-      type-is: 1.6.18
-      utils-merge: 1.0.1
-      vary: 1.1.2
-    transitivePeerDependencies:
-      - supports-color
+  /http-cache-semantics/4.1.0:
+    resolution: {integrity: 
sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==}
     dev: true
 
-  /extend-shallow/2.0.1:
-    resolution: {integrity: sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=}
-    engines: {node: '>=0.10.0'}
+  /http-deceiver/1.2.7:
+    resolution: {integrity: 
sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==}
+    dev: true
+
+  /http-errors/1.6.3:
+    resolution: {integrity: 
sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==}
+    engines: {node: '>= 0.6'}
     dependencies:
-      is-extendable: 0.1.1
+      depd: 1.1.2
+      inherits: 2.0.3
+      setprototypeof: 1.1.0
+      statuses: 1.5.0
     dev: true
 
-  /extend-shallow/3.0.2:
-    resolution: {integrity: sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=}
-    engines: {node: '>=0.10.0'}
+  /http-errors/1.8.1:
+    resolution: {integrity: 
sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==}
+    engines: {node: '>= 0.6'}
     dependencies:
-      assign-symbols: 1.0.0
-      is-extendable: 1.0.1
+      depd: 1.1.2
+      inherits: 2.0.4
+      setprototypeof: 1.2.0
+      statuses: 1.5.0
+      toidentifier: 1.0.1
     dev: true
 
-  /extend/3.0.2:
-    resolution: {integrity: 
sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
+  /http-parser-js/0.5.5:
+    resolution: {integrity: 
sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA==}
     dev: true
 
-  /extglob/2.0.4:
-    resolution: {integrity: 
sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==}
-    engines: {node: '>=0.10.0'}
+  /http-proxy-agent/4.0.1:
+    resolution: {integrity: 
sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==}
+    engines: {node: '>= 6'}
     dependencies:
-      array-unique: 0.3.2
-      define-property: 1.0.0
-      expand-brackets: 2.1.4
-      extend-shallow: 2.0.1
-      fragment-cache: 0.2.1
-      regex-not: 1.0.2
-      snapdragon: 0.8.2
-      to-regex: 3.0.2
+      '@tootallnate/once': 1.1.2
+      agent-base: 6.0.2
+      debug: 4.3.4
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /extsprintf/1.3.0:
-    resolution: {integrity: sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=}
-    engines: {'0': node >=0.6.0}
-    dev: true
-
-  /fast-deep-equal/3.1.3:
-    resolution: {integrity: 
sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+  /http-proxy-middleware/0.19.1_tmpgdztspuwvsxzgjkhoqk7duq:
+    resolution: {integrity: 
sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==}
+    engines: {node: '>=4.0.0'}
+    dependencies:
+      http-proxy: 1.18.1_debug@4.3.4
+      is-glob: 4.0.3
+      lodash: 4.17.21
+      micromatch: 3.1.10_supports-color@6.1.0
+    transitivePeerDependencies:
+      - debug
+      - supports-color
     dev: true
 
-  /fast-diff/1.2.0:
-    resolution: {integrity: 
sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==}
+  /http-proxy-middleware/2.0.3_@types+express@4.17.13:
+    resolution: {integrity: 
sha512-1bloEwnrHMnCoO/Gcwbz7eSVvW50KPES01PecpagI+YLNLci4AcuKJrujW4Mc3sBLpFxMSlsLNHS5Nl/lvrTPA==}
+    engines: {node: '>=12.0.0'}
+    peerDependencies:
+      '@types/express': ^4.17.13
+    peerDependenciesMeta:
+      '@types/express':
+        optional: true
+    dependencies:
+      '@types/express': 4.17.13
+      '@types/http-proxy': 1.17.8
+      http-proxy: 1.18.1
+      is-glob: 4.0.3
+      is-plain-obj: 3.0.0
+      micromatch: 4.0.5
+    transitivePeerDependencies:
+      - debug
     dev: true
 
-  /fast-glob/3.2.11:
-    resolution: {integrity: 
sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==}
-    engines: {node: '>=8.6.0'}
+  /http-proxy/1.18.1:
+    resolution: {integrity: 
sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==}
+    engines: {node: '>=8.0.0'}
     dependencies:
-      '@nodelib/fs.stat': 2.0.5
-      '@nodelib/fs.walk': 1.2.8
-      glob-parent: 5.1.2
-      merge2: 1.4.1
-      micromatch: 4.0.4
+      eventemitter3: 4.0.7
+      follow-redirects: 1.15.2
+      requires-port: 1.0.0
+    transitivePeerDependencies:
+      - debug
     dev: true
 
-  /fast-glob/3.2.12:
-    resolution: {integrity: 
sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==}
-    engines: {node: '>=8.6.0'}
+  /http-proxy/1.18.1_debug@4.3.4:
+    resolution: {integrity: 
sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==}
+    engines: {node: '>=8.0.0'}
     dependencies:
-      '@nodelib/fs.stat': 2.0.5
-      '@nodelib/fs.walk': 1.2.8
-      glob-parent: 5.1.2
-      merge2: 1.4.1
-      micromatch: 4.0.5
+      eventemitter3: 4.0.7
+      follow-redirects: 1.15.2
+      requires-port: 1.0.0
+    transitivePeerDependencies:
+      - debug
     dev: true
 
-  /fast-json-stable-stringify/2.1.0:
-    resolution: {integrity: 
sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
+  /http-signature/1.2.0:
+    resolution: {integrity: 
sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==}
+    engines: {node: '>=0.8', npm: '>=1.3.7'}
+    dependencies:
+      assert-plus: 1.0.0
+      jsprim: 1.4.2
+      sshpk: 1.17.0
     dev: true
 
-  /fast-levenshtein/2.0.6:
-    resolution: {integrity: sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=}
+  /https-browserify/1.0.0:
+    resolution: {integrity: 
sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==}
     dev: true
 
-  /fastq/1.13.0:
-    resolution: {integrity: 
sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==}
+  /https-proxy-agent/5.0.1:
+    resolution: {integrity: 
sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
+    engines: {node: '>= 6'}
     dependencies:
-      reusify: 1.0.4
+      agent-base: 6.0.2
+      debug: 4.3.4
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /faye-websocket/0.11.4:
-    resolution: {integrity: 
sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==}
-    engines: {node: '>=0.8.0'}
-    dependencies:
-      websocket-driver: 0.7.4
+  /human-signals/1.1.1:
+    resolution: {integrity: 
sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==}
+    engines: {node: '>=8.12.0'}
     dev: true
 
-  /fetch-blob/3.1.4:
-    resolution: {integrity: 
sha512-Eq5Xv5+VlSrYWEqKrusxY1C3Hm/hjeAsCGVG3ft7pZahlUAChpGZT/Ms1WmSLnEAisEXszjzu/s+ce6HZB2VHA==}
-    engines: {node: ^12.20 || >= 14.13}
-    dependencies:
-      node-domexception: 1.0.0
-      web-streams-polyfill: 3.2.0
-    dev: false
+  /human-signals/2.1.0:
+    resolution: {integrity: 
sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
+    engines: {node: '>=10.17.0'}
+    dev: true
 
-  /fetch-ponyfill/7.1.0:
-    resolution: {integrity: 
sha512-FhbbL55dj/qdVO3YNK7ZEkshvj3eQ7EuIGV2I6ic/2YiocvyWv+7jg2s4AyS0wdRU75s3tA8ZxI/xPigb0v5Aw==}
+  /iconv-lite/0.4.24:
+    resolution: {integrity: 
sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
+    engines: {node: '>=0.10.0'}
     dependencies:
-      node-fetch: 2.6.7
-    transitivePeerDependencies:
-      - encoding
-    dev: false
-
-  /fflate/0.7.4:
-    resolution: {integrity: 
sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==}
-    dev: false
-
-  /figgy-pudding/3.5.2:
-    resolution: {integrity: 
sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==}
+      safer-buffer: 2.1.2
     dev: true
 
-  /figures/4.0.1:
-    resolution: {integrity: 
sha512-rElJwkA/xS04Vfg+CaZodpso7VqBknOYbzi6I76hI4X80RUjkSxO2oAyPmGbuXUppywjqndOrQDl817hDnI++w==}
-    engines: {node: '>=12'}
+  /iconv-lite/0.6.3:
+    resolution: {integrity: 
sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
+    engines: {node: '>=0.10.0'}
     dependencies:
-      escape-string-regexp: 5.0.0
-      is-unicode-supported: 1.3.0
+      safer-buffer: 2.1.2
     dev: true
 
-  /file-entry-cache/6.0.1:
-    resolution: {integrity: 
sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
-    engines: {node: ^10.12.0 || >=12.0.0}
+  /icss-utils/4.1.1:
+    resolution: {integrity: 
sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==}
+    engines: {node: '>= 6'}
     dependencies:
-      flat-cache: 3.0.4
+      postcss: 7.0.39
     dev: true
 
-  /file-loader/6.2.0_webpack@4.46.0:
-    resolution: {integrity: 
sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==}
-    engines: {node: '>= 10.13.0'}
+  /icss-utils/5.1.0_postcss@8.4.6:
+    resolution: {integrity: 
sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==}
+    engines: {node: ^10 || ^12 || >= 14}
     peerDependencies:
-      webpack: ^4.0.0 || ^5.0.0
+      postcss: ^8.1.0
     dependencies:
-      loader-utils: 2.0.2
-      schema-utils: 3.1.1
-      webpack: 4.46.0
+      postcss: 8.4.6
     dev: true
 
-  /file-uri-to-path/1.0.0:
-    resolution: {integrity: 
sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
-    requiresBuild: true
+  /idb/6.1.5:
+    resolution: {integrity: 
sha512-IJtugpKkiVXQn5Y+LteyBCNk1N8xpGV3wWZk9EVtZWH8DYkjBn0bX1XnGP9RkyZF0sAcywa6unHqSWKe7q4LGw==}
     dev: true
-    optional: true
 
-  /filelist/1.0.2:
-    resolution: {integrity: 
sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==}
+  /identity-obj-proxy/3.0.0:
+    resolution: {integrity: 
sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==}
+    engines: {node: '>=4'}
     dependencies:
-      minimatch: 3.0.5
+      harmony-reflect: 1.6.2
     dev: true
 
-  /fill-range/4.0.0:
-    resolution: {integrity: 
sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==}
-    engines: {node: '>=0.10.0'}
-    dependencies:
-      extend-shallow: 2.0.1
-      is-number: 3.0.0
-      repeat-string: 1.6.1
-      to-regex-range: 2.1.1
+  /ieee754/1.2.1:
+    resolution: {integrity: 
sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
     dev: true
 
-  /fill-range/7.0.1:
-    resolution: {integrity: 
sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
-    engines: {node: '>=8'}
-    dependencies:
-      to-regex-range: 5.0.1
+  /iferr/0.1.5:
+    resolution: {integrity: 
sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA==}
     dev: true
 
-  /finalhandler/1.1.2:
-    resolution: {integrity: 
sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==}
-    engines: {node: '>= 0.8'}
-    dependencies:
-      debug: 2.6.9
-      encodeurl: 1.0.2
-      escape-html: 1.0.3
-      on-finished: 2.3.0
-      parseurl: 1.3.3
-      statuses: 1.5.0
-      unpipe: 1.0.0
-    transitivePeerDependencies:
-      - supports-color
+  /ignore-by-default/2.1.0:
+    resolution: {integrity: 
sha512-yiWd4GVmJp0Q6ghmM2B/V3oZGRmjrKLXvHR3TE1nfoXsmoggllfZUQe74EN0fJdPFZu2NIvNdrMMLm3OsV7Ohw==}
+    engines: {node: '>=10 <11 || >=12 <13 || >=14'}
     dev: true
 
-  /find-cache-dir/2.1.0:
-    resolution: {integrity: 
sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==}
-    engines: {node: '>=6'}
-    dependencies:
-      commondir: 1.0.1
-      make-dir: 2.1.0
-      pkg-dir: 3.0.0
+  /ignore/3.3.10:
+    resolution: {integrity: 
sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==}
     dev: true
 
-  /find-cache-dir/3.3.2:
-    resolution: {integrity: 
sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==}
-    engines: {node: '>=8'}
-    dependencies:
-      commondir: 1.0.1
-      make-dir: 3.1.0
-      pkg-dir: 4.2.0
+  /ignore/4.0.6:
+    resolution: {integrity: 
sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==}
+    engines: {node: '>= 4'}
     dev: true
 
-  /find-up/2.1.0:
-    resolution: {integrity: sha1-RdG35QbHF93UgndaK3eSCjwMV6c=}
-    engines: {node: '>=4'}
-    dependencies:
-      locate-path: 2.0.0
+  /ignore/5.2.0:
+    resolution: {integrity: 
sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==}
+    engines: {node: '>= 4'}
     dev: true
 
-  /find-up/3.0.0:
-    resolution: {integrity: 
sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==}
-    engines: {node: '>=6'}
+  /immer/8.0.1:
+    resolution: {integrity: 
sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA==}
+    dev: true
+
+  /import-cwd/2.1.0:
+    resolution: {integrity: 
sha512-Ew5AZzJQFqrOV5BTW3EIoHAnoie1LojZLXKcCQ/yTRyVZosBhK1x1ViYjHGf5pAFOq8ZyChZp6m/fSN7pJyZtg==}
+    engines: {node: '>=4'}
     dependencies:
-      locate-path: 3.0.0
+      import-from: 2.1.0
     dev: true
 
-  /find-up/4.1.0:
-    resolution: {integrity: 
sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
-    engines: {node: '>=8'}
+  /import-fresh/2.0.0:
+    resolution: {integrity: 
sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==}
+    engines: {node: '>=4'}
     dependencies:
-      locate-path: 5.0.0
-      path-exists: 4.0.0
+      caller-path: 2.0.0
+      resolve-from: 3.0.0
     dev: true
 
-  /find-up/5.0.0:
-    resolution: {integrity: 
sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
-    engines: {node: '>=10'}
+  /import-fresh/3.3.0:
+    resolution: {integrity: 
sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
+    engines: {node: '>=6'}
     dependencies:
-      locate-path: 6.0.0
-      path-exists: 4.0.0
+      parent-module: 1.0.1
+      resolve-from: 4.0.0
     dev: true
 
-  /find-up/6.3.0:
-    resolution: {integrity: 
sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==}
-    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+  /import-from/2.1.0:
+    resolution: {integrity: 
sha512-0vdnLL2wSGnhlRmzHJAg5JHjt1l2vYhzJ7tNLGbeVg0fse56tpGaH0uzH+r9Slej+BSXXEHvBKDEnVSLLE9/+w==}
+    engines: {node: '>=4'}
     dependencies:
-      locate-path: 7.1.1
-      path-exists: 5.0.0
+      resolve-from: 3.0.0
     dev: true
 
-  /find-yarn-workspace-root/1.2.1:
-    resolution: {integrity: 
sha512-dVtfb0WuQG+8Ag2uWkbG79hOUzEsRrhBzgfn86g2sJPkzmcpGdghbNTfUKGTxymFrY/tLIodDzLoW9nOJ4FY8Q==}
-    dependencies:
-      fs-extra: 4.0.3
-      micromatch: 3.1.10
-    transitivePeerDependencies:
-      - supports-color
+  /import-lazy/2.1.0:
+    resolution: {integrity: 
sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A==}
+    engines: {node: '>=4'}
     dev: true
 
-  /flat-cache/3.0.4:
-    resolution: {integrity: 
sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==}
-    engines: {node: ^10.12.0 || >=12.0.0}
+  /import-local/2.0.0:
+    resolution: {integrity: 
sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==}
+    engines: {node: '>=6'}
+    hasBin: true
     dependencies:
-      flatted: 3.2.5
-      rimraf: 3.0.2
+      pkg-dir: 3.0.0
+      resolve-cwd: 2.0.0
     dev: true
 
-  /flat/5.0.2:
-    resolution: {integrity: 
sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==}
+  /import-local/3.1.0:
+    resolution: {integrity: 
sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==}
+    engines: {node: '>=8'}
     hasBin: true
+    dependencies:
+      pkg-dir: 4.2.0
+      resolve-cwd: 3.0.0
     dev: true
 
-  /flatted/3.2.5:
-    resolution: {integrity: 
sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==}
+  /imurmurhash/0.1.4:
+    resolution: {integrity: 
sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
+    engines: {node: '>=0.8.19'}
     dev: true
 
-  /flush-write-stream/1.1.1:
-    resolution: {integrity: 
sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==}
+  /indent-string/2.1.0:
+    resolution: {integrity: 
sha512-aqwDFWSgSgfRaEwao5lg5KEcVd/2a+D1rvoG7NdilmYz0NwRk6StWpWdz/Hpk34MKPpx7s8XxUqimfcQK6gGlg==}
+    engines: {node: '>=0.10.0'}
     dependencies:
-      inherits: 2.0.4
-      readable-stream: 2.3.7
+      repeating: 2.0.1
     dev: true
+    optional: true
 
-  /follow-redirects/1.14.8:
-    resolution: {integrity: 
sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==}
-    engines: {node: '>=4.0'}
-    peerDependencies:
-      debug: '*'
-    peerDependenciesMeta:
-      debug:
-        optional: true
+  /indent-string/4.0.0:
+    resolution: {integrity: 
sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
+    engines: {node: '>=8'}
     dev: true
 
-  /follow-redirects/1.15.2:
-    resolution: {integrity: 
sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
-    engines: {node: '>=4.0'}
-    peerDependencies:
-      debug: '*'
-    peerDependenciesMeta:
-      debug:
-        optional: true
-    dev: false
+  /indent-string/5.0.0:
+    resolution: {integrity: 
sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==}
+    engines: {node: '>=12'}
+    dev: true
 
-  /for-each/0.3.3:
-    resolution: {integrity: 
sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
-    dependencies:
-      is-callable: 1.2.4
+  /indexes-of/1.0.1:
+    resolution: {integrity: 
sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA==}
     dev: true
 
-  /for-in/1.0.2:
-    resolution: {integrity: sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=}
-    engines: {node: '>=0.10.0'}
+  /infer-owner/1.0.4:
+    resolution: {integrity: 
sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==}
     dev: true
 
-  /foreground-child/2.0.0:
-    resolution: {integrity: 
sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==}
-    engines: {node: '>=8.0.0'}
+  /inflight/1.0.6:
+    resolution: {integrity: 
sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
     dependencies:
-      cross-spawn: 7.0.3
-      signal-exit: 3.0.6
-    dev: true
+      once: 1.4.0
+      wrappy: 1.0.2
 
-  /forever-agent/0.6.1:
-    resolution: {integrity: sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=}
+  /inherits/2.0.1:
+    resolution: {integrity: 
sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==}
     dev: true
 
-  /fork-ts-checker-webpack-plugin/4.1.6_e7hrjdrs22zc4syxbltzlwluhe:
-    resolution: {integrity: 
sha512-DUxuQaKoqfNne8iikd14SAkh5uw4+8vNifp6gmA73yYNS6ywLIWSLD/n/mBzHQRpW3J7rbATEakmiA8JvkTyZw==}
-    engines: {node: '>=6.11.5', yarn: '>=1.0.0'}
-    peerDependencies:
-      eslint: '>= 6'
-      typescript: '>= 2.7'
-      vue-template-compiler: '*'
-      webpack: '>= 4'
-    peerDependenciesMeta:
-      eslint:
-        optional: true
-      vue-template-compiler:
-        optional: true
-    dependencies:
-      '@babel/code-frame': 7.16.7
-      chalk: 2.4.2
-      micromatch: 3.1.10
-      minimatch: 3.0.5
-      semver: 5.7.1
-      tapable: 1.1.3
-      typescript: 4.2.4
-      webpack: 4.46.0
-      worker-rpc: 0.1.1
-    transitivePeerDependencies:
-      - supports-color
+  /inherits/2.0.3:
+    resolution: {integrity: 
sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==}
     dev: true
 
-  /form-data/2.3.3:
-    resolution: {integrity: 
sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==}
-    engines: {node: '>= 0.12'}
-    dependencies:
-      asynckit: 0.4.0
-      combined-stream: 1.0.8
-      mime-types: 2.1.34
-    dev: true
+  /inherits/2.0.4:
+    resolution: {integrity: 
sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
 
-  /form-data/4.0.0:
-    resolution: {integrity: 
sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
-    engines: {node: '>= 6'}
-    dependencies:
-      asynckit: 0.4.0
-      combined-stream: 1.0.8
-      mime-types: 2.1.35
-    dev: false
+  /ini/1.3.7:
+    resolution: {integrity: 
sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==}
+    dev: true
 
-  /formdata-polyfill/4.0.10:
-    resolution: {integrity: 
sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
-    engines: {node: '>=12.20.0'}
-    dependencies:
-      fetch-blob: 3.1.4
-    dev: false
+  /ini/1.3.8:
+    resolution: {integrity: 
sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
+    dev: true
 
-  /forwarded/0.2.0:
-    resolution: {integrity: 
sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
-    engines: {node: '>= 0.6'}
+  /ini/2.0.0:
+    resolution: {integrity: 
sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==}
+    engines: {node: '>=10'}
     dev: true
 
-  /fraction.js/4.1.3:
-    resolution: {integrity: 
sha512-pUHWWt6vHzZZiQJcM6S/0PXfS+g6FM4BF5rj9wZyreivhQPdsh5PpE25VtSNxq80wHS5RfY51Ii+8Z0Zl/pmzg==}
+  /inline-chunk-html-plugin/1.1.1:
+    resolution: {integrity: 
sha512-6W1eGIj8z/Yla6xJx5il6jJfCxMZS3kVkbiLQThbbjdsDLRIWkUVmpnhfW2l6WAwCW+qfy0zoXVGBZM1E5XF3g==}
     dev: true
 
-  /fragment-cache/0.2.1:
-    resolution: {integrity: sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=}
-    engines: {node: '>=0.10.0'}
-    dependencies:
-      map-cache: 0.2.2
+  /inline-style-parser/0.1.1:
+    resolution: {integrity: 
sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==}
     dev: true
 
-  /fresh/0.5.2:
-    resolution: {integrity: sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=}
-    engines: {node: '>= 0.6'}
+  /internal-ip/4.3.0:
+    resolution: {integrity: 
sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==}
+    engines: {node: '>=6'}
+    dependencies:
+      default-gateway: 4.2.0
+      ipaddr.js: 1.9.1
     dev: true
 
-  /from2/2.3.0:
-    resolution: {integrity: sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=}
+  /internal-slot/1.0.3:
+    resolution: {integrity: 
sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==}
+    engines: {node: '>= 0.4'}
     dependencies:
-      inherits: 2.0.4
-      readable-stream: 2.3.7
+      get-intrinsic: 1.1.1
+      has: 1.0.3
+      side-channel: 1.0.4
     dev: true
 
-  /fromentries/1.3.2:
-    resolution: {integrity: 
sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==}
+  /interpret/1.4.0:
+    resolution: {integrity: 
sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==}
+    engines: {node: '>= 0.10'}
     dev: true
 
-  /fs-extra/4.0.3:
-    resolution: {integrity: 
sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==}
-    dependencies:
-      graceful-fs: 4.2.9
-      jsonfile: 4.0.0
-      universalify: 0.1.2
+  /interpret/2.2.0:
+    resolution: {integrity: 
sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==}
+    engines: {node: '>= 0.10'}
     dev: true
 
-  /fs-extra/9.1.0:
-    resolution: {integrity: 
sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==}
-    engines: {node: '>=10'}
+  /invariant/2.2.4:
+    resolution: {integrity: 
sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==}
     dependencies:
-      at-least-node: 1.0.0
-      graceful-fs: 4.2.9
-      jsonfile: 6.1.0
-      universalify: 2.0.0
+      loose-envify: 1.4.0
     dev: true
 
-  /fs-minipass/1.2.7:
-    resolution: {integrity: 
sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==}
-    dependencies:
-      minipass: 2.9.0
+  /ip-regex/2.1.0:
+    resolution: {integrity: 
sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw==}
+    engines: {node: '>=4'}
     dev: true
 
-  /fs-minipass/2.1.0:
-    resolution: {integrity: 
sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==}
-    engines: {node: '>= 8'}
-    dependencies:
-      minipass: 3.1.6
+  /ip/1.1.5:
+    resolution: {integrity: 
sha512-rBtCAQAJm8A110nbwn6YdveUnuZH3WrC36IwkRXxDnq53JvXA2NVQvB7IHyKomxK1MJ4VDNw3UtFDdXQ+AvLYA==}
     dev: true
 
-  /fs-monkey/1.0.3:
-    resolution: {integrity: 
sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==}
+  /ip/2.0.0:
+    resolution: {integrity: 
sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==}
     dev: true
 
-  /fs-write-stream-atomic/1.0.10:
-    resolution: {integrity: sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=}
-    dependencies:
-      graceful-fs: 4.2.10
-      iferr: 0.1.5
-      imurmurhash: 0.1.4
-      readable-stream: 2.3.7
+  /ipaddr.js/1.9.1:
+    resolution: {integrity: 
sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
+    engines: {node: '>= 0.10'}
     dev: true
 
-  /fs.realpath/1.0.0:
-    resolution: {integrity: 
sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
+  /ipaddr.js/2.0.1:
+    resolution: {integrity: 
sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==}
+    engines: {node: '>= 10'}
+    dev: true
 
-  /fsevents/1.2.13:
-    resolution: {integrity: 
sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==}
-    engines: {node: '>= 4.0'}
-    os: [darwin]
-    deprecated: fsevents 1 will break on node v14+ and could be using insecure 
binaries. Upgrade to fsevents 2.
-    requiresBuild: true
-    dependencies:
-      bindings: 1.5.0
-      nan: 2.17.0
+  /irregular-plurals/3.3.0:
+    resolution: {integrity: 
sha512-MVBLKUTangM3EfRPFROhmWQQKRDsrgI83J8GS3jXy+OwYqiR2/aoWndYQ5416jLE3uaGgLH7ncme3X9y09gZ3g==}
+    engines: {node: '>=8'}
     dev: true
-    optional: true
 
-  /fsevents/2.3.2:
-    resolution: {integrity: 
sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
-    engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
-    os: [darwin]
-    requiresBuild: true
+  /is-absolute-url/2.1.0:
+    resolution: {integrity: 
sha512-vOx7VprsKyllwjSkLV79NIhpyLfr3jAp7VaTCMXOJHu4m0Ew1CZ2fcjASwmV1jI3BWuWHB013M48eyeldk9gYg==}
+    engines: {node: '>=0.10.0'}
     dev: true
-    optional: true
 
-  /function-bind/1.1.1:
-    resolution: {integrity: 
sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
+  /is-absolute-url/3.0.3:
+    resolution: {integrity: 
sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==}
+    engines: {node: '>=8'}
     dev: true
 
-  /functional-red-black-tree/1.0.1:
-    resolution: {integrity: 
sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==}
+  /is-accessor-descriptor/0.1.6:
+    resolution: {integrity: 
sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      kind-of: 3.2.2
     dev: true
 
-  /gensync/1.0.0-beta.2:
-    resolution: {integrity: 
sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
-    engines: {node: '>=6.9.0'}
+  /is-accessor-descriptor/1.0.0:
+    resolution: {integrity: 
sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      kind-of: 6.0.3
     dev: true
 
-  /get-caller-file/2.0.5:
-    resolution: {integrity: 
sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
-    engines: {node: 6.* || 8.* || >= 10.*}
+  /is-alphabetical/1.0.4:
+    resolution: {integrity: 
sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==}
     dev: true
 
-  /get-func-name/2.0.0:
-    resolution: {integrity: 
sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==}
-
-  /get-intrinsic/1.1.1:
-    resolution: {integrity: 
sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==}
+  /is-alphanumerical/1.0.4:
+    resolution: {integrity: 
sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==}
     dependencies:
-      function-bind: 1.1.1
-      has: 1.0.3
-      has-symbols: 1.0.2
+      is-alphabetical: 1.0.4
+      is-decimal: 1.0.4
     dev: true
 
-  /get-own-enumerable-property-symbols/3.0.2:
-    resolution: {integrity: 
sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==}
+  /is-arguments/1.1.1:
+    resolution: {integrity: 
sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.2
+      has-tostringtag: 1.0.0
     dev: true
 
-  /get-package-type/0.1.0:
-    resolution: {integrity: 
sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==}
-    engines: {node: '>=8.0.0'}
+  /is-arrayish/0.2.1:
+    resolution: {integrity: 
sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
     dev: true
 
-  /get-port/5.1.1:
-    resolution: {integrity: 
sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==}
-    engines: {node: '>=8'}
+  /is-arrayish/0.3.2:
+    resolution: {integrity: 
sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
     dev: true
 
-  /get-stream/4.1.0:
-    resolution: {integrity: 
sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==}
-    engines: {node: '>=6'}
+  /is-bigint/1.0.4:
+    resolution: {integrity: 
sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
     dependencies:
-      pump: 3.0.0
+      has-bigints: 1.0.2
     dev: true
 
-  /get-stream/5.2.0:
-    resolution: {integrity: 
sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==}
-    engines: {node: '>=8'}
+  /is-binary-path/1.0.1:
+    resolution: {integrity: 
sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==}
+    engines: {node: '>=0.10.0'}
     dependencies:
-      pump: 3.0.0
+      binary-extensions: 1.13.1
     dev: true
 
-  /get-stream/6.0.1:
-    resolution: {integrity: 
sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
-    engines: {node: '>=10'}
+  /is-binary-path/2.1.0:
+    resolution: {integrity: 
sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
+    engines: {node: '>=8'}
+    dependencies:
+      binary-extensions: 2.2.0
     dev: true
 
-  /get-symbol-description/1.0.0:
-    resolution: {integrity: 
sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==}
+  /is-boolean-object/1.1.2:
+    resolution: {integrity: 
sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==}
     engines: {node: '>= 0.4'}
     dependencies:
       call-bind: 1.0.2
-      get-intrinsic: 1.1.1
+      has-tostringtag: 1.0.0
     dev: true
 
-  /get-value/2.0.6:
-    resolution: {integrity: sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=}
-    engines: {node: '>=0.10.0'}
+  /is-buffer/1.1.6:
+    resolution: {integrity: 
sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==}
     dev: true
 
-  /getpass/0.1.7:
-    resolution: {integrity: sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=}
-    dependencies:
-      assert-plus: 1.0.0
+  /is-buffer/2.0.5:
+    resolution: {integrity: 
sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==}
+    engines: {node: '>=4'}
     dev: true
 
-  /gettext-parser/1.1.0:
-    resolution: {integrity: sha1-LFpmONiTk0ubVQN9CtgstwBLJnk=}
+  /is-builtin-module/3.2.0:
+    resolution: {integrity: 
sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==}
+    engines: {node: '>=6'}
     dependencies:
-      encoding: 0.1.13
+      builtin-modules: 3.3.0
     dev: true
 
-  /gittar/0.1.1:
-    resolution: {integrity: sha1-1pk+phYKhsi3895yKmH3O8meFLQ=}
-    engines: {node: '>=4'}
-    dependencies:
-      mkdirp: 0.5.5
-      tar: 4.4.19
+  /is-callable/1.2.4:
+    resolution: {integrity: 
sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==}
+    engines: {node: '>= 0.4'}
     dev: true
 
-  /glob-parent/3.1.0:
-    resolution: {integrity: 
sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==}
-    dependencies:
-      is-glob: 3.1.0
-      path-dirname: 1.0.2
+  /is-callable/1.2.7:
+    resolution: {integrity: 
sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
+    engines: {node: '>= 0.4'}
     dev: true
-    optional: true
 
-  /glob-parent/5.1.2:
-    resolution: {integrity: 
sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
-    engines: {node: '>= 6'}
+  /is-ci/2.0.0:
+    resolution: {integrity: 
sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==}
+    hasBin: true
     dependencies:
-      is-glob: 4.0.3
+      ci-info: 2.0.0
     dev: true
 
-  /glob-parent/6.0.2:
-    resolution: {integrity: 
sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
-    engines: {node: '>=10.13.0'}
+  /is-color-stop/1.1.0:
+    resolution: {integrity: 
sha512-H1U8Vz0cfXNujrJzEcvvwMDW9Ra+biSYA3ThdQvAnMLJkEHQXn6bWzLkxHtVYJ+Sdbx0b6finn3jZiaVe7MAHA==}
     dependencies:
-      is-glob: 4.0.3
+      css-color-names: 0.0.4
+      hex-color-regex: 1.1.0
+      hsl-regex: 1.0.0
+      hsla-regex: 1.0.0
+      rgb-regex: 1.0.1
+      rgba-regex: 1.0.0
     dev: true
 
-  /glob/7.2.0:
-    resolution: {integrity: 
sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==}
+  /is-core-module/2.10.0:
+    resolution: {integrity: 
sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==}
     dependencies:
-      fs.realpath: 1.0.0
-      inflight: 1.0.6
-      inherits: 2.0.4
-      minimatch: 3.1.2
-      once: 1.4.0
-      path-is-absolute: 1.0.1
+      has: 1.0.3
+    dev: true
 
-  /glob/7.2.3:
-    resolution: {integrity: 
sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
+  /is-core-module/2.8.0:
+    resolution: {integrity: 
sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==}
     dependencies:
-      fs.realpath: 1.0.0
-      inflight: 1.0.6
-      inherits: 2.0.4
-      minimatch: 3.1.2
-      once: 1.4.0
-      path-is-absolute: 1.0.1
+      has: 1.0.3
     dev: true
 
-  /global-dirs/3.0.0:
-    resolution: {integrity: 
sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==}
-    engines: {node: '>=10'}
+  /is-core-module/2.8.1:
+    resolution: {integrity: 
sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==}
     dependencies:
-      ini: 2.0.0
+      has: 1.0.3
     dev: true
 
-  /globals/11.12.0:
-    resolution: {integrity: 
sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
-    engines: {node: '>=4'}
+  /is-data-descriptor/0.1.4:
+    resolution: {integrity: 
sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      kind-of: 3.2.2
     dev: true
 
-  /globals/13.12.1:
-    resolution: {integrity: 
sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==}
-    engines: {node: '>=8'}
+  /is-data-descriptor/1.0.0:
+    resolution: {integrity: 
sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==}
+    engines: {node: '>=0.10.0'}
     dependencies:
-      type-fest: 0.20.2
+      kind-of: 6.0.3
     dev: true
 
-  /globby/11.1.0:
-    resolution: {integrity: 
sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
-    engines: {node: '>=10'}
+  /is-date-object/1.0.5:
+    resolution: {integrity: 
sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==}
+    engines: {node: '>= 0.4'}
     dependencies:
-      array-union: 2.1.0
-      dir-glob: 3.0.1
-      fast-glob: 3.2.11
-      ignore: 5.2.0
-      merge2: 1.4.1
-      slash: 3.0.0
+      has-tostringtag: 1.0.0
     dev: true
 
-  /globby/13.1.2:
-    resolution: {integrity: 
sha512-LKSDZXToac40u8Q1PQtZihbNdTYSNMuWe+K5l+oa6KgDzSvVrHXlJy40hUP522RjAIoNLJYBJi7ow+rbFpIhHQ==}
-    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+  /is-decimal/1.0.4:
+    resolution: {integrity: 
sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==}
+    dev: true
+
+  /is-descriptor/0.1.6:
+    resolution: {integrity: 
sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==}
+    engines: {node: '>=0.10.0'}
     dependencies:
-      dir-glob: 3.0.1
-      fast-glob: 3.2.12
-      ignore: 5.2.0
-      merge2: 1.4.1
-      slash: 4.0.0
+      is-accessor-descriptor: 0.1.6
+      is-data-descriptor: 0.1.4
+      kind-of: 5.1.0
     dev: true
 
-  /got/9.6.0:
-    resolution: {integrity: 
sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==}
-    engines: {node: '>=8.6'}
+  /is-descriptor/1.0.2:
+    resolution: {integrity: 
sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==}
+    engines: {node: '>=0.10.0'}
     dependencies:
-      '@sindresorhus/is': 0.14.0
-      '@szmarczak/http-timer': 1.1.2
-      '@types/keyv': 3.1.4
-      '@types/responselike': 1.0.0
-      cacheable-request: 6.1.0
-      decompress-response: 3.3.0
-      duplexer3: 0.1.4
-      get-stream: 4.1.0
-      lowercase-keys: 1.0.1
-      mimic-response: 1.0.1
-      p-cancelable: 1.1.0
-      to-readable-stream: 1.0.0
-      url-parse-lax: 3.0.0
+      is-accessor-descriptor: 1.0.0
+      is-data-descriptor: 1.0.0
+      kind-of: 6.0.3
     dev: true
 
-  /graceful-fs/4.2.10:
-    resolution: {integrity: 
sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==}
+  /is-directory/0.3.1:
+    resolution: {integrity: 
sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==}
+    engines: {node: '>=0.10.0'}
     dev: true
 
-  /graceful-fs/4.2.8:
-    resolution: {integrity: 
sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==}
+  /is-docker/2.2.1:
+    resolution: {integrity: 
sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==}
+    engines: {node: '>=8'}
+    hasBin: true
     dev: true
 
-  /graceful-fs/4.2.9:
-    resolution: {integrity: 
sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==}
+  /is-dom/1.1.0:
+    resolution: {integrity: 
sha512-u82f6mvhYxRPKpw8V1N0W8ce1xXwOrQtgGcxl6UCL5zBmZu3is/18K0rR7uFCnMDuAsS/3W54mGL4vsaFUQlEQ==}
+    dependencies:
+      is-object: 1.0.2
+      is-window: 1.0.2
     dev: true
 
-  /growl/1.10.5:
-    resolution: {integrity: 
sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==}
-    engines: {node: '>=4.x'}
+  /is-error/2.2.2:
+    resolution: {integrity: 
sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==}
     dev: true
 
-  /gzip-size/6.0.0:
-    resolution: {integrity: 
sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==}
-    engines: {node: '>=10'}
-    dependencies:
-      duplexer: 0.1.2
+  /is-extendable/0.1.1:
+    resolution: {integrity: 
sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==}
+    engines: {node: '>=0.10.0'}
     dev: true
 
-  /handle-thing/2.0.1:
-    resolution: {integrity: 
sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==}
+  /is-extendable/1.0.1:
+    resolution: {integrity: 
sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      is-plain-object: 2.0.4
     dev: true
 
-  /har-schema/2.0.0:
-    resolution: {integrity: sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=}
-    engines: {node: '>=4'}
+  /is-extglob/1.0.0:
+    resolution: {integrity: 
sha512-7Q+VbVafe6x2T+Tu6NcOf6sRklazEPmBoB3IWk3WdGZM2iGUwU/Oe3Wtq5lSEkDTTlpp8yx+5t4pzO/i9Ty1ww==}
+    engines: {node: '>=0.10.0'}
     dev: true
 
-  /har-validator/5.1.5:
-    resolution: {integrity: 
sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==}
-    engines: {node: '>=6'}
-    deprecated: this library is no longer supported
-    dependencies:
-      ajv: 6.12.6
-      har-schema: 2.0.0
+  /is-extglob/2.1.1:
+    resolution: {integrity: 
sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+    engines: {node: '>=0.10.0'}
     dev: true
 
-  /has-bigints/1.0.1:
-    resolution: {integrity: 
sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==}
+  /is-finite/1.1.0:
+    resolution: {integrity: 
sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==}
+    engines: {node: '>=0.10.0'}
     dev: true
+    optional: true
 
-  /has-color/0.1.7:
-    resolution: {integrity: sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=}
+  /is-fullwidth-code-point/1.0.0:
+    resolution: {integrity: 
sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==}
     engines: {node: '>=0.10.0'}
+    dependencies:
+      number-is-nan: 1.0.1
     dev: true
 
-  /has-flag/3.0.0:
-    resolution: {integrity: 
sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
+  /is-fullwidth-code-point/2.0.0:
+    resolution: {integrity: 
sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==}
     engines: {node: '>=4'}
     dev: true
 
-  /has-flag/4.0.0:
-    resolution: {integrity: 
sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+  /is-fullwidth-code-point/3.0.0:
+    resolution: {integrity: 
sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
     engines: {node: '>=8'}
     dev: true
 
-  /has-symbols/1.0.2:
-    resolution: {integrity: 
sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==}
-    engines: {node: '>= 0.4'}
+  /is-fullwidth-code-point/4.0.0:
+    resolution: {integrity: 
sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==}
+    engines: {node: '>=12'}
     dev: true
 
-  /has-tostringtag/1.0.0:
-    resolution: {integrity: 
sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==}
-    engines: {node: '>= 0.4'}
-    dependencies:
-      has-symbols: 1.0.2
+  /is-function/1.0.2:
+    resolution: {integrity: 
sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==}
     dev: true
 
-  /has-value/0.3.1:
-    resolution: {integrity: sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=}
-    engines: {node: '>=0.10.0'}
-    dependencies:
-      get-value: 2.0.6
-      has-values: 0.1.4
-      isobject: 2.1.0
+  /is-generator-fn/2.1.0:
+    resolution: {integrity: 
sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==}
+    engines: {node: '>=6'}
     dev: true
 
-  /has-value/1.0.0:
-    resolution: {integrity: sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=}
+  /is-glob/2.0.1:
+    resolution: {integrity: 
sha512-a1dBeB19NXsf/E0+FHqkagizel/LQw2DjSQpvQrj3zT+jYPpaUCryPnrQajXKFLCMuf4I6FhRpaGtw4lPrG6Eg==}
     engines: {node: '>=0.10.0'}
     dependencies:
-      get-value: 2.0.6
-      has-values: 1.0.0
-      isobject: 3.0.1
+      is-extglob: 1.0.0
     dev: true
 
-  /has-values/0.1.4:
-    resolution: {integrity: sha1-bWHeldkd/Km5oCCJrThL/49it3E=}
+  /is-glob/3.1.0:
+    resolution: {integrity: 
sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==}
     engines: {node: '>=0.10.0'}
+    dependencies:
+      is-extglob: 2.1.1
     dev: true
 
-  /has-values/1.0.0:
-    resolution: {integrity: sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=}
+  /is-glob/4.0.3:
+    resolution: {integrity: 
sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
     engines: {node: '>=0.10.0'}
     dependencies:
-      is-number: 3.0.0
-      kind-of: 4.0.0
-    dev: true
-
-  /has-yarn/2.1.0:
-    resolution: {integrity: 
sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==}
-    engines: {node: '>=8'}
+      is-extglob: 2.1.1
     dev: true
 
-  /has/1.0.3:
-    resolution: {integrity: 
sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
-    engines: {node: '>= 0.4.0'}
-    dependencies:
-      function-bind: 1.1.1
+  /is-hexadecimal/1.0.4:
+    resolution: {integrity: 
sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==}
     dev: true
 
-  /hash-base/3.1.0:
-    resolution: {integrity: 
sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==}
-    engines: {node: '>=4'}
+  /is-installed-globally/0.3.2:
+    resolution: {integrity: 
sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==}
+    engines: {node: '>=8'}
     dependencies:
-      inherits: 2.0.4
-      readable-stream: 3.6.0
-      safe-buffer: 5.2.1
+      global-dirs: 2.1.0
+      is-path-inside: 3.0.3
     dev: true
 
-  /hash-wasm/4.9.0:
-    resolution: {integrity: 
sha512-7SW7ejyfnRxuOc7ptQHSf4LDoZaWOivfzqw+5rpcQku0nHfmicPKE51ra9BiRLAmT8+gGLestr1XroUkqdjL6w==}
-    dev: false
-
-  /hash.js/1.1.7:
-    resolution: {integrity: 
sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==}
+  /is-installed-globally/0.4.0:
+    resolution: {integrity: 
sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==}
+    engines: {node: '>=10'}
     dependencies:
-      inherits: 2.0.4
-      minimalistic-assert: 1.0.1
+      global-dirs: 3.0.0
+      is-path-inside: 3.0.3
     dev: true
 
-  /hasha/5.2.2:
-    resolution: {integrity: 
sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==}
+  /is-interactive/1.0.0:
+    resolution: {integrity: 
sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==}
     engines: {node: '>=8'}
-    dependencies:
-      is-stream: 2.0.1
-      type-fest: 0.8.1
     dev: true
 
-  /he/1.2.0:
-    resolution: {integrity: 
sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
-    hasBin: true
+  /is-map/2.0.2:
+    resolution: {integrity: 
sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==}
     dev: true
 
-  /hex-color-regex/1.1.0:
-    resolution: {integrity: 
sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==}
+  /is-module/1.0.0:
+    resolution: {integrity: 
sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==}
     dev: true
 
-  /history/4.10.1:
-    resolution: {integrity: 
sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==}
-    dependencies:
-      '@babel/runtime': 7.15.3
-      loose-envify: 1.4.0
-      resolve-pathname: 3.0.0
-      tiny-invariant: 1.1.0
-      tiny-warning: 1.0.3
-      value-equal: 1.0.1
-    dev: false
-
-  /hmac-drbg/1.0.1:
-    resolution: {integrity: sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=}
-    dependencies:
-      hash.js: 1.1.7
-      minimalistic-assert: 1.0.1
-      minimalistic-crypto-utils: 1.0.1
+  /is-negative-zero/2.0.2:
+    resolution: {integrity: 
sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==}
+    engines: {node: '>= 0.4'}
     dev: true
 
-  /hpack.js/2.1.6:
-    resolution: {integrity: sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=}
-    dependencies:
-      inherits: 2.0.4
-      obuf: 1.1.2
-      readable-stream: 2.3.7
-      wbuf: 1.7.3
+  /is-npm/4.0.0:
+    resolution: {integrity: 
sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==}
+    engines: {node: '>=8'}
     dev: true
 
-  /hsl-regex/1.0.0:
-    resolution: {integrity: sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=}
+  /is-npm/5.0.0:
+    resolution: {integrity: 
sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==}
+    engines: {node: '>=10'}
     dev: true
 
-  /hsla-regex/1.0.0:
-    resolution: {integrity: sha1-wc56MWjIxmFAM6S194d/OyJfnDg=}
+  /is-number-object/1.0.6:
+    resolution: {integrity: 
sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      has-tostringtag: 1.0.0
     dev: true
 
-  /html-encoding-sniffer/1.0.2:
-    resolution: {integrity: 
sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==}
+  /is-number/3.0.0:
+    resolution: {integrity: 
sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==}
+    engines: {node: '>=0.10.0'}
     dependencies:
-      whatwg-encoding: 1.0.5
+      kind-of: 3.2.2
     dev: true
 
-  /html-entities/2.3.2:
-    resolution: {integrity: 
sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ==}
+  /is-number/7.0.0:
+    resolution: {integrity: 
sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+    engines: {node: '>=0.12.0'}
     dev: true
 
-  /html-escaper/2.0.2:
-    resolution: {integrity: 
sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
+  /is-obj/1.0.1:
+    resolution: {integrity: 
sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==}
+    engines: {node: '>=0.10.0'}
     dev: true
 
-  /html-minifier/3.5.21:
-    resolution: {integrity: 
sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==}
-    engines: {node: '>=4'}
-    hasBin: true
-    dependencies:
-      camel-case: 3.0.0
-      clean-css: 4.2.4
-      commander: 2.17.1
-      he: 1.2.0
-      param-case: 2.1.1
-      relateurl: 0.2.7
-      uglify-js: 3.4.10
+  /is-obj/2.0.0:
+    resolution: {integrity: 
sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==}
+    engines: {node: '>=8'}
     dev: true
 
-  /html-webpack-exclude-assets-plugin/0.0.7:
-    resolution: {integrity: 
sha512-gaYKMGBPDts3Fb1WXyDEEcS/0TSRg2IDl3EsbQL2AkKWTqdjSKwfQ8Iz0RhPiWErJfqhq5/wkhoYyjQoG55pug==}
-    engines: {node: '>=4.0.0'}
+  /is-object/1.0.2:
+    resolution: {integrity: 
sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==}
     dev: true
 
-  /html-webpack-plugin/3.2.0_webpack@4.46.0:
-    resolution: {integrity: sha1-sBq71yOsqqeze2r0SS69oD2d03s=}
-    engines: {node: '>=6.9'}
-    deprecated: 3.x is no longer supported
-    peerDependencies:
-      webpack: ^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.0
-    dependencies:
-      html-minifier: 3.5.21
-      loader-utils: 0.2.17
-      lodash: 4.17.21
-      pretty-error: 2.1.2
-      tapable: 1.1.3
-      toposort: 1.0.7
-      util.promisify: 1.0.0
-      webpack: 4.46.0
+  /is-path-cwd/2.2.0:
+    resolution: {integrity: 
sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==}
+    engines: {node: '>=6'}
     dev: true
 
-  /htmlparser2/6.1.0:
-    resolution: {integrity: 
sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==}
+  /is-path-in-cwd/2.1.0:
+    resolution: {integrity: 
sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==}
+    engines: {node: '>=6'}
     dependencies:
-      domelementtype: 2.2.0
-      domhandler: 4.3.0
-      domutils: 2.8.0
-      entities: 2.2.0
+      is-path-inside: 2.1.0
     dev: true
 
-  /http-cache-semantics/4.1.0:
-    resolution: {integrity: 
sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==}
+  /is-path-inside/2.1.0:
+    resolution: {integrity: 
sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==}
+    engines: {node: '>=6'}
+    dependencies:
+      path-is-inside: 1.0.2
     dev: true
 
-  /http-deceiver/1.2.7:
-    resolution: {integrity: sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=}
+  /is-path-inside/3.0.3:
+    resolution: {integrity: 
sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
+    engines: {node: '>=8'}
     dev: true
 
-  /http-errors/1.6.3:
-    resolution: {integrity: sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=}
-    engines: {node: '>= 0.6'}
-    dependencies:
-      depd: 1.1.2
-      inherits: 2.0.3
-      setprototypeof: 1.1.0
-      statuses: 1.5.0
+  /is-plain-obj/1.1.0:
+    resolution: {integrity: 
sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==}
+    engines: {node: '>=0.10.0'}
     dev: true
 
-  /http-errors/1.8.1:
-    resolution: {integrity: 
sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==}
-    engines: {node: '>= 0.6'}
-    dependencies:
-      depd: 1.1.2
-      inherits: 2.0.4
-      setprototypeof: 1.2.0
-      statuses: 1.5.0
-      toidentifier: 1.0.1
+  /is-plain-obj/2.1.0:
+    resolution: {integrity: 
sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==}
+    engines: {node: '>=8'}
     dev: true
 
-  /http-parser-js/0.5.5:
-    resolution: {integrity: 
sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA==}
+  /is-plain-obj/3.0.0:
+    resolution: {integrity: 
sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==}
+    engines: {node: '>=10'}
     dev: true
 
-  /http-proxy-middleware/2.0.3_@types+express@4.17.13:
-    resolution: {integrity: 
sha512-1bloEwnrHMnCoO/Gcwbz7eSVvW50KPES01PecpagI+YLNLci4AcuKJrujW4Mc3sBLpFxMSlsLNHS5Nl/lvrTPA==}
-    engines: {node: '>=12.0.0'}
-    peerDependencies:
-      '@types/express': ^4.17.13
-    peerDependenciesMeta:
-      '@types/express':
-        optional: true
+  /is-plain-object/2.0.4:
+    resolution: {integrity: 
sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==}
+    engines: {node: '>=0.10.0'}
     dependencies:
-      '@types/express': 4.17.13
-      '@types/http-proxy': 1.17.8
-      http-proxy: 1.18.1
-      is-glob: 4.0.3
-      is-plain-obj: 3.0.0
-      micromatch: 4.0.4
-    transitivePeerDependencies:
-      - debug
+      isobject: 3.0.1
     dev: true
 
-  /http-proxy/1.18.1:
-    resolution: {integrity: 
sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==}
-    engines: {node: '>=8.0.0'}
-    dependencies:
-      eventemitter3: 4.0.7
-      follow-redirects: 1.14.8
-      requires-port: 1.0.0
-    transitivePeerDependencies:
-      - debug
+  /is-plain-object/5.0.0:
+    resolution: {integrity: 
sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==}
+    engines: {node: '>=0.10.0'}
     dev: true
 
-  /http-signature/1.2.0:
-    resolution: {integrity: sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=}
-    engines: {node: '>=0.8', npm: '>=1.3.7'}
-    dependencies:
-      assert-plus: 1.0.0
-      jsprim: 1.4.2
-      sshpk: 1.17.0
+  /is-potential-custom-element-name/1.0.1:
+    resolution: {integrity: 
sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
     dev: true
 
-  /https-browserify/1.0.0:
-    resolution: {integrity: sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=}
+  /is-promise/4.0.0:
+    resolution: {integrity: 
sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==}
     dev: true
 
-  /human-signals/2.1.0:
-    resolution: {integrity: 
sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
-    engines: {node: '>=10.17.0'}
+  /is-reference/1.2.1:
+    resolution: {integrity: 
sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==}
+    dependencies:
+      '@types/estree': 1.0.0
     dev: true
 
-  /iconv-lite/0.4.24:
-    resolution: {integrity: 
sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
-    engines: {node: '>=0.10.0'}
+  /is-regex/1.1.4:
+    resolution: {integrity: 
sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
+    engines: {node: '>= 0.4'}
     dependencies:
-      safer-buffer: 2.1.2
+      call-bind: 1.0.2
+      has-tostringtag: 1.0.0
     dev: true
 
-  /iconv-lite/0.6.3:
-    resolution: {integrity: 
sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
+  /is-regexp/1.0.0:
+    resolution: {integrity: 
sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==}
     engines: {node: '>=0.10.0'}
-    dependencies:
-      safer-buffer: 2.1.2
     dev: true
 
-  /icss-utils/5.1.0_postcss@8.4.6:
-    resolution: {integrity: 
sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==}
-    engines: {node: ^10 || ^12 || >= 14}
-    peerDependencies:
-      postcss: ^8.1.0
-    dependencies:
-      postcss: 8.4.6
+  /is-resolvable/1.1.0:
+    resolution: {integrity: 
sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==}
     dev: true
 
-  /idb/6.1.5:
-    resolution: {integrity: 
sha512-IJtugpKkiVXQn5Y+LteyBCNk1N8xpGV3wWZk9EVtZWH8DYkjBn0bX1XnGP9RkyZF0sAcywa6unHqSWKe7q4LGw==}
+  /is-root/2.1.0:
+    resolution: {integrity: 
sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==}
+    engines: {node: '>=6'}
     dev: true
 
-  /ieee754/1.2.1:
-    resolution: {integrity: 
sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
+  /is-set/2.0.2:
+    resolution: {integrity: 
sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==}
     dev: true
 
-  /iferr/0.1.5:
-    resolution: {integrity: sha1-xg7taebY/bazEEofy8ocGS3FtQE=}
+  /is-shared-array-buffer/1.0.1:
+    resolution: {integrity: 
sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==}
     dev: true
 
-  /ignore-by-default/2.1.0:
-    resolution: {integrity: 
sha512-yiWd4GVmJp0Q6ghmM2B/V3oZGRmjrKLXvHR3TE1nfoXsmoggllfZUQe74EN0fJdPFZu2NIvNdrMMLm3OsV7Ohw==}
-    engines: {node: '>=10 <11 || >=12 <13 || >=14'}
+  /is-shared-array-buffer/1.0.2:
+    resolution: {integrity: 
sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==}
+    dependencies:
+      call-bind: 1.0.2
     dev: true
 
-  /ignore/4.0.6:
-    resolution: {integrity: 
sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==}
-    engines: {node: '>= 4'}
+  /is-stream/1.1.0:
+    resolution: {integrity: 
sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==}
+    engines: {node: '>=0.10.0'}
     dev: true
 
-  /ignore/5.2.0:
-    resolution: {integrity: 
sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==}
-    engines: {node: '>= 4'}
+  /is-stream/2.0.1:
+    resolution: {integrity: 
sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
+    engines: {node: '>=8'}
     dev: true
 
-  /import-fresh/2.0.0:
-    resolution: {integrity: sha1-2BNVwVYS04bGH53dOSLUMEgipUY=}
-    engines: {node: '>=4'}
+  /is-string/1.0.7:
+    resolution: {integrity: 
sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==}
+    engines: {node: '>= 0.4'}
     dependencies:
-      caller-path: 2.0.0
-      resolve-from: 3.0.0
+      has-tostringtag: 1.0.0
     dev: true
 
-  /import-fresh/3.3.0:
-    resolution: {integrity: 
sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
-    engines: {node: '>=6'}
+  /is-subset/0.1.1:
+    resolution: {integrity: 
sha512-6Ybun0IkarhmEqxXCNw/C0bna6Zb/TkfUX9UbwJtK6ObwAVCxmAP308WWTHviM/zAqXk05cdhYsUsZeGQh99iw==}
+    dev: true
+
+  /is-symbol/1.0.4:
+    resolution: {integrity: 
sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==}
+    engines: {node: '>= 0.4'}
     dependencies:
-      parent-module: 1.0.1
-      resolve-from: 4.0.0
+      has-symbols: 1.0.3
     dev: true
 
-  /import-lazy/2.1.0:
-    resolution: {integrity: sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=}
-    engines: {node: '>=4'}
+  /is-typed-array/1.1.9:
+    resolution: {integrity: 
sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      available-typed-arrays: 1.0.5
+      call-bind: 1.0.2
+      es-abstract: 1.20.4
+      for-each: 0.3.3
+      has-tostringtag: 1.0.0
     dev: true
 
-  /imurmurhash/0.1.4:
-    resolution: {integrity: 
sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
-    engines: {node: '>=0.8.19'}
+  /is-typedarray/1.0.0:
+    resolution: {integrity: 
sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==}
     dev: true
 
-  /indent-string/4.0.0:
-    resolution: {integrity: 
sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
-    engines: {node: '>=8'}
+  /is-unicode-supported/0.1.0:
+    resolution: {integrity: 
sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==}
+    engines: {node: '>=10'}
     dev: true
 
-  /indent-string/5.0.0:
-    resolution: {integrity: 
sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==}
+  /is-unicode-supported/1.3.0:
+    resolution: {integrity: 
sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==}
     engines: {node: '>=12'}
     dev: true
 
-  /indexes-of/1.0.1:
-    resolution: {integrity: sha1-8w9xbI4r00bHtn0985FVZqfAVgc=}
+  /is-utf8/0.2.1:
+    resolution: {integrity: 
sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==}
     dev: true
+    optional: true
 
-  /infer-owner/1.0.4:
-    resolution: {integrity: 
sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==}
+  /is-weakmap/2.0.1:
+    resolution: {integrity: 
sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==}
     dev: true
 
-  /inflight/1.0.6:
-    resolution: {integrity: 
sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
+  /is-weakref/1.0.2:
+    resolution: {integrity: 
sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==}
     dependencies:
-      once: 1.4.0
-      wrappy: 1.0.2
+      call-bind: 1.0.2
+    dev: true
 
-  /inherits/2.0.1:
-    resolution: {integrity: 
sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==}
+  /is-weakset/2.0.2:
+    resolution: {integrity: 
sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==}
+    dependencies:
+      call-bind: 1.0.2
+      get-intrinsic: 1.1.3
     dev: true
 
-  /inherits/2.0.3:
-    resolution: {integrity: 
sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==}
+  /is-whitespace-character/1.0.4:
+    resolution: {integrity: 
sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==}
     dev: true
 
-  /inherits/2.0.4:
-    resolution: {integrity: 
sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+  /is-window/1.0.2:
+    resolution: {integrity: 
sha512-uj00kdXyZb9t9RcAUAwMZAnkBUwdYGhYlt7djMXhfyhUCzwNba50tIiBKR7q0l7tdoBtFVw/3JmLY6fI3rmZmg==}
+    dev: true
 
-  /ini/1.3.8:
-    resolution: {integrity: 
sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
+  /is-windows/1.0.2:
+    resolution: {integrity: 
sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==}
+    engines: {node: '>=0.10.0'}
     dev: true
 
-  /ini/2.0.0:
-    resolution: {integrity: 
sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==}
-    engines: {node: '>=10'}
+  /is-word-character/1.0.4:
+    resolution: {integrity: 
sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==}
     dev: true
 
-  /internal-slot/1.0.3:
-    resolution: {integrity: 
sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==}
-    engines: {node: '>= 0.4'}
+  /is-wsl/1.1.0:
+    resolution: {integrity: 
sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==}
+    engines: {node: '>=4'}
+    dev: true
+
+  /is-wsl/2.2.0:
+    resolution: {integrity: 
sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==}
+    engines: {node: '>=8'}
     dependencies:
-      get-intrinsic: 1.1.1
-      has: 1.0.3
-      side-channel: 1.0.4
+      is-docker: 2.2.1
     dev: true
 
-  /ip/1.1.5:
-    resolution: {integrity: sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=}
+  /is-yarn-global/0.3.0:
+    resolution: {integrity: 
sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==}
     dev: true
 
-  /ipaddr.js/1.9.1:
-    resolution: {integrity: 
sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
-    engines: {node: '>= 0.10'}
+  /isarray/1.0.0:
+    resolution: {integrity: 
sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
     dev: true
 
-  /ipaddr.js/2.0.1:
-    resolution: {integrity: 
sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==}
-    engines: {node: '>= 10'}
+  /isarray/2.0.5:
+    resolution: {integrity: 
sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
     dev: true
 
-  /irregular-plurals/3.3.0:
-    resolution: {integrity: 
sha512-MVBLKUTangM3EfRPFROhmWQQKRDsrgI83J8GS3jXy+OwYqiR2/aoWndYQ5416jLE3uaGgLH7ncme3X9y09gZ3g==}
-    engines: {node: '>=8'}
+  /isexe/2.0.0:
+    resolution: {integrity: 
sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
     dev: true
 
-  /is-absolute-url/2.1.0:
-    resolution: {integrity: sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=}
+  /isobject/2.1.0:
+    resolution: {integrity: 
sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==}
     engines: {node: '>=0.10.0'}
+    dependencies:
+      isarray: 1.0.0
     dev: true
 
-  /is-accessor-descriptor/0.1.6:
-    resolution: {integrity: sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=}
+  /isobject/3.0.1:
+    resolution: {integrity: 
sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==}
     engines: {node: '>=0.10.0'}
-    dependencies:
-      kind-of: 3.2.2
     dev: true
 
-  /is-accessor-descriptor/1.0.0:
-    resolution: {integrity: 
sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==}
+  /isobject/4.0.0:
+    resolution: {integrity: 
sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==}
     engines: {node: '>=0.10.0'}
-    dependencies:
-      kind-of: 6.0.3
     dev: true
 
-  /is-arguments/1.1.1:
-    resolution: {integrity: 
sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==}
-    engines: {node: '>= 0.4'}
+  /isomorphic-unfetch/3.1.0:
+    resolution: {integrity: 
sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==}
     dependencies:
-      call-bind: 1.0.2
-      has-tostringtag: 1.0.0
+      node-fetch: 2.6.7
+      unfetch: 4.2.0
+    transitivePeerDependencies:
+      - encoding
     dev: true
 
-  /is-arrayish/0.2.1:
-    resolution: {integrity: sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=}
+  /isstream/0.1.2:
+    resolution: {integrity: 
sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==}
     dev: true
 
-  /is-arrayish/0.3.2:
-    resolution: {integrity: 
sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
+  /istanbul-lib-coverage/3.2.0:
+    resolution: {integrity: 
sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==}
+    engines: {node: '>=8'}
     dev: true
 
-  /is-bigint/1.0.4:
-    resolution: {integrity: 
sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
+  /istanbul-lib-hook/3.0.0:
+    resolution: {integrity: 
sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==}
+    engines: {node: '>=8'}
     dependencies:
-      has-bigints: 1.0.1
+      append-transform: 2.0.0
     dev: true
 
-  /is-binary-path/1.0.1:
-    resolution: {integrity: 
sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==}
-    engines: {node: '>=0.10.0'}
+  /istanbul-lib-instrument/4.0.3:
+    resolution: {integrity: 
sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==}
+    engines: {node: '>=8'}
     dependencies:
-      binary-extensions: 1.13.1
+      '@babel/core': 7.19.6
+      '@istanbuljs/schema': 0.1.3
+      istanbul-lib-coverage: 3.2.0
+      semver: 6.3.0
+    transitivePeerDependencies:
+      - supports-color
     dev: true
-    optional: true
 
-  /is-binary-path/2.1.0:
-    resolution: {integrity: 
sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
+  /istanbul-lib-instrument/5.2.1:
+    resolution: {integrity: 
sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==}
     engines: {node: '>=8'}
     dependencies:
-      binary-extensions: 2.2.0
+      '@babel/core': 7.19.6
+      '@babel/parser': 7.19.6
+      '@istanbuljs/schema': 0.1.3
+      istanbul-lib-coverage: 3.2.0
+      semver: 6.3.0
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /is-boolean-object/1.1.2:
-    resolution: {integrity: 
sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==}
-    engines: {node: '>= 0.4'}
+  /istanbul-lib-processinfo/2.0.2:
+    resolution: {integrity: 
sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==}
+    engines: {node: '>=8'}
     dependencies:
-      call-bind: 1.0.2
-      has-tostringtag: 1.0.0
+      archy: 1.0.0
+      cross-spawn: 7.0.3
+      istanbul-lib-coverage: 3.2.0
+      make-dir: 3.1.0
+      p-map: 3.0.0
+      rimraf: 3.0.2
+      uuid: 3.4.0
     dev: true
 
-  /is-buffer/1.1.6:
-    resolution: {integrity: 
sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==}
+  /istanbul-lib-report/3.0.0:
+    resolution: {integrity: 
sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==}
+    engines: {node: '>=8'}
+    dependencies:
+      istanbul-lib-coverage: 3.2.0
+      make-dir: 3.1.0
+      supports-color: 7.2.0
     dev: true
 
-  /is-builtin-module/3.2.0:
-    resolution: {integrity: 
sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==}
-    engines: {node: '>=6'}
+  /istanbul-lib-source-maps/4.0.1:
+    resolution: {integrity: 
sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==}
+    engines: {node: '>=10'}
     dependencies:
-      builtin-modules: 3.3.0
+      debug: 4.3.4
+      istanbul-lib-coverage: 3.2.0
+      source-map: 0.6.1
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /is-callable/1.2.4:
-    resolution: {integrity: 
sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==}
-    engines: {node: '>= 0.4'}
+  /istanbul-reports/3.1.3:
+    resolution: {integrity: 
sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg==}
+    engines: {node: '>=8'}
+    dependencies:
+      html-escaper: 2.0.2
+      istanbul-lib-report: 3.0.0
     dev: true
 
-  /is-ci/2.0.0:
-    resolution: {integrity: 
sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==}
-    hasBin: true
+  /iterate-iterator/1.0.2:
+    resolution: {integrity: 
sha512-t91HubM4ZDQ70M9wqp+pcNpu8OyJ9UAtXntT/Bcsvp5tZMnz9vRa+IunKXeI8AnfZMTv0jNuVEmGeLSMjVvfPw==}
+    dev: true
+
+  /iterate-value/1.0.2:
+    resolution: {integrity: 
sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ==}
     dependencies:
-      ci-info: 2.0.0
+      es-get-iterator: 1.1.2
+      iterate-iterator: 1.0.2
     dev: true
 
-  /is-color-stop/1.1.0:
-    resolution: {integrity: sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=}
+  /jake/10.8.2:
+    resolution: {integrity: 
sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==}
+    hasBin: true
     dependencies:
-      css-color-names: 0.0.4
-      hex-color-regex: 1.1.0
-      hsl-regex: 1.0.0
-      hsla-regex: 1.0.0
-      rgb-regex: 1.0.1
-      rgba-regex: 1.0.0
+      async: 0.9.2
+      chalk: 2.4.2
+      filelist: 1.0.2
+      minimatch: 3.1.2
     dev: true
 
-  /is-core-module/2.10.0:
-    resolution: {integrity: 
sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==}
+  /jed/1.1.1:
+    resolution: {integrity: 
sha512-z35ZSEcXHxLW4yumw0dF6L464NT36vmx3wxJw8MDpraBcWuNVgUPZgPJKcu1HekNgwlMFNqol7i/IpSbjhqwqA==}
+
+  /jest-changed-files/26.6.2:
+    resolution: {integrity: 
sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==}
+    engines: {node: '>= 10.14.2'}
     dependencies:
-      has: 1.0.3
+      '@jest/types': 26.6.2
+      execa: 4.1.0
+      throat: 5.0.0
     dev: true
 
-  /is-core-module/2.8.0:
-    resolution: {integrity: 
sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==}
+  /jest-changed-files/27.5.1:
+    resolution: {integrity: 
sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dependencies:
-      has: 1.0.3
+      '@jest/types': 27.5.1
+      execa: 5.1.1
+      throat: 6.0.1
     dev: true
 
-  /is-core-module/2.8.1:
-    resolution: {integrity: 
sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==}
+  /jest-circus/27.5.1:
+    resolution: {integrity: 
sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dependencies:
-      has: 1.0.3
+      '@jest/environment': 27.5.1
+      '@jest/test-result': 27.5.1
+      '@jest/types': 27.5.1
+      '@types/node': 18.8.5
+      chalk: 4.1.2
+      co: 4.6.0
+      dedent: 0.7.0
+      expect: 27.5.1
+      is-generator-fn: 2.1.0
+      jest-each: 27.5.1
+      jest-matcher-utils: 27.5.1
+      jest-message-util: 27.5.1
+      jest-runtime: 27.5.1
+      jest-snapshot: 27.5.1
+      jest-util: 27.5.1
+      pretty-format: 27.5.1
+      slash: 3.0.0
+      stack-utils: 2.0.5
+      throat: 6.0.1
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /is-data-descriptor/0.1.4:
-    resolution: {integrity: sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=}
-    engines: {node: '>=0.10.0'}
+  /jest-cli/26.6.3:
+    resolution: {integrity: 
sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==}
+    engines: {node: '>= 10.14.2'}
+    hasBin: true
     dependencies:
-      kind-of: 3.2.2
+      '@jest/core': 26.6.3
+      '@jest/test-result': 26.6.2
+      '@jest/types': 26.6.2
+      chalk: 4.1.2
+      exit: 0.1.2
+      graceful-fs: 4.2.10
+      import-local: 3.1.0
+      is-ci: 2.0.0
+      jest-config: 26.6.3
+      jest-util: 26.6.2
+      jest-validate: 26.6.2
+      prompts: 2.4.2
+      yargs: 15.4.1
+    transitivePeerDependencies:
+      - bufferutil
+      - canvas
+      - supports-color
+      - ts-node
+      - utf-8-validate
     dev: true
 
-  /is-data-descriptor/1.0.0:
-    resolution: {integrity: 
sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==}
-    engines: {node: '>=0.10.0'}
+  /jest-cli/27.5.1:
+    resolution: {integrity: 
sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    hasBin: true
+    peerDependencies:
+      node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
+    peerDependenciesMeta:
+      node-notifier:
+        optional: true
     dependencies:
-      kind-of: 6.0.3
+      '@jest/core': 27.5.1
+      '@jest/test-result': 27.5.1
+      '@jest/types': 27.5.1
+      chalk: 4.1.2
+      exit: 0.1.2
+      graceful-fs: 4.2.10
+      import-local: 3.1.0
+      jest-config: 27.5.1
+      jest-util: 27.5.1
+      jest-validate: 27.5.1
+      prompts: 2.4.2
+      yargs: 16.2.0
+    transitivePeerDependencies:
+      - bufferutil
+      - canvas
+      - supports-color
+      - ts-node
+      - utf-8-validate
     dev: true
 
-  /is-date-object/1.0.5:
-    resolution: {integrity: 
sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==}
-    engines: {node: '>= 0.4'}
+  /jest-config/26.6.3:
+    resolution: {integrity: 
sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==}
+    engines: {node: '>= 10.14.2'}
+    peerDependencies:
+      ts-node: '>=9.0.0'
+    peerDependenciesMeta:
+      ts-node:
+        optional: true
     dependencies:
-      has-tostringtag: 1.0.0
+      '@babel/core': 7.19.6
+      '@jest/test-sequencer': 26.6.3
+      '@jest/types': 26.6.2
+      babel-jest: 26.6.3_@babel+core@7.19.6
+      chalk: 4.1.2
+      deepmerge: 4.2.2
+      glob: 7.2.3
+      graceful-fs: 4.2.10
+      jest-environment-jsdom: 26.6.2
+      jest-environment-node: 26.6.2
+      jest-get-type: 26.3.0
+      jest-jasmine2: 26.6.3
+      jest-regex-util: 26.0.0
+      jest-resolve: 26.6.2
+      jest-util: 26.6.2
+      jest-validate: 26.6.2
+      micromatch: 4.0.5
+      pretty-format: 26.6.2
+    transitivePeerDependencies:
+      - bufferutil
+      - canvas
+      - supports-color
+      - utf-8-validate
     dev: true
 
-  /is-descriptor/0.1.6:
-    resolution: {integrity: 
sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==}
-    engines: {node: '>=0.10.0'}
+  /jest-config/27.5.1:
+    resolution: {integrity: 
sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    peerDependencies:
+      ts-node: '>=9.0.0'
+    peerDependenciesMeta:
+      ts-node:
+        optional: true
     dependencies:
-      is-accessor-descriptor: 0.1.6
-      is-data-descriptor: 0.1.4
-      kind-of: 5.1.0
+      '@babel/core': 7.19.6
+      '@jest/test-sequencer': 27.5.1
+      '@jest/types': 27.5.1
+      babel-jest: 27.5.1_@babel+core@7.19.6
+      chalk: 4.1.2
+      ci-info: 3.5.0
+      deepmerge: 4.2.2
+      glob: 7.2.3
+      graceful-fs: 4.2.10
+      jest-circus: 27.5.1
+      jest-environment-jsdom: 27.5.1
+      jest-environment-node: 27.5.1
+      jest-get-type: 27.5.1
+      jest-jasmine2: 27.5.1
+      jest-regex-util: 27.5.1
+      jest-resolve: 27.5.1
+      jest-runner: 27.5.1
+      jest-util: 27.5.1
+      jest-validate: 27.5.1
+      micromatch: 4.0.5
+      parse-json: 5.2.0
+      pretty-format: 27.5.1
+      slash: 3.0.0
+      strip-json-comments: 3.1.1
+    transitivePeerDependencies:
+      - bufferutil
+      - canvas
+      - supports-color
+      - utf-8-validate
     dev: true
 
-  /is-descriptor/1.0.2:
-    resolution: {integrity: 
sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==}
-    engines: {node: '>=0.10.0'}
+  /jest-diff/26.6.2:
+    resolution: {integrity: 
sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==}
+    engines: {node: '>= 10.14.2'}
     dependencies:
-      is-accessor-descriptor: 1.0.0
-      is-data-descriptor: 1.0.0
-      kind-of: 6.0.3
+      chalk: 4.1.2
+      diff-sequences: 26.6.2
+      jest-get-type: 26.3.0
+      pretty-format: 26.6.2
     dev: true
 
-  /is-directory/0.3.1:
-    resolution: {integrity: sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=}
-    engines: {node: '>=0.10.0'}
+  /jest-diff/27.5.1:
+    resolution: {integrity: 
sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    dependencies:
+      chalk: 4.1.2
+      diff-sequences: 27.5.1
+      jest-get-type: 27.5.1
+      pretty-format: 27.5.1
     dev: true
 
-  /is-docker/2.2.1:
-    resolution: {integrity: 
sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==}
-    engines: {node: '>=8'}
-    hasBin: true
+  /jest-docblock/26.0.0:
+    resolution: {integrity: 
sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==}
+    engines: {node: '>= 10.14.2'}
+    dependencies:
+      detect-newline: 3.1.0
     dev: true
 
-  /is-error/2.2.2:
-    resolution: {integrity: 
sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==}
+  /jest-docblock/27.5.1:
+    resolution: {integrity: 
sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    dependencies:
+      detect-newline: 3.1.0
     dev: true
 
-  /is-extendable/0.1.1:
-    resolution: {integrity: sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=}
-    engines: {node: '>=0.10.0'}
+  /jest-each/26.6.2:
+    resolution: {integrity: 
sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==}
+    engines: {node: '>= 10.14.2'}
+    dependencies:
+      '@jest/types': 26.6.2
+      chalk: 4.1.2
+      jest-get-type: 26.3.0
+      jest-util: 26.6.2
+      pretty-format: 26.6.2
     dev: true
 
-  /is-extendable/1.0.1:
-    resolution: {integrity: 
sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==}
-    engines: {node: '>=0.10.0'}
+  /jest-each/27.5.1:
+    resolution: {integrity: 
sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dependencies:
-      is-plain-object: 2.0.4
+      '@jest/types': 27.5.1
+      chalk: 4.1.2
+      jest-get-type: 27.5.1
+      jest-util: 27.5.1
+      pretty-format: 27.5.1
     dev: true
 
-  /is-extglob/2.1.1:
-    resolution: {integrity: 
sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
-    engines: {node: '>=0.10.0'}
+  /jest-environment-jsdom/26.6.2:
+    resolution: {integrity: 
sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==}
+    engines: {node: '>= 10.14.2'}
+    dependencies:
+      '@jest/environment': 26.6.2
+      '@jest/fake-timers': 26.6.2
+      '@jest/types': 26.6.2
+      '@types/node': 18.8.5
+      jest-mock: 26.6.2
+      jest-util: 26.6.2
+      jsdom: 16.7.0
+    transitivePeerDependencies:
+      - bufferutil
+      - canvas
+      - supports-color
+      - utf-8-validate
     dev: true
 
-  /is-fullwidth-code-point/3.0.0:
-    resolution: {integrity: 
sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
-    engines: {node: '>=8'}
+  /jest-environment-jsdom/27.5.1:
+    resolution: {integrity: 
sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    dependencies:
+      '@jest/environment': 27.5.1
+      '@jest/fake-timers': 27.5.1
+      '@jest/types': 27.5.1
+      '@types/node': 18.8.5
+      jest-mock: 27.5.1
+      jest-util: 27.5.1
+      jsdom: 16.7.0
+    transitivePeerDependencies:
+      - bufferutil
+      - canvas
+      - supports-color
+      - utf-8-validate
     dev: true
 
-  /is-fullwidth-code-point/4.0.0:
-    resolution: {integrity: 
sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==}
-    engines: {node: '>=12'}
+  /jest-environment-node/26.6.2:
+    resolution: {integrity: 
sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==}
+    engines: {node: '>= 10.14.2'}
+    dependencies:
+      '@jest/environment': 26.6.2
+      '@jest/fake-timers': 26.6.2
+      '@jest/types': 26.6.2
+      '@types/node': 18.8.5
+      jest-mock: 26.6.2
+      jest-util: 26.6.2
     dev: true
 
-  /is-glob/3.1.0:
-    resolution: {integrity: 
sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==}
-    engines: {node: '>=0.10.0'}
+  /jest-environment-node/27.5.1:
+    resolution: {integrity: 
sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dependencies:
-      is-extglob: 2.1.1
+      '@jest/environment': 27.5.1
+      '@jest/fake-timers': 27.5.1
+      '@jest/types': 27.5.1
+      '@types/node': 18.8.5
+      jest-mock: 27.5.1
+      jest-util: 27.5.1
     dev: true
-    optional: true
 
-  /is-glob/4.0.3:
-    resolution: {integrity: 
sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
-    engines: {node: '>=0.10.0'}
+  /jest-fetch-mock/3.0.3:
+    resolution: {integrity: 
sha512-Ux1nWprtLrdrH4XwE7O7InRY6psIi3GOsqNESJgMJ+M5cv4A8Lh7SN9d2V2kKRZ8ebAfcd1LNyZguAOb6JiDqw==}
     dependencies:
-      is-extglob: 2.1.1
+      cross-fetch: 3.1.5
+      promise-polyfill: 8.2.1
+    transitivePeerDependencies:
+      - encoding
     dev: true
 
-  /is-installed-globally/0.4.0:
-    resolution: {integrity: 
sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==}
-    engines: {node: '>=10'}
-    dependencies:
-      global-dirs: 3.0.0
-      is-path-inside: 3.0.3
+  /jest-get-type/26.3.0:
+    resolution: {integrity: 
sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==}
+    engines: {node: '>= 10.14.2'}
     dev: true
 
-  /is-interactive/1.0.0:
-    resolution: {integrity: 
sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==}
-    engines: {node: '>=8'}
+  /jest-get-type/27.5.1:
+    resolution: {integrity: 
sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dev: true
 
-  /is-module/1.0.0:
-    resolution: {integrity: 
sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==}
+  /jest-haste-map/26.6.2:
+    resolution: {integrity: 
sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==}
+    engines: {node: '>= 10.14.2'}
+    dependencies:
+      '@jest/types': 26.6.2
+      '@types/graceful-fs': 4.1.5
+      '@types/node': 18.8.5
+      anymatch: 3.1.2
+      fb-watchman: 2.0.2
+      graceful-fs: 4.2.10
+      jest-regex-util: 26.0.0
+      jest-serializer: 26.6.2
+      jest-util: 26.6.2
+      jest-worker: 26.6.2
+      micromatch: 4.0.5
+      sane: 4.1.0
+      walker: 1.0.8
+    optionalDependencies:
+      fsevents: 2.3.2
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /is-negative-zero/2.0.2:
-    resolution: {integrity: 
sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==}
-    engines: {node: '>= 0.4'}
+  /jest-haste-map/27.5.1:
+    resolution: {integrity: 
sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    dependencies:
+      '@jest/types': 27.5.1
+      '@types/graceful-fs': 4.1.5
+      '@types/node': 18.8.5
+      anymatch: 3.1.2
+      fb-watchman: 2.0.2
+      graceful-fs: 4.2.10
+      jest-regex-util: 27.5.1
+      jest-serializer: 27.5.1
+      jest-util: 27.5.1
+      jest-worker: 27.5.1
+      micromatch: 4.0.5
+      walker: 1.0.8
+    optionalDependencies:
+      fsevents: 2.3.2
     dev: true
 
-  /is-npm/5.0.0:
-    resolution: {integrity: 
sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==}
-    engines: {node: '>=10'}
+  /jest-jasmine2/26.6.3:
+    resolution: {integrity: 
sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==}
+    engines: {node: '>= 10.14.2'}
+    dependencies:
+      '@babel/traverse': 7.19.6
+      '@jest/environment': 26.6.2
+      '@jest/source-map': 26.6.2
+      '@jest/test-result': 26.6.2
+      '@jest/types': 26.6.2
+      '@types/node': 18.8.5
+      chalk: 4.1.2
+      co: 4.6.0
+      expect: 26.6.2
+      is-generator-fn: 2.1.0
+      jest-each: 26.6.2
+      jest-matcher-utils: 26.6.2
+      jest-message-util: 26.6.2
+      jest-runtime: 26.6.3
+      jest-snapshot: 26.6.2
+      jest-util: 26.6.2
+      pretty-format: 26.6.2
+      throat: 5.0.0
+    transitivePeerDependencies:
+      - bufferutil
+      - canvas
+      - supports-color
+      - ts-node
+      - utf-8-validate
     dev: true
 
-  /is-number-object/1.0.6:
-    resolution: {integrity: 
sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==}
-    engines: {node: '>= 0.4'}
+  /jest-jasmine2/27.5.1:
+    resolution: {integrity: 
sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dependencies:
-      has-tostringtag: 1.0.0
+      '@jest/environment': 27.5.1
+      '@jest/source-map': 27.5.1
+      '@jest/test-result': 27.5.1
+      '@jest/types': 27.5.1
+      '@types/node': 18.8.5
+      chalk: 4.1.2
+      co: 4.6.0
+      expect: 27.5.1
+      is-generator-fn: 2.1.0
+      jest-each: 27.5.1
+      jest-matcher-utils: 27.5.1
+      jest-message-util: 27.5.1
+      jest-runtime: 27.5.1
+      jest-snapshot: 27.5.1
+      jest-util: 27.5.1
+      pretty-format: 27.5.1
+      throat: 6.0.1
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /is-number/3.0.0:
-    resolution: {integrity: 
sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==}
-    engines: {node: '>=0.10.0'}
+  /jest-leak-detector/26.6.2:
+    resolution: {integrity: 
sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==}
+    engines: {node: '>= 10.14.2'}
     dependencies:
-      kind-of: 3.2.2
+      jest-get-type: 26.3.0
+      pretty-format: 26.6.2
     dev: true
 
-  /is-number/7.0.0:
-    resolution: {integrity: 
sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
-    engines: {node: '>=0.12.0'}
+  /jest-leak-detector/27.5.1:
+    resolution: {integrity: 
sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    dependencies:
+      jest-get-type: 27.5.1
+      pretty-format: 27.5.1
     dev: true
 
-  /is-obj/1.0.1:
-    resolution: {integrity: sha1-PkcprB9f3gJc19g6iW2rn09n2w8=}
-    engines: {node: '>=0.10.0'}
+  /jest-matcher-utils/26.6.2:
+    resolution: {integrity: 
sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==}
+    engines: {node: '>= 10.14.2'}
+    dependencies:
+      chalk: 4.1.2
+      jest-diff: 26.6.2
+      jest-get-type: 26.3.0
+      pretty-format: 26.6.2
     dev: true
 
-  /is-obj/2.0.0:
-    resolution: {integrity: 
sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==}
-    engines: {node: '>=8'}
+  /jest-matcher-utils/27.5.1:
+    resolution: {integrity: 
sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    dependencies:
+      chalk: 4.1.2
+      jest-diff: 27.5.1
+      jest-get-type: 27.5.1
+      pretty-format: 27.5.1
     dev: true
 
-  /is-path-cwd/2.2.0:
-    resolution: {integrity: 
sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==}
-    engines: {node: '>=6'}
+  /jest-message-util/26.6.2:
+    resolution: {integrity: 
sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==}
+    engines: {node: '>= 10.14.2'}
+    dependencies:
+      '@babel/code-frame': 7.18.6
+      '@jest/types': 26.6.2
+      '@types/stack-utils': 2.0.1
+      chalk: 4.1.2
+      graceful-fs: 4.2.10
+      micromatch: 4.0.5
+      pretty-format: 26.6.2
+      slash: 3.0.0
+      stack-utils: 2.0.5
     dev: true
 
-  /is-path-inside/3.0.3:
-    resolution: {integrity: 
sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
-    engines: {node: '>=8'}
+  /jest-message-util/27.5.1:
+    resolution: {integrity: 
sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    dependencies:
+      '@babel/code-frame': 7.16.7
+      '@jest/types': 27.5.1
+      '@types/stack-utils': 2.0.1
+      chalk: 4.1.2
+      graceful-fs: 4.2.10
+      micromatch: 4.0.5
+      pretty-format: 27.5.1
+      slash: 3.0.0
+      stack-utils: 2.0.5
     dev: true
 
-  /is-plain-obj/2.1.0:
-    resolution: {integrity: 
sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==}
-    engines: {node: '>=8'}
+  /jest-message-util/28.1.3:
+    resolution: {integrity: 
sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==}
+    engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
+    dependencies:
+      '@babel/code-frame': 7.18.6
+      '@jest/types': 28.1.3
+      '@types/stack-utils': 2.0.1
+      chalk: 4.1.2
+      graceful-fs: 4.2.10
+      micromatch: 4.0.5
+      pretty-format: 28.1.3
+      slash: 3.0.0
+      stack-utils: 2.0.5
     dev: true
 
-  /is-plain-obj/3.0.0:
-    resolution: {integrity: 
sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==}
-    engines: {node: '>=10'}
+  /jest-mock/26.6.2:
+    resolution: {integrity: 
sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==}
+    engines: {node: '>= 10.14.2'}
+    dependencies:
+      '@jest/types': 26.6.2
+      '@types/node': 18.8.5
     dev: true
 
-  /is-plain-object/2.0.4:
-    resolution: {integrity: 
sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==}
-    engines: {node: '>=0.10.0'}
+  /jest-mock/27.5.1:
+    resolution: {integrity: 
sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dependencies:
-      isobject: 3.0.1
+      '@jest/types': 27.5.1
+      '@types/node': 18.8.5
     dev: true
 
-  /is-plain-object/5.0.0:
-    resolution: {integrity: 
sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==}
-    engines: {node: '>=0.10.0'}
+  /jest-pnp-resolver/1.2.2_jest-resolve@26.6.2:
+    resolution: {integrity: 
sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==}
+    engines: {node: '>=6'}
+    peerDependencies:
+      jest-resolve: '*'
+    peerDependenciesMeta:
+      jest-resolve:
+        optional: true
+    dependencies:
+      jest-resolve: 26.6.2
     dev: true
 
-  /is-promise/4.0.0:
-    resolution: {integrity: 
sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==}
+  /jest-pnp-resolver/1.2.2_jest-resolve@27.5.1:
+    resolution: {integrity: 
sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==}
+    engines: {node: '>=6'}
+    peerDependencies:
+      jest-resolve: '*'
+    peerDependenciesMeta:
+      jest-resolve:
+        optional: true
+    dependencies:
+      jest-resolve: 27.5.1
     dev: true
 
-  /is-reference/1.2.1:
-    resolution: {integrity: 
sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==}
+  /jest-preset-preact/4.0.5_5pwcttm7mk4uq46yrrfyt2sdyu:
+    resolution: {integrity: 
sha512-MnU7mfpnwopJkdx0WoEyRmrNDIvRN+w6sOur0zEhaRYYMo0gJM7UdZHWTV8k6uo0+ypY+m0kQW6kMukUx4v8JQ==}
+    peerDependencies:
+      jest: 26.x || 27.x
+      preact: 10.x
+      preact-render-to-string: 5.x
     dependencies:
-      '@types/estree': 1.0.0
+      '@babel/core': 7.17.2
+      '@babel/plugin-proposal-class-properties': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-transform-react-jsx': 7.16.7_@babel+core@7.17.2
+      '@babel/preset-env': 7.16.11_@babel+core@7.17.2
+      '@babel/preset-typescript': 7.16.7_@babel+core@7.17.2
+      babel-jest: 27.5.1_@babel+core@7.17.2
+      identity-obj-proxy: 3.0.0
+      isomorphic-unfetch: 3.1.0
+      jest: 26.6.3
+      jest-watch-typeahead: 0.6.5_jest@26.6.3
+      preact: 10.6.1
+      preact-render-to-string: 5.1.19_preact@10.6.1
+    transitivePeerDependencies:
+      - encoding
+      - supports-color
     dev: true
 
-  /is-regex/1.1.4:
-    resolution: {integrity: 
sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
-    engines: {node: '>= 0.4'}
+  /jest-preset-preact/4.0.5_e2p4bsvs32uygapo46tobni7si:
+    resolution: {integrity: 
sha512-MnU7mfpnwopJkdx0WoEyRmrNDIvRN+w6sOur0zEhaRYYMo0gJM7UdZHWTV8k6uo0+ypY+m0kQW6kMukUx4v8JQ==}
+    peerDependencies:
+      jest: 26.x || 27.x
+      preact: 10.x
+      preact-render-to-string: 5.x
     dependencies:
-      call-bind: 1.0.2
-      has-tostringtag: 1.0.0
+      '@babel/core': 7.17.2
+      '@babel/plugin-proposal-class-properties': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-transform-react-jsx': 7.16.7_@babel+core@7.17.2
+      '@babel/preset-env': 7.16.11_@babel+core@7.17.2
+      '@babel/preset-typescript': 7.16.7_@babel+core@7.17.2
+      babel-jest: 27.5.1_@babel+core@7.17.2
+      identity-obj-proxy: 3.0.0
+      isomorphic-unfetch: 3.1.0
+      jest: 27.5.1
+      jest-watch-typeahead: 0.6.5_jest@27.5.1
+      preact: 10.6.5
+      preact-render-to-string: 5.1.19_preact@10.6.5
+    transitivePeerDependencies:
+      - encoding
+      - supports-color
     dev: true
 
-  /is-regexp/1.0.0:
-    resolution: {integrity: sha1-/S2INUXEa6xaYz57mgnof6LLUGk=}
-    engines: {node: '>=0.10.0'}
+  /jest-preset-preact/4.0.5_ewndwes2ovzexxcig72sj2dfke:
+    resolution: {integrity: 
sha512-MnU7mfpnwopJkdx0WoEyRmrNDIvRN+w6sOur0zEhaRYYMo0gJM7UdZHWTV8k6uo0+ypY+m0kQW6kMukUx4v8JQ==}
+    peerDependencies:
+      jest: 26.x || 27.x
+      preact: 10.x
+      preact-render-to-string: 5.x
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/plugin-proposal-class-properties': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-transform-react-jsx': 7.16.7_@babel+core@7.17.2
+      '@babel/preset-env': 7.16.11_@babel+core@7.17.2
+      '@babel/preset-typescript': 7.16.7_@babel+core@7.17.2
+      babel-jest: 27.5.1_@babel+core@7.17.2
+      identity-obj-proxy: 3.0.0
+      isomorphic-unfetch: 3.1.0
+      jest: 26.6.3
+      jest-watch-typeahead: 0.6.5_jest@26.6.3
+      preact: 10.6.5
+      preact-render-to-string: 5.1.19_preact@10.6.5
+    transitivePeerDependencies:
+      - encoding
+      - supports-color
     dev: true
 
-  /is-resolvable/1.1.0:
-    resolution: {integrity: 
sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==}
+  /jest-regex-util/26.0.0:
+    resolution: {integrity: 
sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==}
+    engines: {node: '>= 10.14.2'}
     dev: true
 
-  /is-shared-array-buffer/1.0.1:
-    resolution: {integrity: 
sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==}
+  /jest-regex-util/27.5.1:
+    resolution: {integrity: 
sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dev: true
 
-  /is-stream/2.0.1:
-    resolution: {integrity: 
sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
-    engines: {node: '>=8'}
+  /jest-regex-util/28.0.2:
+    resolution: {integrity: 
sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==}
+    engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
     dev: true
 
-  /is-string/1.0.7:
-    resolution: {integrity: 
sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==}
-    engines: {node: '>= 0.4'}
+  /jest-resolve-dependencies/26.6.3:
+    resolution: {integrity: 
sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==}
+    engines: {node: '>= 10.14.2'}
     dependencies:
-      has-tostringtag: 1.0.0
+      '@jest/types': 26.6.2
+      jest-regex-util: 26.0.0
+      jest-snapshot: 26.6.2
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /is-symbol/1.0.4:
-    resolution: {integrity: 
sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==}
-    engines: {node: '>= 0.4'}
+  /jest-resolve-dependencies/27.5.1:
+    resolution: {integrity: 
sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dependencies:
-      has-symbols: 1.0.2
+      '@jest/types': 27.5.1
+      jest-regex-util: 27.5.1
+      jest-snapshot: 27.5.1
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /is-typedarray/1.0.0:
-    resolution: {integrity: 
sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==}
+  /jest-resolve/26.6.2:
+    resolution: {integrity: 
sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==}
+    engines: {node: '>= 10.14.2'}
+    dependencies:
+      '@jest/types': 26.6.2
+      chalk: 4.1.2
+      graceful-fs: 4.2.10
+      jest-pnp-resolver: 1.2.2_jest-resolve@26.6.2
+      jest-util: 26.6.2
+      read-pkg-up: 7.0.1
+      resolve: 1.22.1
+      slash: 3.0.0
     dev: true
 
-  /is-unicode-supported/0.1.0:
-    resolution: {integrity: 
sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==}
-    engines: {node: '>=10'}
+  /jest-resolve/27.5.1:
+    resolution: {integrity: 
sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    dependencies:
+      '@jest/types': 27.5.1
+      chalk: 4.1.2
+      graceful-fs: 4.2.10
+      jest-haste-map: 27.5.1
+      jest-pnp-resolver: 1.2.2_jest-resolve@27.5.1
+      jest-util: 27.5.1
+      jest-validate: 27.5.1
+      resolve: 1.22.1
+      resolve.exports: 1.1.0
+      slash: 3.0.0
     dev: true
 
-  /is-unicode-supported/1.3.0:
-    resolution: {integrity: 
sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==}
-    engines: {node: '>=12'}
+  /jest-runner/26.6.3:
+    resolution: {integrity: 
sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==}
+    engines: {node: '>= 10.14.2'}
+    dependencies:
+      '@jest/console': 26.6.2
+      '@jest/environment': 26.6.2
+      '@jest/test-result': 26.6.2
+      '@jest/types': 26.6.2
+      '@types/node': 18.8.5
+      chalk: 4.1.2
+      emittery: 0.7.2
+      exit: 0.1.2
+      graceful-fs: 4.2.10
+      jest-config: 26.6.3
+      jest-docblock: 26.0.0
+      jest-haste-map: 26.6.2
+      jest-leak-detector: 26.6.2
+      jest-message-util: 26.6.2
+      jest-resolve: 26.6.2
+      jest-runtime: 26.6.3
+      jest-util: 26.6.2
+      jest-worker: 26.6.2
+      source-map-support: 0.5.21
+      throat: 5.0.0
+    transitivePeerDependencies:
+      - bufferutil
+      - canvas
+      - supports-color
+      - ts-node
+      - utf-8-validate
     dev: true
 
-  /is-weakref/1.0.2:
-    resolution: {integrity: 
sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==}
+  /jest-runner/27.5.1:
+    resolution: {integrity: 
sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dependencies:
-      call-bind: 1.0.2
+      '@jest/console': 27.5.1
+      '@jest/environment': 27.5.1
+      '@jest/test-result': 27.5.1
+      '@jest/transform': 27.5.1
+      '@jest/types': 27.5.1
+      '@types/node': 18.8.5
+      chalk: 4.1.2
+      emittery: 0.8.1
+      graceful-fs: 4.2.10
+      jest-docblock: 27.5.1
+      jest-environment-jsdom: 27.5.1
+      jest-environment-node: 27.5.1
+      jest-haste-map: 27.5.1
+      jest-leak-detector: 27.5.1
+      jest-message-util: 27.5.1
+      jest-resolve: 27.5.1
+      jest-runtime: 27.5.1
+      jest-util: 27.5.1
+      jest-worker: 27.5.1
+      source-map-support: 0.5.21
+      throat: 6.0.1
+    transitivePeerDependencies:
+      - bufferutil
+      - canvas
+      - supports-color
+      - utf-8-validate
     dev: true
 
-  /is-windows/1.0.2:
-    resolution: {integrity: 
sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==}
-    engines: {node: '>=0.10.0'}
+  /jest-runtime/26.6.3:
+    resolution: {integrity: 
sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==}
+    engines: {node: '>= 10.14.2'}
+    hasBin: true
+    dependencies:
+      '@jest/console': 26.6.2
+      '@jest/environment': 26.6.2
+      '@jest/fake-timers': 26.6.2
+      '@jest/globals': 26.6.2
+      '@jest/source-map': 26.6.2
+      '@jest/test-result': 26.6.2
+      '@jest/transform': 26.6.2
+      '@jest/types': 26.6.2
+      '@types/yargs': 15.0.14
+      chalk: 4.1.2
+      cjs-module-lexer: 0.6.0
+      collect-v8-coverage: 1.0.1
+      exit: 0.1.2
+      glob: 7.2.3
+      graceful-fs: 4.2.10
+      jest-config: 26.6.3
+      jest-haste-map: 26.6.2
+      jest-message-util: 26.6.2
+      jest-mock: 26.6.2
+      jest-regex-util: 26.0.0
+      jest-resolve: 26.6.2
+      jest-snapshot: 26.6.2
+      jest-util: 26.6.2
+      jest-validate: 26.6.2
+      slash: 3.0.0
+      strip-bom: 4.0.0
+      yargs: 15.4.1
+    transitivePeerDependencies:
+      - bufferutil
+      - canvas
+      - supports-color
+      - ts-node
+      - utf-8-validate
     dev: true
 
-  /is-wsl/1.1.0:
-    resolution: {integrity: sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=}
-    engines: {node: '>=4'}
+  /jest-runtime/27.5.1:
+    resolution: {integrity: 
sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    dependencies:
+      '@jest/environment': 27.5.1
+      '@jest/fake-timers': 27.5.1
+      '@jest/globals': 27.5.1
+      '@jest/source-map': 27.5.1
+      '@jest/test-result': 27.5.1
+      '@jest/transform': 27.5.1
+      '@jest/types': 27.5.1
+      chalk: 4.1.2
+      cjs-module-lexer: 1.2.2
+      collect-v8-coverage: 1.0.1
+      execa: 5.1.1
+      glob: 7.2.3
+      graceful-fs: 4.2.10
+      jest-haste-map: 27.5.1
+      jest-message-util: 27.5.1
+      jest-mock: 27.5.1
+      jest-regex-util: 27.5.1
+      jest-resolve: 27.5.1
+      jest-snapshot: 27.5.1
+      jest-util: 27.5.1
+      slash: 3.0.0
+      strip-bom: 4.0.0
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /is-wsl/2.2.0:
-    resolution: {integrity: 
sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==}
-    engines: {node: '>=8'}
+  /jest-serializer/26.6.2:
+    resolution: {integrity: 
sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==}
+    engines: {node: '>= 10.14.2'}
     dependencies:
-      is-docker: 2.2.1
+      '@types/node': 18.8.5
+      graceful-fs: 4.2.10
     dev: true
 
-  /is-yarn-global/0.3.0:
-    resolution: {integrity: 
sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==}
+  /jest-serializer/27.5.1:
+    resolution: {integrity: 
sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    dependencies:
+      '@types/node': 18.8.5
+      graceful-fs: 4.2.10
     dev: true
 
-  /isarray/1.0.0:
-    resolution: {integrity: sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=}
+  /jest-snapshot/26.6.2:
+    resolution: {integrity: 
sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==}
+    engines: {node: '>= 10.14.2'}
+    dependencies:
+      '@babel/types': 7.19.4
+      '@jest/types': 26.6.2
+      '@types/babel__traverse': 7.18.2
+      '@types/prettier': 2.7.1
+      chalk: 4.1.2
+      expect: 26.6.2
+      graceful-fs: 4.2.10
+      jest-diff: 26.6.2
+      jest-get-type: 26.3.0
+      jest-haste-map: 26.6.2
+      jest-matcher-utils: 26.6.2
+      jest-message-util: 26.6.2
+      jest-resolve: 26.6.2
+      natural-compare: 1.4.0
+      pretty-format: 26.6.2
+      semver: 7.3.8
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /isexe/2.0.0:
-    resolution: {integrity: 
sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+  /jest-snapshot/27.5.1:
+    resolution: {integrity: 
sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/generator': 7.18.2
+      '@babel/plugin-syntax-typescript': 7.16.7_@babel+core@7.19.6
+      '@babel/traverse': 7.18.2
+      '@babel/types': 7.18.4
+      '@jest/transform': 27.5.1
+      '@jest/types': 27.5.1
+      '@types/babel__traverse': 7.18.2
+      '@types/prettier': 2.7.1
+      babel-preset-current-node-syntax: 1.0.1_@babel+core@7.19.6
+      chalk: 4.1.2
+      expect: 27.5.1
+      graceful-fs: 4.2.10
+      jest-diff: 27.5.1
+      jest-get-type: 27.5.1
+      jest-haste-map: 27.5.1
+      jest-matcher-utils: 27.5.1
+      jest-message-util: 27.5.1
+      jest-util: 27.5.1
+      natural-compare: 1.4.0
+      pretty-format: 27.5.1
+      semver: 7.3.8
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
-  /isobject/2.1.0:
-    resolution: {integrity: sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=}
-    engines: {node: '>=0.10.0'}
+  /jest-util/26.6.2:
+    resolution: {integrity: 
sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==}
+    engines: {node: '>= 10.14.2'}
     dependencies:
-      isarray: 1.0.0
+      '@jest/types': 26.6.2
+      '@types/node': 18.8.5
+      chalk: 4.1.2
+      graceful-fs: 4.2.10
+      is-ci: 2.0.0
+      micromatch: 4.0.5
     dev: true
 
-  /isobject/3.0.1:
-    resolution: {integrity: sha1-TkMekrEalzFjaqH5yNHMvP2reN8=}
-    engines: {node: '>=0.10.0'}
+  /jest-util/27.5.1:
+    resolution: {integrity: 
sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    dependencies:
+      '@jest/types': 27.5.1
+      '@types/node': 18.8.5
+      chalk: 4.1.2
+      ci-info: 3.5.0
+      graceful-fs: 4.2.10
+      picomatch: 2.3.1
     dev: true
 
-  /isomorphic-unfetch/3.1.0:
-    resolution: {integrity: 
sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==}
+  /jest-util/28.1.3:
+    resolution: {integrity: 
sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==}
+    engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
     dependencies:
-      node-fetch: 2.6.7
-      unfetch: 4.2.0
-    transitivePeerDependencies:
-      - encoding
+      '@jest/types': 28.1.3
+      '@types/node': 18.8.5
+      chalk: 4.1.2
+      ci-info: 3.5.0
+      graceful-fs: 4.2.10
+      picomatch: 2.3.1
     dev: true
 
-  /isstream/0.1.2:
-    resolution: {integrity: sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=}
+  /jest-validate/26.6.2:
+    resolution: {integrity: 
sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==}
+    engines: {node: '>= 10.14.2'}
+    dependencies:
+      '@jest/types': 26.6.2
+      camelcase: 6.3.0
+      chalk: 4.1.2
+      jest-get-type: 26.3.0
+      leven: 3.1.0
+      pretty-format: 26.6.2
     dev: true
 
-  /istanbul-lib-coverage/3.2.0:
-    resolution: {integrity: 
sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==}
-    engines: {node: '>=8'}
+  /jest-validate/27.5.1:
+    resolution: {integrity: 
sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    dependencies:
+      '@jest/types': 27.5.1
+      camelcase: 6.3.0
+      chalk: 4.1.2
+      jest-get-type: 27.5.1
+      leven: 3.1.0
+      pretty-format: 27.5.1
     dev: true
 
-  /istanbul-lib-hook/3.0.0:
-    resolution: {integrity: 
sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==}
-    engines: {node: '>=8'}
+  /jest-watch-typeahead/0.6.5_jest@26.6.3:
+    resolution: {integrity: 
sha512-GIbV6h37/isatMDtqZlA8Q5vC6T3w+5qdvtF+3LIkPc58zEWzbKmTHvlUIp3wvBm400RzrQWcVPcsAJqKWu7XQ==}
+    engines: {node: '>=10'}
+    peerDependencies:
+      jest: ^26.0.0 || ^27.0.0
     dependencies:
-      append-transform: 2.0.0
+      ansi-escapes: 4.3.2
+      chalk: 4.1.2
+      jest: 26.6.3
+      jest-regex-util: 27.5.1
+      jest-watcher: 27.5.1
+      slash: 3.0.0
+      string-length: 4.0.2
+      strip-ansi: 6.0.1
     dev: true
 
-  /istanbul-lib-instrument/4.0.3:
-    resolution: {integrity: 
sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==}
-    engines: {node: '>=8'}
+  /jest-watch-typeahead/0.6.5_jest@27.5.1:
+    resolution: {integrity: 
sha512-GIbV6h37/isatMDtqZlA8Q5vC6T3w+5qdvtF+3LIkPc58zEWzbKmTHvlUIp3wvBm400RzrQWcVPcsAJqKWu7XQ==}
+    engines: {node: '>=10'}
+    peerDependencies:
+      jest: ^26.0.0 || ^27.0.0
     dependencies:
-      '@babel/core': 7.16.7
-      '@istanbuljs/schema': 0.1.3
-      istanbul-lib-coverage: 3.2.0
-      semver: 6.3.0
-    transitivePeerDependencies:
-      - supports-color
+      ansi-escapes: 4.3.2
+      chalk: 4.1.2
+      jest: 27.5.1
+      jest-regex-util: 27.5.1
+      jest-watcher: 27.5.1
+      slash: 3.0.0
+      string-length: 4.0.2
+      strip-ansi: 6.0.1
     dev: true
 
-  /istanbul-lib-processinfo/2.0.2:
-    resolution: {integrity: 
sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==}
-    engines: {node: '>=8'}
+  /jest-watch-typeahead/1.1.0_jest@27.5.1:
+    resolution: {integrity: 
sha512-Va5nLSJTN7YFtC2jd+7wsoe1pNe5K4ShLux/E5iHEwlB9AxaxmggY7to9KUqKojhaJw3aXqt5WAb4jGPOolpEw==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    peerDependencies:
+      jest: ^27.0.0 || ^28.0.0
     dependencies:
-      archy: 1.0.0
-      cross-spawn: 7.0.3
-      istanbul-lib-coverage: 3.2.0
-      make-dir: 3.1.0
-      p-map: 3.0.0
-      rimraf: 3.0.2
-      uuid: 3.4.0
+      ansi-escapes: 4.3.2
+      chalk: 4.1.2
+      jest: 27.5.1
+      jest-regex-util: 28.0.2
+      jest-watcher: 28.1.3
+      slash: 4.0.0
+      string-length: 5.0.1
+      strip-ansi: 7.0.1
     dev: true
 
-  /istanbul-lib-report/3.0.0:
-    resolution: {integrity: 
sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==}
-    engines: {node: '>=8'}
+  /jest-watcher/26.6.2:
+    resolution: {integrity: 
sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==}
+    engines: {node: '>= 10.14.2'}
     dependencies:
-      istanbul-lib-coverage: 3.2.0
-      make-dir: 3.1.0
-      supports-color: 7.2.0
+      '@jest/test-result': 26.6.2
+      '@jest/types': 26.6.2
+      '@types/node': 18.8.5
+      ansi-escapes: 4.3.2
+      chalk: 4.1.2
+      jest-util: 26.6.2
+      string-length: 4.0.2
     dev: true
 
-  /istanbul-lib-source-maps/4.0.1:
-    resolution: {integrity: 
sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==}
-    engines: {node: '>=10'}
+  /jest-watcher/27.5.1:
+    resolution: {integrity: 
sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
     dependencies:
-      debug: 4.3.3
-      istanbul-lib-coverage: 3.2.0
-      source-map: 0.6.1
-    transitivePeerDependencies:
-      - supports-color
+      '@jest/test-result': 27.5.1
+      '@jest/types': 27.5.1
+      '@types/node': 18.8.5
+      ansi-escapes: 4.3.2
+      chalk: 4.1.2
+      jest-util: 27.5.1
+      string-length: 4.0.2
     dev: true
 
-  /istanbul-reports/3.1.3:
-    resolution: {integrity: 
sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg==}
-    engines: {node: '>=8'}
+  /jest-watcher/28.1.3:
+    resolution: {integrity: 
sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==}
+    engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
     dependencies:
-      html-escaper: 2.0.2
-      istanbul-lib-report: 3.0.0
+      '@jest/test-result': 28.1.3
+      '@jest/types': 28.1.3
+      '@types/node': 18.8.5
+      ansi-escapes: 4.3.2
+      chalk: 4.1.2
+      emittery: 0.10.2
+      jest-util: 28.1.3
+      string-length: 4.0.2
     dev: true
 
-  /jake/10.8.2:
-    resolution: {integrity: 
sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==}
-    hasBin: true
+  /jest-worker/24.9.0:
+    resolution: {integrity: 
sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==}
+    engines: {node: '>= 6'}
     dependencies:
-      async: 0.9.2
-      chalk: 2.4.2
-      filelist: 1.0.2
-      minimatch: 3.0.5
+      merge-stream: 2.0.0
+      supports-color: 6.1.0
     dev: true
 
-  /jed/1.1.1:
-    resolution: {integrity: 
sha512-z35ZSEcXHxLW4yumw0dF6L464NT36vmx3wxJw8MDpraBcWuNVgUPZgPJKcu1HekNgwlMFNqol7i/IpSbjhqwqA==}
-
   /jest-worker/26.6.2:
     resolution: {integrity: 
sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==}
     engines: {node: '>= 10.13.0'}
@@ -8975,6 +19251,52 @@ packages:
       supports-color: 7.2.0
     dev: true
 
+  /jest-worker/27.5.1:
+    resolution: {integrity: 
sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==}
+    engines: {node: '>= 10.13.0'}
+    dependencies:
+      '@types/node': 18.8.5
+      merge-stream: 2.0.0
+      supports-color: 8.1.1
+    dev: true
+
+  /jest/26.6.3:
+    resolution: {integrity: 
sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==}
+    engines: {node: '>= 10.14.2'}
+    hasBin: true
+    dependencies:
+      '@jest/core': 26.6.3
+      import-local: 3.1.0
+      jest-cli: 26.6.3
+    transitivePeerDependencies:
+      - bufferutil
+      - canvas
+      - supports-color
+      - ts-node
+      - utf-8-validate
+    dev: true
+
+  /jest/27.5.1:
+    resolution: {integrity: 
sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    hasBin: true
+    peerDependencies:
+      node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
+    peerDependenciesMeta:
+      node-notifier:
+        optional: true
+    dependencies:
+      '@jest/core': 27.5.1
+      import-local: 3.1.0
+      jest-cli: 27.5.1
+    transitivePeerDependencies:
+      - bufferutil
+      - canvas
+      - supports-color
+      - ts-node
+      - utf-8-validate
+    dev: true
+
   /js-string-escape/1.0.1:
     resolution: {integrity: 
sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==}
     engines: {node: '>= 0.8'}
@@ -8999,7 +19321,7 @@ packages:
     dev: true
 
   /jsbn/0.1.1:
-    resolution: {integrity: sha1-peZUwuWi3rXyAdls77yoDA7y9RM=}
+    resolution: {integrity: 
sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==}
     dev: true
 
   /jsdom/12.2.0:
@@ -9036,8 +19358,50 @@ packages:
       - utf-8-validate
     dev: true
 
+  /jsdom/16.7.0:
+    resolution: {integrity: 
sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==}
+    engines: {node: '>=10'}
+    peerDependencies:
+      canvas: ^2.5.0
+    peerDependenciesMeta:
+      canvas:
+        optional: true
+    dependencies:
+      abab: 2.0.5
+      acorn: 8.8.0
+      acorn-globals: 6.0.0
+      cssom: 0.4.4
+      cssstyle: 2.3.0
+      data-urls: 2.0.0
+      decimal.js: 10.4.2
+      domexception: 2.0.1
+      escodegen: 2.0.0
+      form-data: 3.0.1
+      html-encoding-sniffer: 2.0.1
+      http-proxy-agent: 4.0.1
+      https-proxy-agent: 5.0.1
+      is-potential-custom-element-name: 1.0.1
+      nwsapi: 2.2.0
+      parse5: 6.0.1
+      saxes: 5.0.1
+      symbol-tree: 3.2.4
+      tough-cookie: 4.1.2
+      w3c-hr-time: 1.0.2
+      w3c-xmlserializer: 2.0.0
+      webidl-conversions: 6.1.0
+      whatwg-encoding: 1.0.5
+      whatwg-mimetype: 2.3.0
+      whatwg-url: 8.7.0
+      ws: 7.5.7
+      xml-name-validator: 3.0.0
+    transitivePeerDependencies:
+      - bufferutil
+      - supports-color
+      - utf-8-validate
+    dev: true
+
   /jsesc/0.5.0:
-    resolution: {integrity: sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=}
+    resolution: {integrity: 
sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==}
     hasBin: true
     dev: true
 
@@ -9061,7 +19425,6 @@ packages:
 
   /json-schema-traverse/0.4.1:
     resolution: {integrity: 
sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
-    dev: true
 
   /json-schema-traverse/1.0.0:
     resolution: {integrity: 
sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
@@ -9076,11 +19439,11 @@ packages:
     dev: true
 
   /json-stringify-safe/5.0.1:
-    resolution: {integrity: sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=}
+    resolution: {integrity: 
sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==}
     dev: true
 
   /json5/0.5.1:
-    resolution: {integrity: sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=}
+    resolution: {integrity: 
sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==}
     hasBin: true
     dev: true
 
@@ -9089,7 +19452,6 @@ packages:
     hasBin: true
     dependencies:
       minimist: 1.2.5
-    dev: true
 
   /json5/2.2.0:
     resolution: {integrity: 
sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==}
@@ -9099,12 +19461,18 @@ packages:
       minimist: 1.2.5
     dev: true
 
+  /json5/2.2.1:
+    resolution: {integrity: 
sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==}
+    engines: {node: '>=6'}
+    hasBin: true
+    dev: true
+
   /jsonc-parser/3.2.0:
     resolution: {integrity: 
sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==}
     dev: true
 
   /jsonfile/4.0.0:
-    resolution: {integrity: sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=}
+    resolution: {integrity: 
sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==}
     optionalDependencies:
       graceful-fs: 4.2.10
     dev: true
@@ -9144,21 +19512,30 @@ packages:
       object.assign: 4.1.2
     dev: true
 
+  /junk/3.1.0:
+    resolution: {integrity: 
sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==}
+    engines: {node: '>=8'}
+    dev: true
+
   /keyv/3.1.0:
     resolution: {integrity: 
sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==}
     dependencies:
       json-buffer: 3.0.0
     dev: true
 
+  /killable/1.0.1:
+    resolution: {integrity: 
sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==}
+    dev: true
+
   /kind-of/3.2.2:
-    resolution: {integrity: sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=}
+    resolution: {integrity: 
sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==}
     engines: {node: '>=0.10.0'}
     dependencies:
       is-buffer: 1.1.6
     dev: true
 
   /kind-of/4.0.0:
-    resolution: {integrity: sha1-IIE989cSkosgc3hpGkUGb65y3Vc=}
+    resolution: {integrity: 
sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==}
     engines: {node: '>=0.10.0'}
     dependencies:
       is-buffer: 1.1.6
@@ -9213,13 +19590,24 @@ packages:
       package-json: 6.5.0
     dev: true
 
+  /lazy-universal-dotenv/3.0.1:
+    resolution: {integrity: 
sha512-prXSYk799h3GY3iOWnC6ZigYzMPjxN2svgjJ9shk7oMadSNX3wXy0B6F32PMJv7qtMnrIbUxoEHzbutvxR2LBQ==}
+    engines: {node: '>=6.0.0', npm: '>=6.0.0', yarn: '>=1.0.0'}
+    dependencies:
+      '@babel/runtime': 7.17.8
+      app-root-dir: 1.0.2
+      core-js: 3.26.0
+      dotenv: 8.6.0
+      dotenv-expand: 5.1.0
+    dev: true
+
   /leven/3.1.0:
     resolution: {integrity: 
sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
     engines: {node: '>=6'}
     dev: true
 
   /levn/0.3.0:
-    resolution: {integrity: sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=}
+    resolution: {integrity: 
sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==}
     engines: {node: '>= 0.8.0'}
     dependencies:
       prelude-ls: 1.1.2
@@ -9243,6 +19631,18 @@ packages:
     resolution: {integrity: 
sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
     dev: true
 
+  /load-json-file/1.1.0:
+    resolution: {integrity: 
sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      graceful-fs: 4.2.10
+      parse-json: 2.2.0
+      pify: 2.3.0
+      pinkie-promise: 2.0.1
+      strip-bom: 2.0.0
+    dev: true
+    optional: true
+
   /load-json-file/7.0.1:
     resolution: {integrity: 
sha512-Gnxj3ev3mB5TkVBGad0JM6dmLiQL+o0t23JPBZ9sd+yvSLk05mFoqKBw5N8gbbkU4TNXyqCgIrl/VM17OgUIgQ==}
     engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@@ -9254,7 +19654,7 @@ packages:
     dev: true
 
   /loader-utils/0.2.17:
-    resolution: {integrity: sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=}
+    resolution: {integrity: 
sha512-tiv66G0SmiOx+pLWMtGEkfSEejxvb6N6uRrQjfWJIT79W9GMpgKeCAmm9aVBKtd4WEgntciI8CsGqjpDoCWJug==}
     dependencies:
       big.js: 3.2.0
       emojis-list: 2.1.0
@@ -9269,7 +19669,6 @@ packages:
       big.js: 5.2.2
       emojis-list: 3.0.0
       json5: 1.0.1
-    dev: true
 
   /loader-utils/2.0.0:
     resolution: {integrity: 
sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==}
@@ -9277,7 +19676,7 @@ packages:
     dependencies:
       big.js: 5.2.2
       emojis-list: 3.0.0
-      json5: 2.2.0
+      json5: 2.2.1
     dev: true
 
   /loader-utils/2.0.2:
@@ -9289,6 +19688,11 @@ packages:
       json5: 2.2.0
     dev: true
 
+  /local-access/1.1.0:
+    resolution: {integrity: 
sha512-XfegD5pyTAfb+GY6chk283Ox5z8WexG56OvM06RWLpAc/UHozO8X6xAxEkIitZOtsSMM1Yr3DkHgW5W+onLhCw==}
+    engines: {node: '>=6'}
+    dev: true
+
   /locate-path/2.0.0:
     resolution: {integrity: sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=}
     engines: {node: '>=4'}
@@ -9326,16 +19730,32 @@ packages:
       p-locate: 6.0.0
     dev: true
 
+  /lodash-es/4.17.21:
+    resolution: {integrity: 
sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
+    dev: false
+
+  /lodash._reinterpolate/3.0.0:
+    resolution: {integrity: 
sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==}
+    dev: true
+
   /lodash.debounce/4.0.8:
-    resolution: {integrity: sha1-gteb/zCmfEAF/9XiUVMArZyk168=}
+    resolution: {integrity: 
sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
+    dev: true
+
+  /lodash.escape/4.0.1:
+    resolution: {integrity: 
sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw==}
     dev: true
 
   /lodash.flattendeep/4.4.0:
-    resolution: {integrity: sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=}
+    resolution: {integrity: 
sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==}
+    dev: true
+
+  /lodash.isequal/4.5.0:
+    resolution: {integrity: 
sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==}
     dev: true
 
   /lodash.memoize/4.1.2:
-    resolution: {integrity: sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=}
+    resolution: {integrity: 
sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==}
     dev: true
 
   /lodash.merge/4.6.2:
@@ -9343,15 +19763,38 @@ packages:
     dev: true
 
   /lodash.sortby/4.7.0:
-    resolution: {integrity: sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=}
+    resolution: {integrity: 
sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==}
+    dev: true
+
+  /lodash.template/4.5.0:
+    resolution: {integrity: 
sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==}
+    dependencies:
+      lodash._reinterpolate: 3.0.0
+      lodash.templatesettings: 4.2.0
+    dev: true
+
+  /lodash.templatesettings/4.2.0:
+    resolution: {integrity: 
sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==}
+    dependencies:
+      lodash._reinterpolate: 3.0.0
+    dev: true
+
+  /lodash.truncate/4.4.2:
+    resolution: {integrity: 
sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==}
     dev: true
 
   /lodash.uniq/4.5.0:
-    resolution: {integrity: sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=}
+    resolution: {integrity: 
sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==}
     dev: true
 
   /lodash/4.17.21:
     resolution: {integrity: 
sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
+
+  /log-symbols/3.0.0:
+    resolution: {integrity: 
sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==}
+    engines: {node: '>=8'}
+    dependencies:
+      chalk: 2.4.2
     dev: true
 
   /log-symbols/4.1.0:
@@ -9362,19 +19805,39 @@ packages:
       is-unicode-supported: 0.1.0
     dev: true
 
+  /loglevel/1.8.0:
+    resolution: {integrity: 
sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==}
+    engines: {node: '>= 0.6.0'}
+    dev: true
+
   /loose-envify/1.4.0:
     resolution: {integrity: 
sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
     hasBin: true
     dependencies:
       js-tokens: 4.0.0
 
+  /loud-rejection/1.6.0:
+    resolution: {integrity: 
sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      currently-unhandled: 0.4.1
+      signal-exit: 3.0.7
+    dev: true
+    optional: true
+
   /loupe/2.3.4:
     resolution: {integrity: 
sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==}
     dependencies:
       get-func-name: 2.0.0
 
   /lower-case/1.1.4:
-    resolution: {integrity: sha1-miyr0bno4K6ZOkv31YdcOcQujqw=}
+    resolution: {integrity: 
sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==}
+    dev: true
+
+  /lower-case/2.0.2:
+    resolution: {integrity: 
sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
+    dependencies:
+      tslib: 2.4.0
     dev: true
 
   /lowercase-keys/1.0.1:
@@ -9387,6 +19850,13 @@ packages:
     engines: {node: '>=8'}
     dev: true
 
+  /lowlight/1.20.0:
+    resolution: {integrity: 
sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==}
+    dependencies:
+      fault: 1.0.4
+      highlight.js: 10.7.3
+    dev: true
+
   /lru-cache/4.1.5:
     resolution: {integrity: 
sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==}
     dependencies:
@@ -9412,7 +19882,7 @@ packages:
     dev: true
 
   /lz-string/1.4.4:
-    resolution: {integrity: sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=}
+    resolution: {integrity: 
sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==}
     hasBin: true
     dev: true
 
@@ -9437,6 +19907,12 @@ packages:
       semver: 6.3.0
     dev: true
 
+  /makeerror/1.0.12:
+    resolution: {integrity: 
sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==}
+    dependencies:
+      tmpl: 1.0.5
+    dev: true
+
   /map-age-cleaner/0.1.3:
     resolution: {integrity: 
sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==}
     engines: {node: '>=6'}
@@ -9444,16 +19920,73 @@ packages:
       p-defer: 1.0.0
     dev: true
 
-  /map-cache/0.2.2:
-    resolution: {integrity: sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=}
-    engines: {node: '>=0.10.0'}
+  /map-cache/0.2.2:
+    resolution: {integrity: 
sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /map-obj/1.0.1:
+    resolution: {integrity: 
sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+    optional: true
+
+  /map-or-similar/1.5.0:
+    resolution: {integrity: 
sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==}
+    dev: true
+
+  /map-visit/1.0.0:
+    resolution: {integrity: 
sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      object-visit: 1.0.1
+    dev: true
+
+  /markdown-escapes/1.0.4:
+    resolution: {integrity: 
sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==}
+    dev: true
+
+  /markdown-to-jsx/6.11.4:
+    resolution: {integrity: 
sha512-3lRCD5Sh+tfA52iGgfs/XZiw33f7fFX9Bn55aNnVNUd2GzLDkOWyKYYD8Yju2B1Vn+feiEdgJs8T6Tg0xNokPw==}
+    engines: {node: '>= 4'}
+    peerDependencies:
+      react: '>= 0.14.0'
+    dependencies:
+      prop-types: 15.8.1
+      unquote: 1.1.1
+    dev: true
+
+  /markdown-to-jsx/6.11.4_react@16.14.0:
+    resolution: {integrity: 
sha512-3lRCD5Sh+tfA52iGgfs/XZiw33f7fFX9Bn55aNnVNUd2GzLDkOWyKYYD8Yju2B1Vn+feiEdgJs8T6Tg0xNokPw==}
+    engines: {node: '>= 4'}
+    peerDependencies:
+      react: '>= 0.14.0'
+    dependencies:
+      prop-types: 15.8.1
+      react: 16.14.0
+      unquote: 1.1.1
+    dev: true
+
+  /markdown-to-jsx/7.1.7:
+    resolution: {integrity: 
sha512-VI3TyyHlGkO8uFle0IOibzpO1c1iJDcXcS/zBrQrXQQvJ2tpdwVzVZ7XdKsyRz1NdRmre4dqQkMZzUHaKIG/1w==}
+    engines: {node: '>= 10'}
+    peerDependencies:
+      react: '>= 0.14.0'
+    dev: true
+
+  /markdown-to-jsx/7.1.7_react@16.14.0:
+    resolution: {integrity: 
sha512-VI3TyyHlGkO8uFle0IOibzpO1c1iJDcXcS/zBrQrXQQvJ2tpdwVzVZ7XdKsyRz1NdRmre4dqQkMZzUHaKIG/1w==}
+    engines: {node: '>= 10'}
+    peerDependencies:
+      react: '>= 0.14.0'
+    dependencies:
+      react: 16.14.0
     dev: true
 
-  /map-visit/1.0.0:
-    resolution: {integrity: sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=}
-    engines: {node: '>=0.10.0'}
-    dependencies:
-      object-visit: 1.0.1
+  /marked/2.0.7:
+    resolution: {integrity: 
sha512-BJXxkuIfJchcXOJWTT2DOL+yFWifFv2yGYOUzvXg8Qz610QKw+sHCvTMYwA+qWGhlA2uivBezChZ/pBy1tWdkQ==}
+    engines: {node: '>= 8.16.2'}
+    hasBin: true
     dev: true
 
   /marked/4.1.1:
@@ -9484,6 +20017,35 @@ packages:
       safe-buffer: 5.2.1
     dev: true
 
+  /mdast-squeeze-paragraphs/4.0.0:
+    resolution: {integrity: 
sha512-zxdPn69hkQ1rm4J+2Cs2j6wDEv7O17TfXTJ33tl/+JPIoEmtV9t2ZzBM5LPHE8QlHsmVD8t3vPKCyY3oH+H8MQ==}
+    dependencies:
+      unist-util-remove: 2.1.0
+    dev: true
+
+  /mdast-util-definitions/4.0.0:
+    resolution: {integrity: 
sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ==}
+    dependencies:
+      unist-util-visit: 2.0.3
+    dev: true
+
+  /mdast-util-to-hast/10.0.1:
+    resolution: {integrity: 
sha512-BW3LM9SEMnjf4HXXVApZMt8gLQWVNXc3jryK0nJu/rOXPOnlkUjmdkDlmxMirpbU9ILncGFIwLH/ubnWBbcdgA==}
+    dependencies:
+      '@types/mdast': 3.0.10
+      '@types/unist': 2.0.6
+      mdast-util-definitions: 4.0.0
+      mdurl: 1.0.1
+      unist-builder: 2.0.3
+      unist-util-generated: 1.1.6
+      unist-util-position: 3.1.0
+      unist-util-visit: 2.0.3
+    dev: true
+
+  /mdast-util-to-string/1.1.0:
+    resolution: {integrity: 
sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==}
+    dev: true
+
   /mdn-data/2.0.14:
     resolution: {integrity: 
sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==}
     dev: true
@@ -9492,6 +20054,10 @@ packages:
     resolution: {integrity: 
sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==}
     dev: true
 
+  /mdurl/1.0.1:
+    resolution: {integrity: 
sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==}
+    dev: true
+
   /media-typer/0.3.0:
     resolution: {integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=}
     engines: {node: '>= 0.6'}
@@ -9512,8 +20078,14 @@ packages:
       fs-monkey: 1.0.3
     dev: true
 
+  /memoizerific/1.11.3:
+    resolution: {integrity: 
sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==}
+    dependencies:
+      map-or-similar: 1.5.0
+    dev: true
+
   /memory-fs/0.4.1:
-    resolution: {integrity: sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=}
+    resolution: {integrity: 
sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ==}
     dependencies:
       errno: 0.1.8
       readable-stream: 2.3.7
@@ -9527,6 +20099,23 @@ packages:
       readable-stream: 2.3.7
     dev: true
 
+  /meow/3.7.0:
+    resolution: {integrity: 
sha512-TNdwZs0skRlpPpCUK25StC4VH+tP5GgeY1HQOOGP+lQ2xtdkN2VtT/5tiX9k3IWpkBPV9b3LsAWXn4GGi/PrSA==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      camelcase-keys: 2.1.0
+      decamelize: 1.2.0
+      loud-rejection: 1.6.0
+      map-obj: 1.0.1
+      minimist: 1.2.5
+      normalize-package-data: 2.5.0
+      object-assign: 4.1.1
+      read-pkg-up: 1.0.1
+      redent: 1.0.0
+      trim-newlines: 1.0.0
+    dev: true
+    optional: true
+
   /merge-descriptors/1.0.1:
     resolution: {integrity: sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=}
     dev: true
@@ -9541,7 +20130,7 @@ packages:
     dev: true
 
   /methods/1.1.2:
-    resolution: {integrity: sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=}
+    resolution: {integrity: 
sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==}
     engines: {node: '>= 0.6'}
     dev: true
 
@@ -9570,12 +20159,25 @@ packages:
       - supports-color
     dev: true
 
-  /micromatch/4.0.4:
-    resolution: {integrity: 
sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==}
-    engines: {node: '>=8.6'}
+  /micromatch/3.1.10_supports-color@6.1.0:
+    resolution: {integrity: 
sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==}
+    engines: {node: '>=0.10.0'}
     dependencies:
-      braces: 3.0.2
-      picomatch: 2.3.1
+      arr-diff: 4.0.0
+      array-unique: 0.3.2
+      braces: 2.3.2_supports-color@6.1.0
+      define-property: 2.0.2
+      extend-shallow: 3.0.2
+      extglob: 2.0.4_supports-color@6.1.0
+      fragment-cache: 0.2.1
+      kind-of: 6.0.3
+      nanomatch: 1.2.13_supports-color@6.1.0
+      object.pick: 1.3.0
+      regex-not: 1.0.2
+      snapdragon: 0.8.2_supports-color@6.1.0
+      to-regex: 3.0.2
+    transitivePeerDependencies:
+      - supports-color
     dev: true
 
   /micromatch/4.0.5:
@@ -9594,29 +20196,15 @@ packages:
       brorand: 1.1.0
     dev: true
 
-  /mime-db/1.51.0:
-    resolution: {integrity: 
sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==}
-    engines: {node: '>= 0.6'}
-    dev: true
-
   /mime-db/1.52.0:
     resolution: {integrity: 
sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
     engines: {node: '>= 0.6'}
-    dev: false
-
-  /mime-types/2.1.34:
-    resolution: {integrity: 
sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==}
-    engines: {node: '>= 0.6'}
-    dependencies:
-      mime-db: 1.51.0
-    dev: true
 
   /mime-types/2.1.35:
     resolution: {integrity: 
sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
     engines: {node: '>= 0.6'}
     dependencies:
       mime-db: 1.52.0
-    dev: false
 
   /mime/1.6.0:
     resolution: {integrity: 
sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
@@ -9624,6 +20212,12 @@ packages:
     hasBin: true
     dev: true
 
+  /mime/2.6.0:
+    resolution: {integrity: 
sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==}
+    engines: {node: '>=4.0.0'}
+    hasBin: true
+    dev: true
+
   /mimic-fn/2.1.0:
     resolution: {integrity: 
sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
     engines: {node: '>=6'}
@@ -9639,6 +20233,30 @@ packages:
     engines: {node: '>=4'}
     dev: true
 
+  /min-document/2.19.0:
+    resolution: {integrity: 
sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==}
+    dependencies:
+      dom-walk: 0.1.2
+    dev: true
+
+  /min-indent/1.0.1:
+    resolution: {integrity: 
sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
+    engines: {node: '>=4'}
+    dev: true
+
+  /mini-css-extract-plugin/0.9.0_webpack@4.46.0:
+    resolution: {integrity: 
sha512-lp3GeY7ygcgAmVIcRPBVhIkf8Us7FZjA+ILpal44qLdSu11wmjKQ3d9k15lfD7pO4esu9eUIAW7qiYIBppv40A==}
+    engines: {node: '>= 6.9.0'}
+    peerDependencies:
+      webpack: ^4.4.0
+    dependencies:
+      loader-utils: 1.4.0
+      normalize-url: 1.9.1
+      schema-utils: 1.0.0
+      webpack: 4.46.0
+      webpack-sources: 1.4.3
+    dev: true
+
   /mini-css-extract-plugin/1.6.2_webpack@4.46.0:
     resolution: {integrity: 
sha512-WhDvO3SjGm40oV5y26GjMJYjd2UMqrLAGKy5YS2/3QKJy2F7jgynuHTir/tgUUOiNQu5saXHdc8reo7YuhhT4Q==}
     engines: {node: '>= 10.13.0'}
@@ -9651,12 +20269,17 @@ packages:
       webpack-sources: 1.4.3
     dev: true
 
+  /mini-svg-data-uri/1.4.4:
+    resolution: {integrity: 
sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==}
+    hasBin: true
+    dev: true
+
   /minimalistic-assert/1.0.1:
     resolution: {integrity: 
sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==}
     dev: true
 
   /minimalistic-crypto-utils/1.0.1:
-    resolution: {integrity: sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=}
+    resolution: {integrity: 
sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==}
     dev: true
 
   /minimatch/3.0.4:
@@ -9685,7 +20308,6 @@ packages:
 
   /minimist/1.2.5:
     resolution: {integrity: 
sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==}
-    dev: true
 
   /minipass-collect/1.0.2:
     resolution: {integrity: 
sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==}
@@ -9804,8 +20426,12 @@ packages:
       yargs-unparser: 2.0.0
     dev: true
 
+  /moo/0.5.2:
+    resolution: {integrity: 
sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==}
+    dev: true
+
   /move-concurrently/1.0.1:
-    resolution: {integrity: sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=}
+    resolution: {integrity: 
sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ==}
     dependencies:
       aproba: 1.2.0
       copy-concurrently: 1.0.5
@@ -9829,6 +20455,10 @@ packages:
     resolution: {integrity: sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=}
     dev: true
 
+  /ms/2.1.1:
+    resolution: {integrity: 
sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==}
+    dev: true
+
   /ms/2.1.2:
     resolution: {integrity: 
sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
     dev: true
@@ -9838,7 +20468,7 @@ packages:
     dev: true
 
   /multicast-dns-service-types/1.1.0:
-    resolution: {integrity: sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=}
+    resolution: {integrity: 
sha512-cnAsSVxIDsYt0v7HmC0hWZFwwXSh+E6PgCrREDuN/EsjgLwA5XRmlMHhSiDPrt6HxY1gTivEa/Zh7GtODoLevQ==}
     dev: true
 
   /multicast-dns/6.2.3:
@@ -9849,18 +20479,37 @@ packages:
       thunky: 1.1.0
     dev: true
 
+  /mustache/4.2.0:
+    resolution: {integrity: 
sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==}
+    hasBin: true
+    dev: true
+
+  /mute-stream/0.0.8:
+    resolution: {integrity: 
sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==}
+    dev: true
+
   /nan/2.17.0:
     resolution: {integrity: 
sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==}
     requiresBuild: true
     dev: true
     optional: true
 
+  /nanoclone/0.2.1:
+    resolution: {integrity: 
sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==}
+    dev: false
+
   /nanoid/3.2.0:
     resolution: {integrity: 
sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==}
     engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
     hasBin: true
     dev: true
 
+  /nanoid/3.3.4:
+    resolution: {integrity: 
sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==}
+    engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+    hasBin: true
+    dev: true
+
   /nanomatch/1.2.13:
     resolution: {integrity: 
sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==}
     engines: {node: '>=0.10.0'}
@@ -9880,6 +20529,25 @@ packages:
       - supports-color
     dev: true
 
+  /nanomatch/1.2.13_supports-color@6.1.0:
+    resolution: {integrity: 
sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      arr-diff: 4.0.0
+      array-unique: 0.3.2
+      define-property: 2.0.2
+      extend-shallow: 3.0.2
+      fragment-cache: 0.2.1
+      is-windows: 1.0.2
+      kind-of: 6.0.3
+      object.pick: 1.3.0
+      regex-not: 1.0.2
+      snapdragon: 0.8.2_supports-color@6.1.0
+      to-regex: 3.0.2
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /native-url/0.3.4:
     resolution: {integrity: 
sha512-6iM8R99ze45ivyH8vybJ7X0yekIcPf5GgLV5K0ENCbmRcaRIDoj37BC8iLEmaaBfqqb8enuZ5p0uhY+lVAbAcA==}
     dependencies:
@@ -9890,6 +20558,16 @@ packages:
     resolution: {integrity: sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=}
     dev: true
 
+  /nearley/2.20.1:
+    resolution: {integrity: 
sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==}
+    hasBin: true
+    dependencies:
+      commander: 2.20.3
+      moo: 0.5.2
+      railroad-diagrams: 1.0.0
+      randexp: 0.4.6
+    dev: true
+
   /negotiator/0.6.3:
     resolution: {integrity: 
sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==}
     engines: {node: '>= 0.6'}
@@ -9899,12 +20577,27 @@ packages:
     resolution: {integrity: 
sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
     dev: true
 
+  /nested-error-stacks/2.1.1:
+    resolution: {integrity: 
sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==}
+    dev: true
+
+  /nice-try/1.0.5:
+    resolution: {integrity: 
sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==}
+    dev: true
+
   /no-case/2.3.2:
     resolution: {integrity: 
sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==}
     dependencies:
       lower-case: 1.1.4
     dev: true
 
+  /no-case/3.0.4:
+    resolution: {integrity: 
sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
+    dependencies:
+      lower-case: 2.0.2
+      tslib: 2.4.0
+    dev: true
+
   /node-domexception/1.0.0:
     resolution: {integrity: 
sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
     engines: {node: '>=10.5.0'}
@@ -9930,11 +20623,20 @@ packages:
       formdata-polyfill: 4.0.10
     dev: false
 
+  /node-forge/0.10.0:
+    resolution: {integrity: 
sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==}
+    engines: {node: '>= 6.0.0'}
+    dev: true
+
   /node-forge/1.2.1:
     resolution: {integrity: 
sha512-Fcvtbb+zBcZXbTTVwqGA5W+MKBj56UjVRevvchv5XrcyXbmNdesfZL37nlcWOfpgHhgmxApw3tQbTr4CqNmX4w==}
     engines: {node: '>= 6.13.0'}
     dev: true
 
+  /node-int64/0.4.0:
+    resolution: {integrity: 
sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==}
+    dev: true
+
   /node-libs-browser/2.2.1:
     resolution: {integrity: 
sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==}
     dependencies:
@@ -9963,6 +20665,19 @@ packages:
       vm-browserify: 1.1.2
     dev: true
 
+  /node-notifier/8.0.2:
+    resolution: {integrity: 
sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg==}
+    requiresBuild: true
+    dependencies:
+      growly: 1.3.0
+      is-wsl: 2.2.0
+      semver: 7.3.8
+      shellwords: 0.1.1
+      uuid: 8.3.2
+      which: 2.0.2
+    dev: true
+    optional: true
+
   /node-preload/0.2.1:
     resolution: {integrity: 
sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==}
     engines: {node: '>=8'}
@@ -9970,10 +20685,37 @@ packages:
       process-on-spawn: 1.0.0
     dev: true
 
+  /node-releases/1.1.77:
+    resolution: {integrity: 
sha512-rB1DUFUNAN4Gn9keO2K1efO35IDK7yKHCdCaIMvFO7yUYmmZYeDjnGKle26G4rwj+LKRQpjyUUvMkPglwGCYNQ==}
+    dev: true
+
   /node-releases/2.0.2:
     resolution: {integrity: 
sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==}
     dev: true
 
+  /node-releases/2.0.6:
+    resolution: {integrity: 
sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==}
+    dev: true
+
+  /nodent-compiler/3.2.13:
+    resolution: {integrity: 
sha512-nzzWPXZwSdsWie34om+4dLrT/5l1nT/+ig1v06xuSgMtieJVAnMQFuZihUwREM+M7dFso9YoHfDmweexEXXrrw==}
+    engines: {'0': n, '1': o, '2': d, '3': e, '4': ' ', '5': '>', '6': '=', 
'7': ' ', '8': '0', '9': ., '10': '1', '11': '0', '12': ., '13': '0'}
+    dependencies:
+      acorn: 5.7.4
+      acorn-es7-plugin: 1.1.7
+      nodent-transform: 3.2.9
+      source-map: 0.5.7
+    dev: true
+
+  /nodent-runtime/3.2.1:
+    resolution: {integrity: 
sha512-7Ws63oC+215smeKJQCxzrK21VFVlCFBkwl0MOObt0HOpVQXs3u483sAmtkF33nNqZ5rSOQjB76fgyPBmAUrtCA==}
+    requiresBuild: true
+    dev: true
+
+  /nodent-transform/3.2.9:
+    resolution: {integrity: 
sha512-4a5FH4WLi+daH/CGD5o/JWRR8W5tlCkd3nrDSkxbOzscJTyTUITltvOJeQjg3HJ1YgEuNyiPhQbvbtRjkQBByQ==}
+    dev: true
+
   /nofilter/3.1.0:
     resolution: {integrity: 
sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==}
     engines: {node: '>=12.19'}
@@ -9987,13 +20729,21 @@ packages:
       underscore: 1.6.0
     dev: true
 
+  /normalize-package-data/2.5.0:
+    resolution: {integrity: 
sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==}
+    dependencies:
+      hosted-git-info: 2.8.9
+      resolve: 1.22.1
+      semver: 5.7.1
+      validate-npm-package-license: 3.0.4
+    dev: true
+
   /normalize-path/2.1.1:
     resolution: {integrity: 
sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==}
     engines: {node: '>=0.10.0'}
     dependencies:
       remove-trailing-separator: 1.1.0
     dev: true
-    optional: true
 
   /normalize-path/3.0.0:
     resolution: {integrity: 
sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
@@ -10001,10 +20751,20 @@ packages:
     dev: true
 
   /normalize-range/0.1.2:
-    resolution: {integrity: sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=}
+    resolution: {integrity: 
sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
     engines: {node: '>=0.10.0'}
     dev: true
 
+  /normalize-url/1.9.1:
+    resolution: {integrity: 
sha512-A48My/mtCklowHBlI8Fq2jFWK4tX4lJ5E6ytFsSOq1fzpvT0SQSgKhSg7lN5c2uYFOrUAOQp6zhhJnpp1eMloQ==}
+    engines: {node: '>=4'}
+    dependencies:
+      object-assign: 4.1.1
+      prepend-http: 1.0.4
+      query-string: 4.3.4
+      sort-keys: 1.1.2
+    dev: true
+
   /normalize-url/3.3.0:
     resolution: {integrity: 
sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==}
     engines: {node: '>=6'}
@@ -10020,6 +20780,13 @@ packages:
     engines: {node: '>=10'}
     dev: true
 
+  /npm-run-path/2.0.2:
+    resolution: {integrity: 
sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==}
+    engines: {node: '>=4'}
+    dependencies:
+      path-key: 2.0.1
+    dev: true
+
   /npm-run-path/4.0.1:
     resolution: {integrity: 
sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
     engines: {node: '>=8'}
@@ -10027,6 +20794,24 @@ packages:
       path-key: 3.1.1
     dev: true
 
+  /npmlog/4.1.2:
+    resolution: {integrity: 
sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==}
+    dependencies:
+      are-we-there-yet: 1.1.7
+      console-control-strings: 1.1.0
+      gauge: 2.7.4
+      set-blocking: 2.0.0
+    dev: true
+
+  /npmlog/5.0.1:
+    resolution: {integrity: 
sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==}
+    dependencies:
+      are-we-there-yet: 2.0.0
+      console-control-strings: 1.1.0
+      gauge: 3.0.2
+      set-blocking: 2.0.0
+    dev: true
+
   /nth-check/1.0.2:
     resolution: {integrity: 
sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==}
     dependencies:
@@ -10039,6 +20824,15 @@ packages:
       boolbase: 1.0.0
     dev: true
 
+  /num2fraction/1.2.2:
+    resolution: {integrity: 
sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==}
+    dev: true
+
+  /number-is-nan/1.0.1:
+    resolution: {integrity: 
sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
   /nwsapi/2.2.0:
     resolution: {integrity: 
sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==}
     dev: true
@@ -10084,12 +20878,12 @@ packages:
     dev: true
 
   /object-assign/4.1.1:
-    resolution: {integrity: sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=}
+    resolution: {integrity: 
sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
     engines: {node: '>=0.10.0'}
     dev: true
 
   /object-copy/0.1.0:
-    resolution: {integrity: sha1-fn2Fi3gb18mRpBupde04EnVOmYw=}
+    resolution: {integrity: 
sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==}
     engines: {node: '>=0.10.0'}
     dependencies:
       copy-descriptor: 0.1.1
@@ -10101,6 +20895,10 @@ packages:
     resolution: {integrity: 
sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==}
     dev: true
 
+  /object-inspect/1.12.2:
+    resolution: {integrity: 
sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==}
+    dev: true
+
   /object-is/1.1.5:
     resolution: {integrity: 
sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==}
     engines: {node: '>= 0.4'}
@@ -10115,7 +20913,7 @@ packages:
     dev: true
 
   /object-visit/1.0.1:
-    resolution: {integrity: sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=}
+    resolution: {integrity: 
sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==}
     engines: {node: '>=0.10.0'}
     dependencies:
       isobject: 3.0.1
@@ -10131,6 +20929,16 @@ packages:
       object-keys: 1.1.1
     dev: true
 
+  /object.assign/4.1.4:
+    resolution: {integrity: 
sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.2
+      define-properties: 1.1.4
+      has-symbols: 1.0.3
+      object-keys: 1.1.1
+    dev: true
+
   /object.entries/1.1.5:
     resolution: {integrity: 
sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==}
     engines: {node: '>= 0.4'}
@@ -10154,8 +20962,8 @@ packages:
     engines: {node: '>= 0.8'}
     dependencies:
       call-bind: 1.0.2
-      define-properties: 1.1.3
-      es-abstract: 1.19.1
+      define-properties: 1.1.4
+      es-abstract: 1.20.4
     dev: true
 
   /object.hasown/1.1.0:
@@ -10166,7 +20974,7 @@ packages:
     dev: true
 
   /object.pick/1.3.0:
-    resolution: {integrity: sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=}
+    resolution: {integrity: 
sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==}
     engines: {node: '>=0.10.0'}
     dependencies:
       isobject: 3.0.1
@@ -10186,7 +20994,7 @@ packages:
     dev: true
 
   /on-finished/2.3.0:
-    resolution: {integrity: sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=}
+    resolution: {integrity: 
sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==}
     engines: {node: '>= 0.8'}
     dependencies:
       ee-first: 1.1.1
@@ -10209,6 +21017,14 @@ packages:
       mimic-fn: 2.1.0
     dev: true
 
+  /open/7.4.2:
+    resolution: {integrity: 
sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==}
+    engines: {node: '>=8'}
+    dependencies:
+      is-docker: 2.2.1
+      is-wsl: 2.2.0
+    dev: true
+
   /open/8.4.0:
     resolution: {integrity: 
sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==}
     engines: {node: '>=12'}
@@ -10223,6 +21039,23 @@ packages:
     hasBin: true
     dev: true
 
+  /opn/5.5.0:
+    resolution: {integrity: 
sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==}
+    engines: {node: '>=4'}
+    dependencies:
+      is-wsl: 1.1.0
+    dev: true
+
+  /optimize-css-assets-webpack-plugin/5.0.8_webpack@4.46.0:
+    resolution: {integrity: 
sha512-mgFS1JdOtEGzD8l+EuISqL57cKO+We9GcoiQEmdCWRqqck+FGNmYJtx9qfAPzEz+lRrlThWMuGDaRkI/yWNx/Q==}
+    peerDependencies:
+      webpack: ^4.0.0
+    dependencies:
+      cssnano: 4.1.11
+      last-call-webpack-plugin: 3.0.0
+      webpack: 4.46.0
+    dev: true
+
   /optimize-css-assets-webpack-plugin/6.0.1_webpack@4.46.0:
     resolution: {integrity: 
sha512-BshV2UZPfggZLdUfN3zFBbG4sl/DynUI+YCB6fRRDWaqO2OiWN8GPcp4Y0/fEV6B3k9Hzyk3czve3V/8B/SzKQ==}
     peerDependencies:
@@ -10258,6 +21091,20 @@ packages:
       word-wrap: 1.2.3
     dev: true
 
+  /ora/4.1.1:
+    resolution: {integrity: 
sha512-sjYP8QyVWBpBZWD6Vr1M/KwknSw6kJOz41tvGMlwWeClHBtYKTbHMki1PsLZnxKpXMPbTKv9b3pjQu3REib96A==}
+    engines: {node: '>=8'}
+    dependencies:
+      chalk: 3.0.0
+      cli-cursor: 3.1.0
+      cli-spinners: 2.6.1
+      is-interactive: 1.0.0
+      log-symbols: 3.0.0
+      mute-stream: 0.0.8
+      strip-ansi: 6.0.1
+      wcwidth: 1.0.1
+    dev: true
+
   /ora/5.4.1:
     resolution: {integrity: 
sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==}
     engines: {node: '>=10'}
@@ -10274,7 +21121,24 @@ packages:
     dev: true
 
   /os-browserify/0.3.0:
-    resolution: {integrity: sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=}
+    resolution: {integrity: 
sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==}
+    dev: true
+
+  /os-homedir/1.0.2:
+    resolution: {integrity: 
sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+    optional: true
+
+  /overlayscrollbars/1.13.3:
+    resolution: {integrity: 
sha512-1nB/B5kaakJuHXaLXLRK0bUIilWhUGT6q5g+l2s5vqYdLle/sd0kscBHkQC1kuuDg9p9WR4MTdySDOPbeL/86g==}
+    dev: true
+
+  /p-all/2.1.0:
+    resolution: {integrity: 
sha512-HbZxz5FONzz/z2gJfk6bFca0BCiSRF8jU3yCsWOen/vR6lZjfPOu/e7L3uFzTW1i0H8TlC3vqQstEJPQL4/uLA==}
+    engines: {node: '>=6'}
+    dependencies:
+      p-map: 2.1.0
     dev: true
 
   /p-cancelable/1.1.0:
@@ -10287,6 +21151,18 @@ packages:
     engines: {node: '>=4'}
     dev: true
 
+  /p-each-series/2.2.0:
+    resolution: {integrity: 
sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==}
+    engines: {node: '>=8'}
+    dev: true
+
+  /p-event/4.2.0:
+    resolution: {integrity: 
sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==}
+    engines: {node: '>=8'}
+    dependencies:
+      p-timeout: 3.2.0
+    dev: true
+
   /p-event/5.0.1:
     resolution: {integrity: 
sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==}
     engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@@ -10294,6 +21170,18 @@ packages:
       p-timeout: 5.1.0
     dev: true
 
+  /p-filter/2.1.0:
+    resolution: {integrity: 
sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==}
+    engines: {node: '>=8'}
+    dependencies:
+      p-map: 2.1.0
+    dev: true
+
+  /p-finally/1.0.0:
+    resolution: {integrity: 
sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==}
+    engines: {node: '>=4'}
+    dev: true
+
   /p-limit/1.3.0:
     resolution: {integrity: 
sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==}
     engines: {node: '>=4'}
@@ -10357,6 +21245,11 @@ packages:
       p-limit: 4.0.0
     dev: true
 
+  /p-map/2.1.0:
+    resolution: {integrity: 
sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==}
+    engines: {node: '>=6'}
+    dev: true
+
   /p-map/3.0.0:
     resolution: {integrity: 
sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==}
     engines: {node: '>=8'}
@@ -10378,6 +21271,13 @@ packages:
       aggregate-error: 4.0.1
     dev: true
 
+  /p-retry/3.0.1:
+    resolution: {integrity: 
sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==}
+    engines: {node: '>=6'}
+    dependencies:
+      retry: 0.12.0
+    dev: true
+
   /p-retry/4.6.1:
     resolution: {integrity: 
sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA==}
     engines: {node: '>=8'}
@@ -10386,13 +21286,20 @@ packages:
       retry: 0.13.1
     dev: true
 
+  /p-timeout/3.2.0:
+    resolution: {integrity: 
sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==}
+    engines: {node: '>=8'}
+    dependencies:
+      p-finally: 1.0.0
+    dev: true
+
   /p-timeout/5.1.0:
     resolution: {integrity: 
sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==}
     engines: {node: '>=12'}
     dev: true
 
   /p-try/1.0.0:
-    resolution: {integrity: sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=}
+    resolution: {integrity: 
sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==}
     engines: {node: '>=4'}
     dev: true
 
@@ -10405,7 +21312,7 @@ packages:
     resolution: {integrity: 
sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==}
     engines: {node: '>=8'}
     dependencies:
-      graceful-fs: 4.2.9
+      graceful-fs: 4.2.10
       hasha: 5.2.2
       lodash.flattendeep: 4.4.0
       release-zalgo: 1.0.0
@@ -10434,11 +21341,18 @@ packages:
     dev: true
 
   /param-case/2.1.1:
-    resolution: {integrity: sha1-35T9jPZTHs915r75oIWPvHK+Ikc=}
+    resolution: {integrity: 
sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==}
     dependencies:
       no-case: 2.3.2
     dev: true
 
+  /param-case/3.0.4:
+    resolution: {integrity: 
sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==}
+    dependencies:
+      dot-case: 3.0.4
+      tslib: 2.4.0
+    dev: true
+
   /parent-module/1.0.1:
     resolution: {integrity: 
sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
     engines: {node: '>=6'}
@@ -10456,8 +21370,27 @@ packages:
       safe-buffer: 5.2.1
     dev: true
 
+  /parse-entities/2.0.0:
+    resolution: {integrity: 
sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==}
+    dependencies:
+      character-entities: 1.2.4
+      character-entities-legacy: 1.1.4
+      character-reference-invalid: 1.1.4
+      is-alphanumerical: 1.0.4
+      is-decimal: 1.0.4
+      is-hexadecimal: 1.0.4
+    dev: true
+
+  /parse-json/2.2.0:
+    resolution: {integrity: 
sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      error-ex: 1.3.2
+    dev: true
+    optional: true
+
   /parse-json/4.0.0:
-    resolution: {integrity: sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=}
+    resolution: {integrity: 
sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==}
     engines: {node: '>=4'}
     dependencies:
       error-ex: 1.3.2
@@ -10468,7 +21401,7 @@ packages:
     resolution: {integrity: 
sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
     engines: {node: '>=8'}
     dependencies:
-      '@babel/code-frame': 7.16.7
+      '@babel/code-frame': 7.18.6
       error-ex: 1.3.2
       json-parse-even-better-errors: 2.3.1
       lines-and-columns: 1.2.4
@@ -10479,6 +21412,13 @@ packages:
     engines: {node: '>=6'}
     dev: true
 
+  /parse5-htmlparser2-tree-adapter/7.0.0:
+    resolution: {integrity: 
sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==}
+    dependencies:
+      domhandler: 5.0.3
+      parse5: 7.1.1
+    dev: true
+
   /parse5/4.0.0:
     resolution: {integrity: 
sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==}
     dev: true
@@ -10487,13 +21427,30 @@ packages:
     resolution: {integrity: 
sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==}
     dev: true
 
+  /parse5/6.0.1:
+    resolution: {integrity: 
sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==}
+    dev: true
+
+  /parse5/7.1.1:
+    resolution: {integrity: 
sha512-kwpuwzB+px5WUg9pyK0IcK/shltJN5/OVhQagxhCQNtT9Y9QRZqNY2e1cmbu/paRh5LMnz/oVTVLBpjFmMZhSg==}
+    dependencies:
+      entities: 4.4.0
+    dev: true
+
   /parseurl/1.3.3:
     resolution: {integrity: 
sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
     engines: {node: '>= 0.8'}
     dev: true
 
+  /pascal-case/3.1.2:
+    resolution: {integrity: 
sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==}
+    dependencies:
+      no-case: 3.0.4
+      tslib: 2.4.0
+    dev: true
+
   /pascalcase/0.1.1:
-    resolution: {integrity: sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=}
+    resolution: {integrity: 
sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==}
     engines: {node: '>=0.10.0'}
     dev: true
 
@@ -10502,7 +21459,14 @@ packages:
     dev: true
 
   /path-dirname/1.0.2:
-    resolution: {integrity: sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=}
+    resolution: {integrity: 
sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==}
+    dev: true
+
+  /path-exists/2.1.0:
+    resolution: {integrity: 
sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      pinkie-promise: 2.0.1
     dev: true
     optional: true
 
@@ -10525,6 +21489,15 @@ packages:
     resolution: {integrity: 
sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
     engines: {node: '>=0.10.0'}
 
+  /path-is-inside/1.0.2:
+    resolution: {integrity: 
sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==}
+    dev: true
+
+  /path-key/2.0.1:
+    resolution: {integrity: 
sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==}
+    engines: {node: '>=4'}
+    dev: true
+
   /path-key/3.1.1:
     resolution: {integrity: 
sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
     engines: {node: '>=8'}
@@ -10538,6 +21511,23 @@ packages:
     resolution: {integrity: sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=}
     dev: true
 
+  /path-type/1.1.0:
+    resolution: {integrity: 
sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      graceful-fs: 4.2.10
+      pify: 2.3.0
+      pinkie-promise: 2.0.1
+    dev: true
+    optional: true
+
+  /path-type/3.0.0:
+    resolution: {integrity: 
sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==}
+    engines: {node: '>=4'}
+    dependencies:
+      pify: 3.0.0
+    dev: true
+
   /path-type/4.0.0:
     resolution: {integrity: 
sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
     engines: {node: '>=8'}
@@ -10558,7 +21548,7 @@ packages:
     dev: true
 
   /performance-now/2.1.0:
-    resolution: {integrity: sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=}
+    resolution: {integrity: 
sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==}
     dev: true
 
   /picocolors/0.2.1:
@@ -10574,11 +21564,38 @@ packages:
     engines: {node: '>=8.6'}
     dev: true
 
+  /pify/2.3.0:
+    resolution: {integrity: 
sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /pify/3.0.0:
+    resolution: {integrity: 
sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==}
+    engines: {node: '>=4'}
+    dev: true
+
   /pify/4.0.1:
     resolution: {integrity: 
sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==}
     engines: {node: '>=6'}
     dev: true
 
+  /pinkie-promise/2.0.1:
+    resolution: {integrity: 
sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      pinkie: 2.0.4
+    dev: true
+
+  /pinkie/2.0.4:
+    resolution: {integrity: 
sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /pirates/4.0.5:
+    resolution: {integrity: 
sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==}
+    engines: {node: '>= 6'}
+    dev: true
+
   /pkg-conf/4.0.0:
     resolution: {integrity: 
sha512-7dmgi4UY4qk+4mj5Cd8v/GExPo0K+SlY+hulOSdfZ/T6jVH6//y7NtzZo5WrfhDBxuQ0jCa7fLZmNaNh7EWL/w==}
     engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@@ -10601,6 +21618,20 @@ packages:
       find-up: 4.1.0
     dev: true
 
+  /pkg-dir/5.0.0:
+    resolution: {integrity: 
sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==}
+    engines: {node: '>=10'}
+    dependencies:
+      find-up: 5.0.0
+    dev: true
+
+  /pkg-up/3.1.0:
+    resolution: {integrity: 
sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==}
+    engines: {node: '>=8'}
+    dependencies:
+      find-up: 3.0.0
+    dev: true
+
   /plur/5.1.0:
     resolution: {integrity: 
sha512-VP/72JeXqak2KiOzjgKtQen5y3IZHn+9GOuLDafPv0eXa47xq0At93XahYBs26MsifCQ4enGKwbjBTKgb9QJXg==}
     engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@@ -10612,6 +21643,15 @@ packages:
     resolution: {integrity: 
sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==}
     dev: true
 
+  /pnp-webpack-plugin/1.6.4_typescript@4.8.4:
+    resolution: {integrity: 
sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==}
+    engines: {node: '>=6'}
+    dependencies:
+      ts-pnp: 1.2.0_typescript@4.8.4
+    transitivePeerDependencies:
+      - typescript
+    dev: true
+
   /pnp-webpack-plugin/1.7.0_typescript@4.2.4:
     resolution: {integrity: 
sha512-2Rb3vm+EXble/sMXNSu6eoBx8e79gKqhNq9F5ZWW6ERNCTE/Q0wQNne5541tE5vKjfM8hpNCYL+LGc1YTfI0dg==}
     engines: {node: '>=6'}
@@ -10637,6 +21677,13 @@ packages:
       '@babel/runtime': 7.17.2
     dev: true
 
+  /polished/4.2.2:
+    resolution: {integrity: 
sha512-Sz2Lkdxz6F2Pgnpi9U5Ng/WdWAUZxmHrNPoVlm3aAemxoy2Qy7LGjQg4uf8qKelDAUW94F4np3iH2YPf2qefcQ==}
+    engines: {node: '>=10'}
+    dependencies:
+      '@babel/runtime': 7.17.8
+    dev: true
+
   /portfinder/1.0.28:
     resolution: {integrity: 
sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==}
     engines: {node: '>= 0.12.0'}
@@ -10648,8 +21695,19 @@ packages:
       - supports-color
     dev: true
 
+  /portfinder/1.0.28_supports-color@6.1.0:
+    resolution: {integrity: 
sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==}
+    engines: {node: '>= 0.12.0'}
+    dependencies:
+      async: 2.6.3
+      debug: 3.2.7_supports-color@6.1.0
+      mkdirp: 0.5.5
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /posix-character-classes/0.1.1:
-    resolution: {integrity: sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=}
+    resolution: {integrity: 
sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==}
     engines: {node: '>=0.10.0'}
     dev: true
 
@@ -10675,7 +21733,7 @@ packages:
     resolution: {integrity: 
sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      browserslist: 4.19.1
+      browserslist: 4.21.4
       color: 3.2.1
       has: 1.0.3
       postcss: 7.0.39
@@ -10688,7 +21746,7 @@ packages:
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      browserslist: 4.19.1
+      browserslist: 4.21.4
       caniuse-api: 3.0.0
       colord: 2.9.2
       postcss: 8.4.6
@@ -10777,6 +21835,20 @@ packages:
       postcss: 8.4.6
     dev: true
 
+  /postcss-flexbugs-fixes/4.2.1:
+    resolution: {integrity: 
sha512-9SiofaZ9CWpQWxOwRh1b/r85KD5y7GgvsNt1056k6OYLvWUun0czCvogfJgylC22uJTwW1KzY3Gz65NZRlvoiQ==}
+    dependencies:
+      postcss: 7.0.39
+    dev: true
+
+  /postcss-load-config/2.1.2:
+    resolution: {integrity: 
sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw==}
+    engines: {node: '>= 4'}
+    dependencies:
+      cosmiconfig: 5.2.1
+      import-cwd: 2.1.0
+    dev: true
+
   /postcss-load-config/3.1.2:
     resolution: {integrity: 
sha512-X1NVP1itP6VE5dDA4wR6NK1g9lNlkBx9A+tgDKb/8Mnx4HrvX6k+DcTXGelZvfp6p4zCBZjh4Gwyp4aptOUI9Q==}
     engines: {node: '>= 10'}
@@ -10790,6 +21862,32 @@ packages:
       yaml: 1.10.2
     dev: true
 
+  /postcss-loader/3.0.0:
+    resolution: {integrity: 
sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==}
+    engines: {node: '>= 6'}
+    dependencies:
+      loader-utils: 1.4.0
+      postcss: 7.0.39
+      postcss-load-config: 2.1.2
+      schema-utils: 1.0.0
+    dev: true
+
+  /postcss-loader/4.3.0_gzaxsinx64nntyd3vmdqwl7coe:
+    resolution: {integrity: 
sha512-M/dSoIiNDOo8Rk0mUqoj4kpGq91gcxCfb9PoyZVdZ76/AuhxylHDYZblNE8o+EQ9AMSASeMFEKxZf5aU6wlx1Q==}
+    engines: {node: '>= 10.13.0'}
+    peerDependencies:
+      postcss: ^7.0.0 || ^8.0.1
+      webpack: ^4.0.0 || ^5.0.0
+    dependencies:
+      cosmiconfig: 7.0.1
+      klona: 2.0.5
+      loader-utils: 2.0.2
+      postcss: 7.0.39
+      schema-utils: 3.1.1
+      semver: 7.3.8
+      webpack: 4.46.0
+    dev: true
+
   /postcss-loader/4.3.0_sa6x6oa3aqtj2o2n4wqcmgxr4e:
     resolution: {integrity: 
sha512-M/dSoIiNDOo8Rk0mUqoj4kpGq91gcxCfb9PoyZVdZ76/AuhxylHDYZblNE8o+EQ9AMSASeMFEKxZf5aU6wlx1Q==}
     engines: {node: '>= 10.13.0'}
@@ -10802,7 +21900,7 @@ packages:
       loader-utils: 2.0.2
       postcss: 8.4.6
       schema-utils: 3.1.1
-      semver: 7.3.5
+      semver: 7.3.8
       webpack: 4.46.0
     dev: true
 
@@ -10831,7 +21929,7 @@ packages:
     resolution: {integrity: 
sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      browserslist: 4.19.1
+      browserslist: 4.21.4
       caniuse-api: 3.0.0
       cssnano-util-same-parent: 4.0.1
       postcss: 7.0.39
@@ -10845,7 +21943,7 @@ packages:
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      browserslist: 4.19.1
+      browserslist: 4.21.4
       caniuse-api: 3.0.0
       cssnano-utils: 3.0.2_postcss@8.4.6
       postcss: 8.4.6
@@ -10897,7 +21995,7 @@ packages:
     engines: {node: '>=6.9.0'}
     dependencies:
       alphanum-sort: 1.0.2
-      browserslist: 4.19.1
+      browserslist: 4.21.4
       cssnano-util-get-arguments: 4.0.0
       postcss: 7.0.39
       postcss-value-parser: 3.3.1
@@ -10910,7 +22008,7 @@ packages:
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      browserslist: 4.19.1
+      browserslist: 4.21.4
       cssnano-utils: 3.0.2_postcss@8.4.6
       postcss: 8.4.6
       postcss-value-parser: 4.2.0
@@ -10936,6 +22034,13 @@ packages:
       postcss-selector-parser: 6.0.9
     dev: true
 
+  /postcss-modules-extract-imports/2.0.0:
+    resolution: {integrity: 
sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==}
+    engines: {node: '>= 6'}
+    dependencies:
+      postcss: 7.0.39
+    dev: true
+
   /postcss-modules-extract-imports/3.0.0_postcss@8.4.6:
     resolution: {integrity: 
sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==}
     engines: {node: ^10 || ^12 || >= 14}
@@ -10945,6 +22050,16 @@ packages:
       postcss: 8.4.6
     dev: true
 
+  /postcss-modules-local-by-default/3.0.3:
+    resolution: {integrity: 
sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==}
+    engines: {node: '>= 6'}
+    dependencies:
+      icss-utils: 4.1.1
+      postcss: 7.0.39
+      postcss-selector-parser: 6.0.9
+      postcss-value-parser: 4.2.0
+    dev: true
+
   /postcss-modules-local-by-default/4.0.0_postcss@8.4.6:
     resolution: {integrity: 
sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==}
     engines: {node: ^10 || ^12 || >= 14}
@@ -10957,6 +22072,14 @@ packages:
       postcss-value-parser: 4.2.0
     dev: true
 
+  /postcss-modules-scope/2.2.0:
+    resolution: {integrity: 
sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==}
+    engines: {node: '>= 6'}
+    dependencies:
+      postcss: 7.0.39
+      postcss-selector-parser: 6.0.9
+    dev: true
+
   /postcss-modules-scope/3.0.0_postcss@8.4.6:
     resolution: {integrity: 
sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==}
     engines: {node: ^10 || ^12 || >= 14}
@@ -10967,6 +22090,13 @@ packages:
       postcss-selector-parser: 6.0.9
     dev: true
 
+  /postcss-modules-values/3.0.0:
+    resolution: {integrity: 
sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==}
+    dependencies:
+      icss-utils: 4.1.1
+      postcss: 7.0.39
+    dev: true
+
   /postcss-modules-values/4.0.0_postcss@8.4.6:
     resolution: {integrity: 
sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==}
     engines: {node: ^10 || ^12 || >= 14}
@@ -11094,7 +22224,7 @@ packages:
     resolution: {integrity: 
sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      browserslist: 4.19.1
+      browserslist: 4.21.4
       postcss: 7.0.39
       postcss-value-parser: 3.3.1
     dev: true
@@ -11105,7 +22235,7 @@ packages:
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      browserslist: 4.19.1
+      browserslist: 4.21.4
       postcss: 8.4.6
       postcss-value-parser: 4.2.0
     dev: true
@@ -11173,7 +22303,7 @@ packages:
     resolution: {integrity: 
sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      browserslist: 4.19.1
+      browserslist: 4.21.4
       caniuse-api: 3.0.0
       has: 1.0.3
       postcss: 7.0.39
@@ -11185,7 +22315,7 @@ packages:
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      browserslist: 4.19.1
+      browserslist: 4.21.4
       caniuse-api: 3.0.0
       postcss: 8.4.6
     dev: true
@@ -11256,42 +22386,366 @@ packages:
       uniqs: 2.0.0
     dev: true
 
-  /postcss-unique-selectors/5.0.4_postcss@8.4.6:
-    resolution: {integrity: 
sha512-5ampwoSDJCxDPoANBIlMgoBcYUHnhaiuLYJR5pj1DLnYQvMRVyFuTA5C3Bvt+aHtiqWpJkD/lXT50Vo1D0ZsAQ==}
-    engines: {node: ^10 || ^12 || >=14.0}
+  /postcss-unique-selectors/5.0.4_postcss@8.4.6:
+    resolution: {integrity: 
sha512-5ampwoSDJCxDPoANBIlMgoBcYUHnhaiuLYJR5pj1DLnYQvMRVyFuTA5C3Bvt+aHtiqWpJkD/lXT50Vo1D0ZsAQ==}
+    engines: {node: ^10 || ^12 || >=14.0}
+    peerDependencies:
+      postcss: ^8.2.15
+    dependencies:
+      postcss: 8.4.6
+      postcss-selector-parser: 6.0.9
+    dev: true
+
+  /postcss-value-parser/3.3.1:
+    resolution: {integrity: 
sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==}
+    dev: true
+
+  /postcss-value-parser/4.2.0:
+    resolution: {integrity: 
sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
+    dev: true
+
+  /postcss/7.0.39:
+    resolution: {integrity: 
sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==}
+    engines: {node: '>=6.0.0'}
+    dependencies:
+      picocolors: 0.2.1
+      source-map: 0.6.1
+    dev: true
+
+  /postcss/8.4.6:
+    resolution: {integrity: 
sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA==}
+    engines: {node: ^10 || ^12 || >=14}
+    dependencies:
+      nanoid: 3.2.0
+      picocolors: 1.0.0
+      source-map-js: 1.0.2
+    dev: true
+
+  /preact-cli/3.0.5_ka7slmjrdyz4arupkjrkg4jzfm:
+    resolution: {integrity: 
sha512-Oc9HOjwX/3Zk1eXkmP7TMmtqbaROl7F0RWZ2Ni5Q/grmx3yBLJmarkUcOSKabkI/Usw2dU3RVju32Q3Pvy5qIw==}
+    engines: {node: '>=8'}
+    hasBin: true
+    peerDependencies:
+      preact: '*'
+      preact-render-to-string: '*'
+    dependencies:
+      '@babel/core': 7.17.2
+      '@babel/plugin-proposal-class-properties': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-proposal-decorators': 7.17.2_@babel+core@7.17.2
+      '@babel/plugin-proposal-object-rest-spread': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.17.2
+      '@babel/plugin-transform-object-assign': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-transform-react-jsx': 7.16.7_@babel+core@7.17.2
+      '@babel/preset-env': 7.16.11_@babel+core@7.17.2
+      '@babel/preset-typescript': 7.16.7_@babel+core@7.17.2
+      '@preact/async-loader': 3.0.1_preact@10.6.5
+      '@prefresh/webpack': 1.1.0_iaukxvobhnxulwhqqdnbfsnwxu
+      autoprefixer: 9.8.8
+      babel-esm-plugin: 0.9.0_webpack@4.46.0
+      babel-loader: 8.2.3_mc362qep5qjjhwk7q3m45kuizi
+      babel-plugin-macros: 2.8.0
+      babel-plugin-transform-react-remove-prop-types: 0.4.24
+      browserslist: 4.19.1
+      compression-webpack-plugin: 4.0.1_webpack@4.46.0
+      console-clear: 1.1.1
+      copy-webpack-plugin: 5.1.2_webpack@4.46.0
+      critters-webpack-plugin: 2.5.0_html-webpack-plugin@3.2.0
+      cross-spawn-promise: 0.10.2
+      css-loader: 3.6.0_webpack@4.46.0
+      ejs-loader: 0.5.0
+      envinfo: 7.8.1
+      esm: 3.2.25
+      fast-async: 6.3.8
+      file-loader: 6.2.0_webpack@4.46.0
+      fork-ts-checker-webpack-plugin: 4.1.6_3awoqomffoooecyduzzbrfpye4
+      get-port: 5.1.1
+      gittar: 0.1.1
+      glob: 7.2.3
+      html-webpack-exclude-assets-plugin: 0.0.7
+      html-webpack-plugin: 3.2.0_webpack@4.46.0
+      ip: 1.1.5
+      isomorphic-unfetch: 3.1.0
+      kleur: 4.1.4
+      loader-utils: 2.0.2
+      mini-css-extract-plugin: 0.9.0_webpack@4.46.0
+      minimatch: 3.1.2
+      native-url: 0.3.4
+      optimize-css-assets-webpack-plugin: 5.0.8_webpack@4.46.0
+      ora: 4.1.1
+      postcss-load-config: 2.1.2
+      postcss-loader: 3.0.0
+      preact: 10.6.5
+      preact-render-to-string: 5.1.19_preact@10.6.5
+      progress-bar-webpack-plugin: 2.1.0_webpack@4.46.0
+      promise-polyfill: 8.2.1
+      prompts: 2.4.2
+      raw-loader: 4.0.2_webpack@4.46.0
+      react-refresh: 0.8.3
+      require-relative: 0.8.7
+      resolve-from: 5.0.0
+      rimraf: 3.0.2
+      sade: 1.8.1
+      size-plugin: 2.0.2_webpack@4.46.0
+      source-map: 0.7.3
+      stack-trace: 0.0.10
+      style-loader: 1.3.0_webpack@4.46.0
+      terser-webpack-plugin: 3.1.0_webpack@4.46.0
+      typescript: 3.9.10
+      update-notifier: 4.1.3
+      url-loader: 4.1.1_lit45vopotvaqup7lrvlnvtxwy
+      validate-npm-package-name: 3.0.0
+      webpack: 4.46.0
+      webpack-bundle-analyzer: 3.9.0
+      webpack-dev-server: 3.11.3_webpack@4.46.0
+      webpack-fix-style-only-entries: 0.5.2
+      webpack-merge: 4.2.2
+      webpack-plugin-replace: 1.2.0
+      which: 2.0.2
+      workbox-cacheable-response: 5.1.4
+      workbox-core: 5.1.4
+      workbox-precaching: 5.1.4
+      workbox-routing: 5.1.4
+      workbox-strategies: 5.1.4
+      workbox-webpack-plugin: 5.1.4_webpack@4.46.0
+    transitivePeerDependencies:
+      - bluebird
+      - bufferutil
+      - debug
+      - encoding
+      - eslint
+      - supports-color
+      - utf-8-validate
+      - vue-template-compiler
+      - webpack-cli
+      - webpack-command
+    dev: true
+
+  /preact-cli/3.3.5_4lrkxlnsyltikzdya2zqvxqmyq:
+    resolution: {integrity: 
sha512-qtIk8WtheEoY192UoKFQD14cw5CoUnYs9A+gIL95H/WT4aw8Z4CvxsB6+eELMZnsruakkq7OQMd0xRrfyoZNgA==}
+    engines: {node: '>=12'}
+    hasBin: true
     peerDependencies:
-      postcss: ^8.2.15
+      less-loader: ^7.3.0
+      preact: '*'
+      preact-render-to-string: '*'
+      sass-loader: ^10.2.0
+      stylus-loader: ^4.3.3
+    peerDependenciesMeta:
+      less-loader:
+        optional: true
+      sass-loader:
+        optional: true
+      stylus-loader:
+        optional: true
     dependencies:
+      '@babel/core': 7.17.2
+      '@babel/plugin-proposal-class-properties': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-proposal-decorators': 7.17.2_@babel+core@7.17.2
+      '@babel/plugin-proposal-object-rest-spread': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.17.2
+      '@babel/plugin-transform-object-assign': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-transform-react-jsx': 7.16.7_@babel+core@7.17.2
+      '@babel/preset-env': 7.16.11_@babel+core@7.17.2
+      '@babel/preset-typescript': 7.16.7_@babel+core@7.17.2
+      '@preact/async-loader': 3.0.1_preact@10.6.1
+      '@prefresh/babel-plugin': 0.4.1
+      '@prefresh/webpack': 3.3.2_ev3yg7augojg2gbov5lykbl5qy
+      '@types/webpack': 4.41.32
+      autoprefixer: 10.4.2_postcss@8.4.6
+      babel-esm-plugin: 0.9.0_webpack@4.46.0
+      babel-loader: 8.2.3_mc362qep5qjjhwk7q3m45kuizi
+      babel-plugin-macros: 3.1.0
+      babel-plugin-transform-react-remove-prop-types: 0.4.24
+      browserslist: 4.19.1
+      compression-webpack-plugin: 6.1.1_webpack@4.46.0
+      console-clear: 1.1.1
+      copy-webpack-plugin: 6.4.1_webpack@4.46.0
+      critters-webpack-plugin: 2.5.0_html-webpack-plugin@3.2.0
+      cross-spawn-promise: 0.10.2
+      css-loader: 5.2.7_webpack@4.46.0
+      ejs-loader: 0.5.0
+      envinfo: 7.8.1
+      esm: 3.2.25
+      file-loader: 6.2.0_webpack@4.46.0
+      fork-ts-checker-webpack-plugin: 4.1.6_whfidqbq6inl26rhdbd2ot7yoa
+      get-port: 5.1.1
+      gittar: 0.1.1
+      glob: 7.2.0
+      html-webpack-exclude-assets-plugin: 0.0.7
+      html-webpack-plugin: 3.2.0_webpack@4.46.0
+      ip: 1.1.5
+      isomorphic-unfetch: 3.1.0
+      kleur: 4.1.4
+      loader-utils: 2.0.2
+      mini-css-extract-plugin: 1.6.2_webpack@4.46.0
+      minimatch: 3.0.5
+      native-url: 0.3.4
+      optimize-css-assets-webpack-plugin: 6.0.1_webpack@4.46.0
+      ora: 5.4.1
+      pnp-webpack-plugin: 1.7.0_typescript@4.2.4
       postcss: 8.4.6
-      postcss-selector-parser: 6.0.9
-    dev: true
-
-  /postcss-value-parser/3.3.1:
-    resolution: {integrity: 
sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==}
-    dev: true
-
-  /postcss-value-parser/4.2.0:
-    resolution: {integrity: 
sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
-    dev: true
-
-  /postcss/7.0.39:
-    resolution: {integrity: 
sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==}
-    engines: {node: '>=6.0.0'}
-    dependencies:
-      picocolors: 0.2.1
-      source-map: 0.6.1
+      postcss-load-config: 3.1.2
+      postcss-loader: 4.3.0_sa6x6oa3aqtj2o2n4wqcmgxr4e
+      preact: 10.6.1
+      preact-render-to-string: 5.1.19_preact@10.6.1
+      progress-bar-webpack-plugin: 2.1.0_webpack@4.46.0
+      promise-polyfill: 8.2.1
+      prompts: 2.4.2
+      raw-loader: 4.0.2_webpack@4.46.0
+      react-refresh: 0.10.0
+      rimraf: 3.0.2
+      sade: 1.8.1
+      sass-loader: 10.1.1_sass@1.32.13
+      size-plugin: 3.0.0_webpack@4.46.0
+      source-map: 0.7.3
+      stack-trace: 0.0.10
+      style-loader: 2.0.0_webpack@4.46.0
+      terser-webpack-plugin: 4.2.3_webpack@4.46.0
+      typescript: 4.2.4
+      update-notifier: 5.1.0
+      url-loader: 4.1.1_lit45vopotvaqup7lrvlnvtxwy
+      validate-npm-package-name: 3.0.0
+      webpack: 4.46.0
+      webpack-bundle-analyzer: 4.5.0
+      webpack-dev-server: 4.7.4_webpack@4.46.0
+      webpack-fix-style-only-entries: 0.6.1
+      webpack-merge: 5.8.0
+      webpack-plugin-replace: 1.2.0
+      which: 2.0.2
+      workbox-cacheable-response: 6.4.2
+      workbox-core: 6.4.2
+      workbox-precaching: 6.4.2
+      workbox-routing: 6.4.2
+      workbox-strategies: 6.4.2
+      workbox-webpack-plugin: 6.4.2_webpack@4.46.0
+    transitivePeerDependencies:
+      - '@types/babel__core'
+      - bluebird
+      - bufferutil
+      - debug
+      - encoding
+      - eslint
+      - supports-color
+      - ts-node
+      - utf-8-validate
+      - vue-template-compiler
+      - webpack-cli
+      - webpack-command
     dev: true
 
-  /postcss/8.4.6:
-    resolution: {integrity: 
sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA==}
-    engines: {node: ^10 || ^12 || >=14}
+  /preact-cli/3.3.5_mvcuzfcaha7xgb2vtvvy6e3v4a:
+    resolution: {integrity: 
sha512-qtIk8WtheEoY192UoKFQD14cw5CoUnYs9A+gIL95H/WT4aw8Z4CvxsB6+eELMZnsruakkq7OQMd0xRrfyoZNgA==}
+    engines: {node: '>=12'}
+    hasBin: true
+    peerDependencies:
+      less-loader: ^7.3.0
+      preact: '*'
+      preact-render-to-string: '*'
+      sass-loader: ^10.2.0
+      stylus-loader: ^4.3.3
+    peerDependenciesMeta:
+      less-loader:
+        optional: true
+      sass-loader:
+        optional: true
+      stylus-loader:
+        optional: true
     dependencies:
-      nanoid: 3.2.0
-      picocolors: 1.0.0
-      source-map-js: 1.0.2
+      '@babel/core': 7.17.2
+      '@babel/plugin-proposal-class-properties': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-proposal-decorators': 7.17.2_@babel+core@7.17.2
+      '@babel/plugin-proposal-object-rest-spread': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.17.2
+      '@babel/plugin-transform-object-assign': 7.16.7_@babel+core@7.17.2
+      '@babel/plugin-transform-react-jsx': 7.16.7_@babel+core@7.17.2
+      '@babel/preset-env': 7.16.11_@babel+core@7.17.2
+      '@babel/preset-typescript': 7.16.7_@babel+core@7.17.2
+      '@preact/async-loader': 3.0.1_preact@10.6.5
+      '@prefresh/babel-plugin': 0.4.1
+      '@prefresh/webpack': 3.3.2_dveknyjmyxkzkf4ybureeu5fae
+      '@types/webpack': 4.41.32
+      autoprefixer: 10.4.2_postcss@8.4.6
+      babel-esm-plugin: 0.9.0_webpack@4.46.0
+      babel-loader: 8.2.3_mc362qep5qjjhwk7q3m45kuizi
+      babel-plugin-macros: 3.1.0
+      babel-plugin-transform-react-remove-prop-types: 0.4.24
+      browserslist: 4.19.1
+      compression-webpack-plugin: 6.1.1_webpack@4.46.0
+      console-clear: 1.1.1
+      copy-webpack-plugin: 6.4.1_webpack@4.46.0
+      critters-webpack-plugin: 2.5.0_html-webpack-plugin@3.2.0
+      cross-spawn-promise: 0.10.2
+      css-loader: 5.2.7_webpack@4.46.0
+      ejs-loader: 0.5.0
+      envinfo: 7.8.1
+      esm: 3.2.25
+      file-loader: 6.2.0_webpack@4.46.0
+      fork-ts-checker-webpack-plugin: 4.1.6_e7hrjdrs22zc4syxbltzlwluhe
+      get-port: 5.1.1
+      gittar: 0.1.1
+      glob: 7.2.0
+      html-webpack-exclude-assets-plugin: 0.0.7
+      html-webpack-plugin: 3.2.0_webpack@4.46.0
+      ip: 1.1.5
+      isomorphic-unfetch: 3.1.0
+      kleur: 4.1.4
+      loader-utils: 2.0.2
+      mini-css-extract-plugin: 1.6.2_webpack@4.46.0
+      minimatch: 3.0.5
+      native-url: 0.3.4
+      optimize-css-assets-webpack-plugin: 6.0.1_webpack@4.46.0
+      ora: 5.4.1
+      pnp-webpack-plugin: 1.7.0_typescript@4.2.4
+      postcss: 8.4.6
+      postcss-load-config: 3.1.2
+      postcss-loader: 4.3.0_sa6x6oa3aqtj2o2n4wqcmgxr4e
+      preact: 10.6.5
+      preact-render-to-string: 5.1.19_preact@10.6.5
+      progress-bar-webpack-plugin: 2.1.0_webpack@4.46.0
+      promise-polyfill: 8.2.1
+      prompts: 2.4.2
+      raw-loader: 4.0.2_webpack@4.46.0
+      react-refresh: 0.10.0
+      rimraf: 3.0.2
+      sade: 1.8.1
+      size-plugin: 3.0.0_webpack@4.46.0
+      source-map: 0.7.3
+      stack-trace: 0.0.10
+      style-loader: 2.0.0_webpack@4.46.0
+      terser-webpack-plugin: 4.2.3_webpack@4.46.0
+      typescript: 4.2.4
+      update-notifier: 5.1.0
+      url-loader: 4.1.1_lit45vopotvaqup7lrvlnvtxwy
+      validate-npm-package-name: 3.0.0
+      webpack: 4.46.0
+      webpack-bundle-analyzer: 4.5.0
+      webpack-dev-server: 4.7.4_webpack@4.46.0
+      webpack-fix-style-only-entries: 0.6.1
+      webpack-merge: 5.8.0
+      webpack-plugin-replace: 1.2.0
+      which: 2.0.2
+      workbox-cacheable-response: 6.4.2
+      workbox-core: 6.4.2
+      workbox-precaching: 6.4.2
+      workbox-routing: 6.4.2
+      workbox-strategies: 6.4.2
+      workbox-webpack-plugin: 6.4.2_webpack@4.46.0
+    transitivePeerDependencies:
+      - '@types/babel__core'
+      - bluebird
+      - bufferutil
+      - debug
+      - encoding
+      - eslint
+      - supports-color
+      - ts-node
+      - utf-8-validate
+      - vue-template-compiler
+      - webpack-cli
+      - webpack-command
     dev: true
 
-  /preact-cli/3.3.5_mvcuzfcaha7xgb2vtvvy6e3v4a:
+  /preact-cli/3.3.5_p6ocopta3zc4zccdbpyllaobd4:
     resolution: {integrity: 
sha512-qtIk8WtheEoY192UoKFQD14cw5CoUnYs9A+gIL95H/WT4aw8Z4CvxsB6+eELMZnsruakkq7OQMd0xRrfyoZNgA==}
     engines: {node: '>=12'}
     hasBin: true
@@ -11338,7 +22792,7 @@ packages:
       envinfo: 7.8.1
       esm: 3.2.25
       file-loader: 6.2.0_webpack@4.46.0
-      fork-ts-checker-webpack-plugin: 4.1.6_e7hrjdrs22zc4syxbltzlwluhe
+      fork-ts-checker-webpack-plugin: 4.1.6_whfidqbq6inl26rhdbd2ot7yoa
       get-port: 5.1.1
       gittar: 0.1.1
       glob: 7.2.0
@@ -11366,6 +22820,7 @@ packages:
       react-refresh: 0.10.0
       rimraf: 3.0.2
       sade: 1.8.1
+      sass-loader: 10.1.1_sass@1.32.13
       size-plugin: 3.0.0_webpack@4.46.0
       source-map: 0.7.3
       stack-trace: 0.0.10
@@ -11403,6 +22858,31 @@ packages:
       - webpack-command
     dev: true
 
+  /preact-render-to-json/3.6.6_preact@10.6.1:
+    resolution: {integrity: 
sha512-w+guVnrKJMtSdAYKD3INih1O+XNEgJmj58r49KjjnwE1tLqzNXq1NaZXDg1DGhQ0fj67DYKdR9BqhogFI0lvsg==}
+    peerDependencies:
+      preact: '*'
+    dependencies:
+      preact: 10.6.1
+    dev: true
+
+  /preact-render-to-json/3.6.6_preact@10.6.5:
+    resolution: {integrity: 
sha512-w+guVnrKJMtSdAYKD3INih1O+XNEgJmj58r49KjjnwE1tLqzNXq1NaZXDg1DGhQ0fj67DYKdR9BqhogFI0lvsg==}
+    peerDependencies:
+      preact: '*'
+    dependencies:
+      preact: 10.6.5
+    dev: true
+
+  /preact-render-to-string/5.1.19_preact@10.6.1:
+    resolution: {integrity: 
sha512-bj8sn/oytIKO6RtOGSS/1+5CrQyRSC99eLUnEVbqUa6MzJX5dYh7wu9bmT0d6lm/Vea21k9KhCQwvr2sYN3rrQ==}
+    peerDependencies:
+      preact: '>=10'
+    dependencies:
+      preact: 10.6.1
+      pretty-format: 3.8.0
+    dev: true
+
   /preact-render-to-string/5.1.19_preact@10.6.5:
     resolution: {integrity: 
sha512-bj8sn/oytIKO6RtOGSS/1+5CrQyRSC99eLUnEVbqUa6MzJX5dYh7wu9bmT0d6lm/Vea21k9KhCQwvr2sYN3rrQ==}
     peerDependencies:
@@ -11411,6 +22891,14 @@ packages:
       preact: 10.6.5
       pretty-format: 3.8.0
 
+  /preact-router/3.2.1_preact@10.6.1:
+    resolution: {integrity: 
sha512-KEN2VN1DxUlTwzW5IFkF13YIA2OdQ2OvgJTkQREF+AA2NrHRLaGbB68EjS4IeZOa1shvQ1FvEm3bSLta4sXBhg==}
+    peerDependencies:
+      preact: '>=10'
+    dependencies:
+      preact: 10.6.1
+    dev: false
+
   /preact-router/3.2.1_preact@10.6.5:
     resolution: {integrity: 
sha512-KEN2VN1DxUlTwzW5IFkF13YIA2OdQ2OvgJTkQREF+AA2NrHRLaGbB68EjS4IeZOa1shvQ1FvEm3bSLta4sXBhg==}
     peerDependencies:
@@ -11419,11 +22907,14 @@ packages:
       preact: 10.6.5
     dev: false
 
+  /preact/10.6.1:
+    resolution: {integrity: 
sha512-ydCg+ISIq70vqiThvNWStZWLRjR9U2awP/JAmGdWUKm9+Tyuy+MqVdAIyEByeIspAVtD4GWC/SJtxO8XD4knVA==}
+
   /preact/10.6.5:
     resolution: {integrity: 
sha512-i+LXM6JiVjQXSt2jG2vZZFapGpCuk1fl8o6ii3G84MA3xgj686FKjs4JFDkmUVhtxyq21+4ay74zqPykz9hU6w==}
 
   /prelude-ls/1.1.2:
-    resolution: {integrity: sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=}
+    resolution: {integrity: 
sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==}
     engines: {node: '>= 0.8.0'}
     dev: true
 
@@ -11432,11 +22923,22 @@ packages:
     engines: {node: '>= 0.8.0'}
     dev: true
 
+  /prepend-http/1.0.4:
+    resolution: {integrity: 
sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
   /prepend-http/2.0.0:
-    resolution: {integrity: sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=}
+    resolution: {integrity: 
sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==}
     engines: {node: '>=4'}
     dev: true
 
+  /prettier/2.2.1:
+    resolution: {integrity: 
sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==}
+    engines: {node: '>=10.13.0'}
+    hasBin: true
+    dev: true
+
   /prettier/2.5.1:
     resolution: {integrity: 
sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==}
     engines: {node: '>=10.13.0'}
@@ -11444,7 +22946,7 @@ packages:
     dev: true
 
   /pretty-bytes/4.0.2:
-    resolution: {integrity: sha1-sr+C5zUNZcbDOqlaqlpPYyf2HNk=}
+    resolution: {integrity: 
sha512-yJAF+AjbHKlxQ8eezMd/34Mnj/YTQ3i6kLzvVsH4l/BfIFtp444n0wVbnsn66JimZ9uBofv815aRp1zCppxlWw==}
     engines: {node: '>=4'}
     dev: true
 
@@ -11470,9 +22972,33 @@ packages:
       react-is: 17.0.2
     dev: true
 
+  /pretty-format/27.5.1:
+    resolution: {integrity: 
sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==}
+    engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
+    dependencies:
+      ansi-regex: 5.0.1
+      ansi-styles: 5.2.0
+      react-is: 17.0.2
+    dev: true
+
+  /pretty-format/28.1.3:
+    resolution: {integrity: 
sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==}
+    engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
+    dependencies:
+      '@jest/schemas': 28.1.3
+      ansi-regex: 5.0.1
+      ansi-styles: 5.2.0
+      react-is: 18.2.0
+    dev: true
+
   /pretty-format/3.8.0:
     resolution: {integrity: 
sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==}
 
+  /pretty-hrtime/1.0.3:
+    resolution: {integrity: 
sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==}
+    engines: {node: '>= 0.8'}
+    dev: true
+
   /pretty-ms/7.0.1:
     resolution: {integrity: 
sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==}
     engines: {node: '>=10'}
@@ -11480,6 +23006,16 @@ packages:
       parse-ms: 2.1.0
     dev: true
 
+  /prismjs/1.27.0:
+    resolution: {integrity: 
sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==}
+    engines: {node: '>=6'}
+    dev: true
+
+  /prismjs/1.29.0:
+    resolution: {integrity: 
sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==}
+    engines: {node: '>=6'}
+    dev: true
+
   /process-nextick-args/2.0.1:
     resolution: {integrity: 
sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
     dev: true
@@ -11492,7 +23028,7 @@ packages:
     dev: true
 
   /process/0.11.10:
-    resolution: {integrity: sha1-czIwDoQBYb2j5podHZGn1LwW8YI=}
+    resolution: {integrity: 
sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==}
     engines: {node: '>= 0.6.0'}
     dev: true
 
@@ -11511,8 +23047,17 @@ packages:
     engines: {node: '>=0.4.0'}
     dev: true
 
+  /promise-inflight/1.0.1:
+    resolution: {integrity: 
sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==}
+    peerDependencies:
+      bluebird: '*'
+    peerDependenciesMeta:
+      bluebird:
+        optional: true
+    dev: true
+
   /promise-inflight/1.0.1_bluebird@3.7.2:
-    resolution: {integrity: sha1-mEcocL8igTL8vdhoEputEsPAKeM=}
+    resolution: {integrity: 
sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==}
     peerDependencies:
       bluebird: '*'
     peerDependenciesMeta:
@@ -11526,6 +23071,35 @@ packages:
     resolution: {integrity: 
sha512-3p9zj0cEHbp7NVUxEYUWjQlffXqnXaZIMPkAO7HhFh8u5636xLRDHOUo2vpWSK0T2mqm6fKLXYn1KP6PAZ2gKg==}
     dev: true
 
+  /promise.allsettled/1.0.5:
+    resolution: {integrity: 
sha512-tVDqeZPoBC0SlzJHzWGZ2NKAguVq2oiYj7gbggbiTvH2itHohijTp7njOUA0aQ/nl+0lr/r6egmhoYu63UZ/pQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      array.prototype.map: 1.0.4
+      call-bind: 1.0.2
+      define-properties: 1.1.4
+      es-abstract: 1.20.4
+      get-intrinsic: 1.1.3
+      iterate-value: 1.0.2
+    dev: true
+
+  /promise.prototype.finally/3.1.3:
+    resolution: {integrity: 
sha512-EXRF3fC9/0gz4qkt/f5EP5iW4kj9oFpBICNpCNOb/52+8nlHIX07FPLbi/q4qYBQ1xZqivMzTpNQSnArVASolQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.2
+      define-properties: 1.1.4
+      es-abstract: 1.20.4
+    dev: true
+
+  /prompts/2.4.0:
+    resolution: {integrity: 
sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ==}
+    engines: {node: '>= 6'}
+    dependencies:
+      kleur: 3.0.3
+      sisteransi: 1.0.5
+    dev: true
+
   /prompts/2.4.2:
     resolution: {integrity: 
sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==}
     engines: {node: '>= 6'}
@@ -11542,6 +23116,16 @@ packages:
       react-is: 16.13.1
     dev: true
 
+  /property-expr/2.0.5:
+    resolution: {integrity: 
sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA==}
+    dev: false
+
+  /property-information/5.6.0:
+    resolution: {integrity: 
sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==}
+    dependencies:
+      xtend: 4.0.2
+    dev: true
+
   /proxy-addr/2.0.7:
     resolution: {integrity: 
sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
     engines: {node: '>= 0.10'}
@@ -11551,11 +23135,11 @@ packages:
     dev: true
 
   /prr/1.0.1:
-    resolution: {integrity: sha1-0/wRS6BplaRexok/SEzrHXj19HY=}
+    resolution: {integrity: 
sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==}
     dev: true
 
   /pseudomap/1.0.2:
-    resolution: {integrity: sha1-8FKijacOYYkX7wqKw0wa5aaChrM=}
+    resolution: {integrity: 
sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==}
     dev: true
 
   /psl/1.8.0:
@@ -11596,17 +23180,16 @@ packages:
     dev: true
 
   /punycode/1.3.2:
-    resolution: {integrity: sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=}
+    resolution: {integrity: 
sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==}
     dev: true
 
   /punycode/1.4.1:
-    resolution: {integrity: sha1-wNWmOycYgArY4esPpSachN1BhF4=}
+    resolution: {integrity: 
sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==}
     dev: true
 
   /punycode/2.1.1:
     resolution: {integrity: 
sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==}
     engines: {node: '>=6'}
-    dev: true
 
   /pupa/2.1.1:
     resolution: {integrity: 
sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==}
@@ -11616,7 +23199,7 @@ packages:
     dev: true
 
   /q/1.5.1:
-    resolution: {integrity: sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=}
+    resolution: {integrity: 
sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==}
     engines: {node: '>=0.6.0', teleport: '>=0.2.0'}
     dev: true
 
@@ -11630,6 +23213,13 @@ packages:
     resolution: {integrity: 
sha512-HM7yY8O2ilqhmULxGMpcHSF1EhJJ9yBj8gvDEuZ6M+KGJ0YY2hKpnXvRD+hZPLrDVck3ExIGhmPtSdcjC+guuw==}
     dev: false
 
+  /qs/6.11.0:
+    resolution: {integrity: 
sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==}
+    engines: {node: '>=0.6'}
+    dependencies:
+      side-channel: 1.0.4
+    dev: true
+
   /qs/6.5.3:
     resolution: {integrity: 
sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==}
     engines: {node: '>=0.6'}
@@ -11640,13 +23230,21 @@ packages:
     engines: {node: '>=0.6'}
     dev: true
 
+  /query-string/4.3.4:
+    resolution: {integrity: 
sha512-O2XLNDBIg1DnTOa+2XrIwSiXEV8h2KImXUnjhhn2+UsvZ+Es2uyd5CCRTNQlDGbzUQOW3aYCBx9rVA6dzsiY7Q==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      object-assign: 4.1.1
+      strict-uri-encode: 1.1.0
+    dev: true
+
   /querystring-es3/0.2.1:
-    resolution: {integrity: sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=}
+    resolution: {integrity: 
sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==}
     engines: {node: '>=0.4.x'}
     dev: true
 
   /querystring/0.2.0:
-    resolution: {integrity: sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=}
+    resolution: {integrity: 
sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==}
     engines: {node: '>=0.4.x'}
     deprecated: The querystring API is considered Legacy. new code should use 
the URLSearchParams API instead.
     dev: true
@@ -11657,10 +23255,36 @@ packages:
     deprecated: The querystring API is considered Legacy. new code should use 
the URLSearchParams API instead.
     dev: true
 
+  /querystringify/2.2.0:
+    resolution: {integrity: 
sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==}
+    dev: true
+
   /queue-microtask/1.2.3:
     resolution: {integrity: 
sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
     dev: true
 
+  /raf/3.4.1:
+    resolution: {integrity: 
sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==}
+    dependencies:
+      performance-now: 2.1.0
+    dev: true
+
+  /railroad-diagrams/1.0.0:
+    resolution: {integrity: 
sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A==}
+    dev: true
+
+  /ramda/0.28.0:
+    resolution: {integrity: 
sha512-9QnLuG/kPVgWvMQ4aODhsBUFKOUmnbUnsSXACv+NCQZcHbeb+v8Lodp8OVxtRULN1/xOyYLLaL6npE6dMq5QTA==}
+    dev: true
+
+  /randexp/0.4.6:
+    resolution: {integrity: 
sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==}
+    engines: {node: '>=0.12'}
+    dependencies:
+      discontinuous-range: 1.0.0
+      ret: 0.1.15
+    dev: true
+
   /randombytes/2.1.0:
     resolution: {integrity: 
sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
     dependencies:
@@ -11710,6 +23334,156 @@ packages:
       strip-json-comments: 2.0.1
     dev: true
 
+  /react-colorful/5.6.1:
+    resolution: {integrity: 
sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==}
+    peerDependencies:
+      react: '>=16.8.0'
+      react-dom: '>=16.8.0'
+    dev: true
+
+  /react-colorful/5.6.1_wcqkhtmu7mswc6yz4uyexck3ty:
+    resolution: {integrity: 
sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==}
+    peerDependencies:
+      react: '>=16.8.0'
+      react-dom: '>=16.8.0'
+    dependencies:
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+    dev: true
+
+  /react-dev-utils/11.0.4_ef2lra3u3fsnrdrpybbvbgzate:
+    resolution: {integrity: 
sha512-dx0LvIGHcOPtKbeiSUM4jqpBl3TcY7CDjZdfOIcKeznE7BWr9dg0iPG90G5yfVQ+p/rGNMXdbfStvzQZEVEi4A==}
+    engines: {node: '>=10'}
+    peerDependencies:
+      typescript: '>=2.7'
+      webpack: '>=4'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+    dependencies:
+      '@babel/code-frame': 7.10.4
+      address: 1.1.2
+      browserslist: 4.14.2
+      chalk: 2.4.2
+      cross-spawn: 7.0.3
+      detect-port-alt: 1.1.6
+      escape-string-regexp: 2.0.0
+      filesize: 6.1.0
+      find-up: 4.1.0
+      fork-ts-checker-webpack-plugin: 4.1.6_ef2lra3u3fsnrdrpybbvbgzate
+      global-modules: 2.0.0
+      globby: 11.0.1
+      gzip-size: 5.1.1
+      immer: 8.0.1
+      is-root: 2.1.0
+      loader-utils: 2.0.0
+      open: 7.4.2
+      pkg-up: 3.1.0
+      prompts: 2.4.0
+      react-error-overlay: 6.0.11
+      recursive-readdir: 2.2.2
+      shell-quote: 1.7.2
+      strip-ansi: 6.0.0
+      text-table: 0.2.0
+      typescript: 4.8.4
+      webpack: 4.46.0
+    transitivePeerDependencies:
+      - eslint
+      - supports-color
+      - vue-template-compiler
+    dev: true
+
+  /react-dom/16.14.0_react@16.14.0:
+    resolution: {integrity: 
sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==}
+    peerDependencies:
+      react: ^16.14.0
+    dependencies:
+      loose-envify: 1.4.0
+      object-assign: 4.1.1
+      prop-types: 15.8.1
+      react: 16.14.0
+      scheduler: 0.19.1
+    dev: true
+
+  /react-draggable/4.4.5:
+    resolution: {integrity: 
sha512-OMHzJdyJbYTZo4uQE393fHcqqPYsEtkjfMgvCHr6rejT+Ezn4OZbNyGH50vv+SunC1RMvwOTSWkEODQLzw1M9g==}
+    peerDependencies:
+      react: '>= 16.3.0'
+      react-dom: '>= 16.3.0'
+    dependencies:
+      clsx: 1.2.1
+      prop-types: 15.8.1
+    dev: true
+
+  /react-draggable/4.4.5_wcqkhtmu7mswc6yz4uyexck3ty:
+    resolution: {integrity: 
sha512-OMHzJdyJbYTZo4uQE393fHcqqPYsEtkjfMgvCHr6rejT+Ezn4OZbNyGH50vv+SunC1RMvwOTSWkEODQLzw1M9g==}
+    peerDependencies:
+      react: '>= 16.3.0'
+      react-dom: '>= 16.3.0'
+    dependencies:
+      clsx: 1.2.1
+      prop-types: 15.8.1
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+    dev: true
+
+  /react-element-to-jsx-string/14.3.4:
+    resolution: {integrity: 
sha512-t4ZwvV6vwNxzujDQ+37bspnLwA4JlgUPWhLjBJWsNIDceAf6ZKUTCjdm08cN6WeZ5pTMKiCJkmAYnpmR4Bm+dg==}
+    peerDependencies:
+      react: ^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1
+      react-dom: ^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1
+    dependencies:
+      '@base2/pretty-print-object': 1.0.1
+      is-plain-object: 5.0.0
+      react-is: 17.0.2
+    dev: true
+
+  /react-error-overlay/6.0.11:
+    resolution: {integrity: 
sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==}
+    dev: true
+
+  /react-fast-compare/3.2.0:
+    resolution: {integrity: 
sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==}
+    dev: true
+
+  /react-helmet-async/1.3.0:
+    resolution: {integrity: 
sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==}
+    peerDependencies:
+      react: ^16.6.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.6.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      '@babel/runtime': 7.17.8
+      invariant: 2.2.4
+      prop-types: 15.8.1
+      react-fast-compare: 3.2.0
+      shallowequal: 1.1.0
+    dev: true
+
+  /react-helmet-async/1.3.0_wcqkhtmu7mswc6yz4uyexck3ty:
+    resolution: {integrity: 
sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==}
+    peerDependencies:
+      react: ^16.6.0 || ^17.0.0 || ^18.0.0
+      react-dom: ^16.6.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      '@babel/runtime': 7.17.8
+      invariant: 2.2.4
+      prop-types: 15.8.1
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      react-fast-compare: 3.2.0
+      shallowequal: 1.1.0
+    dev: true
+
+  /react-inspector/5.1.1:
+    resolution: {integrity: 
sha512-GURDaYzoLbW8pMGXwYPDBIv6nqei4kK7LPRZ9q9HCZF54wqXz/dnylBp/kfE9XmekBhHvLDdcYeyIwSrvtOiWg==}
+    peerDependencies:
+      react: ^16.8.4 || ^17.0.0
+    dependencies:
+      '@babel/runtime': 7.17.8
+      is-dom: 1.1.0
+      prop-types: 15.8.1
+    dev: true
+
   /react-is/16.13.1:
     resolution: {integrity: 
sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
     dev: true
@@ -11718,11 +23492,182 @@ packages:
     resolution: {integrity: 
sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
     dev: true
 
+  /react-is/18.2.0:
+    resolution: {integrity: 
sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==}
+    dev: true
+
+  /react-lifecycles-compat/3.0.4:
+    resolution: {integrity: 
sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==}
+    dev: true
+
+  /react-popper-tooltip/3.1.1:
+    resolution: {integrity: 
sha512-EnERAnnKRptQBJyaee5GJScWNUKQPDD2ywvzZyUjst/wj5U64C8/CnSYLNEmP2hG0IJ3ZhtDxE8oDN+KOyavXQ==}
+    peerDependencies:
+      react: ^16.6.0 || ^17.0.0
+      react-dom: ^16.6.0 || ^17.0.0
+    dependencies:
+      '@babel/runtime': 7.17.8
+      '@popperjs/core': 2.11.6
+      react-popper: 2.3.0_@popperjs+core@2.11.6
+    dev: true
+
+  /react-popper-tooltip/3.1.1_wcqkhtmu7mswc6yz4uyexck3ty:
+    resolution: {integrity: 
sha512-EnERAnnKRptQBJyaee5GJScWNUKQPDD2ywvzZyUjst/wj5U64C8/CnSYLNEmP2hG0IJ3ZhtDxE8oDN+KOyavXQ==}
+    peerDependencies:
+      react: ^16.6.0 || ^17.0.0
+      react-dom: ^16.6.0 || ^17.0.0
+    dependencies:
+      '@babel/runtime': 7.17.8
+      '@popperjs/core': 2.11.6
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      react-popper: 2.3.0_ahsyp7paedy7ttpixxrzktxjdi
+    dev: true
+
+  /react-popper/2.3.0_@popperjs+core@2.11.6:
+    resolution: {integrity: 
sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==}
+    peerDependencies:
+      '@popperjs/core': ^2.0.0
+      react: ^16.8.0 || ^17 || ^18
+      react-dom: ^16.8.0 || ^17 || ^18
+    dependencies:
+      '@popperjs/core': 2.11.6
+      react-fast-compare: 3.2.0
+      warning: 4.0.3
+    dev: true
+
+  /react-popper/2.3.0_ahsyp7paedy7ttpixxrzktxjdi:
+    resolution: {integrity: 
sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==}
+    peerDependencies:
+      '@popperjs/core': ^2.0.0
+      react: ^16.8.0 || ^17 || ^18
+      react-dom: ^16.8.0 || ^17 || ^18
+    dependencies:
+      '@popperjs/core': 2.11.6
+      react: 16.14.0
+      react-dom: 16.14.0_react@16.14.0
+      react-fast-compare: 3.2.0
+      warning: 4.0.3
+    dev: true
+
   /react-refresh/0.10.0:
     resolution: {integrity: 
sha512-PgidR3wST3dDYKr6b4pJoqQFpPGNKDSCDx4cZoshjXipw3LzO7mG1My2pwEzz2JVkF+inx3xRpDeQLFQGH/hsQ==}
     engines: {node: '>=0.10.0'}
     dev: true
 
+  /react-refresh/0.8.3:
+    resolution: {integrity: 
sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /react-sizeme/3.0.2:
+    resolution: {integrity: 
sha512-xOIAOqqSSmKlKFJLO3inBQBdymzDuXx4iuwkNcJmC96jeiOg5ojByvL+g3MW9LPEsojLbC6pf68zOfobK8IPlw==}
+    dependencies:
+      element-resize-detector: 1.2.4
+      invariant: 2.2.4
+      shallowequal: 1.1.0
+      throttle-debounce: 3.0.1
+    dev: true
+
+  /react-syntax-highlighter/13.5.3:
+    resolution: {integrity: 
sha512-crPaF+QGPeHNIblxxCdf2Lg936NAHKhNhuMzRL3F9ct6aYXL3NcZtCL0Rms9+qVo6Y1EQLdXGypBNSbPL/r+qg==}
+    peerDependencies:
+      react: '>= 0.14.0'
+    dependencies:
+      '@babel/runtime': 7.17.8
+      highlight.js: 10.7.3
+      lowlight: 1.20.0
+      prismjs: 1.29.0
+      refractor: 3.6.0
+    dev: true
+
+  /react-syntax-highlighter/13.5.3_react@16.14.0:
+    resolution: {integrity: 
sha512-crPaF+QGPeHNIblxxCdf2Lg936NAHKhNhuMzRL3F9ct6aYXL3NcZtCL0Rms9+qVo6Y1EQLdXGypBNSbPL/r+qg==}
+    peerDependencies:
+      react: '>= 0.14.0'
+    dependencies:
+      '@babel/runtime': 7.17.8
+      highlight.js: 10.7.3
+      lowlight: 1.20.0
+      prismjs: 1.29.0
+      react: 16.14.0
+      refractor: 3.6.0
+    dev: true
+
+  /react-textarea-autosize/8.3.4:
+    resolution: {integrity: 
sha512-CdtmP8Dc19xL8/R6sWvtknD/eCXkQr30dtvC4VmGInhRsfF8X/ihXCq6+9l9qbxmKRiq407/7z5fxE7cVWQNgQ==}
+    engines: {node: '>=10'}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      '@babel/runtime': 7.17.8
+      use-composed-ref: 1.3.0
+      use-latest: 1.2.1
+    transitivePeerDependencies:
+      - '@types/react'
+    dev: true
+
+  /react-textarea-autosize/8.3.4_react@16.14.0:
+    resolution: {integrity: 
sha512-CdtmP8Dc19xL8/R6sWvtknD/eCXkQr30dtvC4VmGInhRsfF8X/ihXCq6+9l9qbxmKRiq407/7z5fxE7cVWQNgQ==}
+    engines: {node: '>=10'}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      '@babel/runtime': 7.17.8
+      react: 16.14.0
+      use-composed-ref: 1.3.0_react@16.14.0
+      use-latest: 1.2.1_react@16.14.0
+    transitivePeerDependencies:
+      - '@types/react'
+    dev: true
+
+  /react/16.14.0:
+    resolution: {integrity: 
sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      loose-envify: 1.4.0
+      object-assign: 4.1.1
+      prop-types: 15.8.1
+    dev: true
+
+  /read-pkg-up/1.0.1:
+    resolution: {integrity: 
sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      find-up: 1.1.2
+      read-pkg: 1.1.0
+    dev: true
+    optional: true
+
+  /read-pkg-up/7.0.1:
+    resolution: {integrity: 
sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==}
+    engines: {node: '>=8'}
+    dependencies:
+      find-up: 4.1.0
+      read-pkg: 5.2.0
+      type-fest: 0.8.1
+    dev: true
+
+  /read-pkg/1.1.0:
+    resolution: {integrity: 
sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      load-json-file: 1.1.0
+      normalize-package-data: 2.5.0
+      path-type: 1.1.0
+    dev: true
+    optional: true
+
+  /read-pkg/5.2.0:
+    resolution: {integrity: 
sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==}
+    engines: {node: '>=8'}
+    dependencies:
+      '@types/normalize-package-data': 2.4.1
+      normalize-package-data: 2.5.0
+      parse-json: 5.2.0
+      type-fest: 0.6.0
+    dev: true
+
   /readable-stream/2.3.7:
     resolution: {integrity: 
sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==}
     dependencies:
@@ -11744,17 +23689,28 @@ packages:
       util-deprecate: 1.0.2
     dev: true
 
-  /readdirp/2.2.1:
+  /readdirp/2.2.1:
+    resolution: {integrity: 
sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==}
+    engines: {node: '>=0.10'}
+    dependencies:
+      graceful-fs: 4.2.10
+      micromatch: 3.1.10
+      readable-stream: 2.3.7
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+    optional: true
+
+  /readdirp/2.2.1_supports-color@6.1.0:
     resolution: {integrity: 
sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==}
     engines: {node: '>=0.10'}
     dependencies:
       graceful-fs: 4.2.10
-      micromatch: 3.1.10
+      micromatch: 3.1.10_supports-color@6.1.0
       readable-stream: 2.3.7
     transitivePeerDependencies:
       - supports-color
     dev: true
-    optional: true
 
   /readdirp/3.6.0:
     resolution: {integrity: 
sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
@@ -11763,6 +23719,45 @@ packages:
       picomatch: 2.3.1
     dev: true
 
+  /rechoir/0.6.2:
+    resolution: {integrity: 
sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==}
+    engines: {node: '>= 0.10'}
+    dependencies:
+      resolve: 1.22.1
+    dev: true
+
+  /recursive-readdir/2.2.2:
+    resolution: {integrity: 
sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      minimatch: 3.0.4
+    dev: true
+
+  /redent/1.0.0:
+    resolution: {integrity: 
sha512-qtW5hKzGQZqKoh6JNSD+4lfitfPKGz42e6QwiRmPM5mmKtR0N41AbJRYu0xJi7nhOJ4WDgRkKvAk6tw4WIwR4g==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      indent-string: 2.1.0
+      strip-indent: 1.0.1
+    dev: true
+    optional: true
+
+  /redent/3.0.0:
+    resolution: {integrity: 
sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==}
+    engines: {node: '>=8'}
+    dependencies:
+      indent-string: 4.0.0
+      strip-indent: 3.0.0
+    dev: true
+
+  /refractor/3.6.0:
+    resolution: {integrity: 
sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==}
+    dependencies:
+      hastscript: 6.0.0
+      parse-entities: 2.0.0
+      prismjs: 1.27.0
+    dev: true
+
   /regenerate-unicode-properties/10.0.1:
     resolution: {integrity: 
sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw==}
     engines: {node: '>=4'}
@@ -11784,7 +23779,7 @@ packages:
   /regenerator-transform/0.14.5:
     resolution: {integrity: 
sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==}
     dependencies:
-      '@babel/runtime': 7.17.2
+      '@babel/runtime': 7.17.8
     dev: true
 
   /regex-not/1.0.2:
@@ -11800,7 +23795,16 @@ packages:
     engines: {node: '>= 0.4'}
     dependencies:
       call-bind: 1.0.2
-      define-properties: 1.1.3
+      define-properties: 1.1.4
+    dev: true
+
+  /regexp.prototype.flags/1.4.3:
+    resolution: {integrity: 
sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.2
+      define-properties: 1.1.4
+      functions-have-names: 1.2.3
     dev: true
 
   /regexpp/3.2.0:
@@ -11846,7 +23850,7 @@ packages:
     dev: true
 
   /relateurl/0.2.7:
-    resolution: {integrity: sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=}
+    resolution: {integrity: 
sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==}
     engines: {node: '>= 0.10'}
     dev: true
 
@@ -11857,10 +23861,73 @@ packages:
       es6-error: 4.1.1
     dev: true
 
+  /remark-external-links/8.0.0:
+    resolution: {integrity: 
sha512-5vPSX0kHoSsqtdftSHhIYofVINC8qmp0nctkeU9YoJwV3YfiBRiI6cbFRJ0oI/1F9xS+bopXG0m2KS8VFscuKA==}
+    dependencies:
+      extend: 3.0.2
+      is-absolute-url: 3.0.3
+      mdast-util-definitions: 4.0.0
+      space-separated-tokens: 1.1.5
+      unist-util-visit: 2.0.3
+    dev: true
+
+  /remark-footnotes/2.0.0:
+    resolution: {integrity: 
sha512-3Clt8ZMH75Ayjp9q4CorNeyjwIxHFcTkaektplKGl2A1jNGEUey8cKL0ZC5vJwfcD5GFGsNLImLG/NGzWIzoMQ==}
+    dev: true
+
+  /remark-mdx/1.6.22:
+    resolution: {integrity: 
sha512-phMHBJgeV76uyFkH4rvzCftLfKCr2RZuF+/gmVcaKrpsihyzmhXjA0BEMDaPTXG5y8qZOKPVo83NAOX01LPnOQ==}
+    dependencies:
+      '@babel/core': 7.12.9
+      '@babel/helper-plugin-utils': 7.10.4
+      '@babel/plugin-proposal-object-rest-spread': 7.12.1_@babel+core@7.12.9
+      '@babel/plugin-syntax-jsx': 7.12.1_@babel+core@7.12.9
+      '@mdx-js/util': 1.6.22
+      is-alphabetical: 1.0.4
+      remark-parse: 8.0.3
+      unified: 9.2.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /remark-parse/8.0.3:
+    resolution: {integrity: 
sha512-E1K9+QLGgggHxCQtLt++uXltxEprmWzNfg+MxpfHsZlrddKzZ/hZyWHDbK3/Ap8HJQqYJRXP+jHczdL6q6i85Q==}
+    dependencies:
+      ccount: 1.1.0
+      collapse-white-space: 1.0.6
+      is-alphabetical: 1.0.4
+      is-decimal: 1.0.4
+      is-whitespace-character: 1.0.4
+      is-word-character: 1.0.4
+      markdown-escapes: 1.0.4
+      parse-entities: 2.0.0
+      repeat-string: 1.6.1
+      state-toggle: 1.0.3
+      trim: 0.0.1
+      trim-trailing-lines: 1.1.4
+      unherit: 1.1.3
+      unist-util-remove-position: 2.0.1
+      vfile-location: 3.2.0
+      xtend: 4.0.2
+    dev: true
+
+  /remark-slug/6.1.0:
+    resolution: {integrity: 
sha512-oGCxDF9deA8phWvxFuyr3oSJsdyUAxMFbA0mZ7Y1Sas+emILtO+e5WutF9564gDsEN4IXaQXm5pFo6MLH+YmwQ==}
+    dependencies:
+      github-slugger: 1.4.0
+      mdast-util-to-string: 1.1.0
+      unist-util-visit: 2.0.3
+    dev: true
+
+  /remark-squeeze-paragraphs/4.0.0:
+    resolution: {integrity: 
sha512-8qRqmL9F4nuLPIgl92XUuxI3pFxize+F1H0e/W3llTk0UsjJaj01+RrirkMw7P21RKe4X6goQhYRSvNWX+70Rw==}
+    dependencies:
+      mdast-squeeze-paragraphs: 4.0.0
+    dev: true
+
   /remove-trailing-separator/1.1.0:
-    resolution: {integrity: sha1-wkvOKig62tW8P1jg1IJJuSN52O8=}
+    resolution: {integrity: 
sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==}
     dev: true
-    optional: true
 
   /renderkid/2.0.7:
     resolution: {integrity: 
sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ==}
@@ -11878,10 +23945,18 @@ packages:
     dev: true
 
   /repeat-string/1.6.1:
-    resolution: {integrity: sha1-jcrkcOHIirwtYA//Sndihtp15jc=}
+    resolution: {integrity: 
sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==}
     engines: {node: '>=0.10'}
     dev: true
 
+  /repeating/2.0.1:
+    resolution: {integrity: 
sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      is-finite: 1.1.0
+    dev: true
+    optional: true
+
   /request-promise-core/1.1.4_request@2.88.2:
     resolution: {integrity: 
sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==}
     engines: {node: '>=0.10.0'}
@@ -11922,7 +23997,7 @@ packages:
       is-typedarray: 1.0.0
       isstream: 0.1.2
       json-stringify-safe: 5.0.1
-      mime-types: 2.1.34
+      mime-types: 2.1.35
       oauth-sign: 0.9.0
       performance-now: 2.1.0
       qs: 6.5.3
@@ -11946,8 +24021,19 @@ packages:
     resolution: {integrity: 
sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}
     dev: true
 
+  /require-relative/0.8.7:
+    resolution: {integrity: 
sha512-AKGr4qvHiryxRb19m3PsLRGuKVAbJLUD7E6eOaHkfKhwc+vSgVOCY5xNvm9EkolBKTOf0GrQAZKLimOCz81Khg==}
+    dev: true
+
   /requires-port/1.0.0:
-    resolution: {integrity: sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=}
+    resolution: {integrity: 
sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
+    dev: true
+
+  /resolve-cwd/2.0.0:
+    resolution: {integrity: 
sha512-ccu8zQTrzVr954472aUVPLEcB3YpKSYR3cg/3lo1okzobPBM+1INXBbBZlDbnI/hbEocnf8j0QVo43hQKrbchg==}
+    engines: {node: '>=4'}
+    dependencies:
+      resolve-from: 3.0.0
     dev: true
 
   /resolve-cwd/3.0.0:
@@ -11958,7 +24044,7 @@ packages:
     dev: true
 
   /resolve-from/3.0.0:
-    resolution: {integrity: sha1-six699nWiBvItuZTM17rywoYh0g=}
+    resolution: {integrity: 
sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==}
     engines: {node: '>=4'}
     dev: true
 
@@ -11977,10 +24063,15 @@ packages:
     dev: false
 
   /resolve-url/0.2.1:
-    resolution: {integrity: sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=}
+    resolution: {integrity: 
sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==}
     deprecated: https://github.com/lydell/resolve-url#deprecated
     dev: true
 
+  /resolve.exports/1.1.0:
+    resolution: {integrity: 
sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==}
+    engines: {node: '>=10'}
+    dev: true
+
   /resolve/1.21.0:
     resolution: {integrity: 
sha512-3wCbTpk5WJlyE4mSOtDLhqQmGFi0/TD9VPwmiolnk8U0wRgMEktqCXd3vy5buTO3tljvalNvKrjHEfrd2WpEKA==}
     hasBin: true
@@ -11990,15 +24081,6 @@ packages:
       supports-preserve-symlinks-flag: 1.0.0
     dev: true
 
-  /resolve/1.22.0:
-    resolution: {integrity: 
sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==}
-    hasBin: true
-    dependencies:
-      is-core-module: 2.10.0
-      path-parse: 1.0.7
-      supports-preserve-symlinks-flag: 1.0.0
-    dev: true
-
   /resolve/1.22.1:
     resolution: {integrity: 
sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==}
     hasBin: true
@@ -12016,7 +24098,7 @@ packages:
     dev: true
 
   /responselike/1.0.2:
-    resolution: {integrity: sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=}
+    resolution: {integrity: 
sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==}
     dependencies:
       lowercase-keys: 1.0.1
     dev: true
@@ -12034,6 +24116,11 @@ packages:
     engines: {node: '>=0.12'}
     dev: true
 
+  /retry/0.12.0:
+    resolution: {integrity: 
sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==}
+    engines: {node: '>= 4'}
+    dev: true
+
   /retry/0.13.1:
     resolution: {integrity: 
sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==}
     engines: {node: '>= 4'}
@@ -12045,18 +24132,18 @@ packages:
     dev: true
 
   /rgb-regex/1.0.1:
-    resolution: {integrity: sha1-wODWiC3w4jviVKR16O3UGRX+rrE=}
+    resolution: {integrity: 
sha512-gDK5mkALDFER2YLqH6imYvK6g02gpNGM4ILDZ472EwWfXZnC2ZEpoB2ECXTyOVUKuk/bPJZMzwQPBYICzP+D3w==}
     dev: true
 
   /rgba-regex/1.0.0:
-    resolution: {integrity: sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=}
+    resolution: {integrity: 
sha512-zgn5OjNQXLUTdq8m17KdaicF6w89TZs8ZU8y0AYENIU6wG8GG6LLm0yLSiPY8DmaYmHdgRW8rnApjoT0fQRfMg==}
     dev: true
 
   /rimraf/2.7.1:
     resolution: {integrity: 
sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==}
     hasBin: true
     dependencies:
-      glob: 7.2.0
+      glob: 7.2.3
     dev: true
 
   /rimraf/3.0.2:
@@ -12073,6 +24160,36 @@ packages:
       inherits: 2.0.4
     dev: true
 
+  /rollup-plugin-babel/4.4.0_n6u4oijhaodubo5gx2ecrhe56e:
+    resolution: {integrity: 
sha512-Lek/TYp1+7g7I+uMfJnnSJ7YWoD58ajo6Oarhlex7lvUce+RCKRuGRSgztDO3/MF/PuGKmUL5iTHKf208UNszw==}
+    deprecated: This package has been deprecated and is no longer maintained. 
Please use @rollup/plugin-babel.
+    peerDependencies:
+      '@babel/core': 7 || ^7.0.0-rc.2
+      rollup: '>=0.60.0 <3'
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/helper-module-imports': 7.18.6
+      rollup: 1.32.1
+      rollup-pluginutils: 2.8.2
+    dev: true
+
+  /rollup-plugin-bundle-html/0.2.2:
+    resolution: {integrity: 
sha512-nK4Z/k3MVjfCcnC5T15ksHw3JyRJx110oduy3VBW0ki2qI0tu4pLlgXyltBgtd+gpiFCPqEnfy89XRPG+eCOwA==}
+    dependencies:
+      cheerio: 1.0.0-rc.12
+      hasha: 4.0.1
+    dev: true
+
+  /rollup-plugin-css-only/3.1.0_rollup@2.79.0:
+    resolution: {integrity: 
sha512-TYMOE5uoD76vpj+RTkQLzC9cQtbnJNktHPB507FzRWBVaofg7KhIqq1kGbcVOadARSozWF883Ho9KpSPKH8gqA==}
+    engines: {node: '>=10.12.0'}
+    peerDependencies:
+      rollup: 1 || 2
+    dependencies:
+      '@rollup/pluginutils': 4.2.1
+      rollup: 2.79.0
+    dev: true
+
   /rollup-plugin-sourcemaps/0.6.3_n3h7ooyjwm4phuvjpg4pqirc4i:
     resolution: {integrity: 
sha512-paFu+nT1xvuO1tPFYXGe+XnQvg4Hjqv/eIhG8i5EspfYYPBKL57X7iVbfv55aNVASg3dzWvES9dmWsL2KhfByw==}
     engines: {node: '>=10.0.0'}
@@ -12089,6 +24206,19 @@ packages:
       source-map-resolve: 0.6.0
     dev: true
 
+  /rollup-plugin-terser/5.3.1_rollup@1.32.1:
+    resolution: {integrity: 
sha512-1pkwkervMJQGFYvM9nscrUoncPwiKR/K+bHdjv6PFgRo3cgPHoRT83y2Aa3GvINj4539S15t/tpFPb775TDs6w==}
+    peerDependencies:
+      rollup: '>=0.66.0 <3'
+    dependencies:
+      '@babel/code-frame': 7.18.6
+      jest-worker: 24.9.0
+      rollup: 1.32.1
+      rollup-pluginutils: 2.8.2
+      serialize-javascript: 4.0.0
+      terser: 4.8.0
+    dev: true
+
   /rollup-plugin-terser/7.0.2_rollup@2.79.0:
     resolution: {integrity: 
sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==}
     peerDependencies:
@@ -12101,6 +24231,21 @@ packages:
       terser: 5.10.0
     dev: true
 
+  /rollup-pluginutils/2.8.2:
+    resolution: {integrity: 
sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==}
+    dependencies:
+      estree-walker: 0.6.1
+    dev: true
+
+  /rollup/1.32.1:
+    resolution: {integrity: 
sha512-/2HA0Ec70TvQnXdzynFffkjA6XN+1e2pEv/uKS5Ulca40g2L7KuOE3riasHoNVHOsFD5KKZgDsMk1CP3Tw9s+A==}
+    hasBin: true
+    dependencies:
+      '@types/estree': 1.0.0
+      '@types/node': 18.8.5
+      acorn: 7.4.1
+    dev: true
+
   /rollup/2.79.0:
     resolution: {integrity: 
sha512-x4KsrCgwQ7ZJPcFA/SUu6QVcYlO7uRLfLAy0DSA4NS2eG8japdbpM50ToH7z4iObodRYOJ0soneF0iaQRJ6zhA==}
     engines: {node: '>=10.0.0'}
@@ -12109,6 +24254,18 @@ packages:
       fsevents: 2.3.2
     dev: true
 
+  /rst-selector-parser/2.2.3:
+    resolution: {integrity: 
sha512-nDG1rZeP6oFTLN6yNDV/uiAvs1+FS/KlrEwh7+y7dpuApDBy6bI2HTBcc0/V8lv9OTqfyD34eF7au2pm8aBbhA==}
+    dependencies:
+      lodash.flattendeep: 4.4.0
+      nearley: 2.20.1
+    dev: true
+
+  /rsvp/4.8.5:
+    resolution: {integrity: 
sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==}
+    engines: {node: 6.* || >= 7.*}
+    dev: true
+
   /run-parallel/1.2.0:
     resolution: {integrity: 
sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
     dependencies:
@@ -12116,7 +24273,7 @@ packages:
     dev: true
 
   /run-queue/1.0.3:
-    resolution: {integrity: sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=}
+    resolution: {integrity: 
sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg==}
     dependencies:
       aproba: 1.2.0
     dev: true
@@ -12128,6 +24285,10 @@ packages:
       mri: 1.2.0
     dev: true
 
+  /safe-buffer/5.1.1:
+    resolution: {integrity: 
sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==}
+    dev: true
+
   /safe-buffer/5.1.2:
     resolution: {integrity: 
sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
     dev: true
@@ -12136,8 +24297,16 @@ packages:
     resolution: {integrity: 
sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
     dev: true
 
+  /safe-regex-test/1.0.0:
+    resolution: {integrity: 
sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==}
+    dependencies:
+      call-bind: 1.0.2
+      get-intrinsic: 1.1.3
+      is-regex: 1.1.4
+    dev: true
+
   /safe-regex/1.1.0:
-    resolution: {integrity: sha1-QKNmnzsHfR6UPURinhV91IAjvy4=}
+    resolution: {integrity: 
sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==}
     dependencies:
       ret: 0.1.15
     dev: true
@@ -12146,6 +24315,73 @@ packages:
     resolution: {integrity: 
sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
     dev: true
 
+  /sane/4.1.0:
+    resolution: {integrity: 
sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==}
+    engines: {node: 6.* || 8.* || >= 10.*}
+    deprecated: some dependency vulnerabilities fixed, support for node < 10 
dropped, and newer ECMAScript syntax/features added
+    hasBin: true
+    dependencies:
+      '@cnakazawa/watch': 1.0.4
+      anymatch: 2.0.0
+      capture-exit: 2.0.0
+      exec-sh: 0.3.6
+      execa: 1.0.0
+      fb-watchman: 2.0.2
+      micromatch: 3.1.10
+      minimist: 1.2.5
+      walker: 1.0.8
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /sass-loader/10.1.1_sass@1.32.13:
+    resolution: {integrity: 
sha512-W6gVDXAd5hR/WHsPicvZdjAWHBcEJ44UahgxcIE196fW2ong0ZHMPO1kZuI5q0VlvMQZh32gpv69PLWQm70qrw==}
+    engines: {node: '>= 10.13.0'}
+    peerDependencies:
+      fibers: '>= 3.1.0'
+      node-sass: ^4.0.0 || ^5.0.0
+      sass: ^1.3.0
+      webpack: ^4.36.0 || ^5.0.0
+    peerDependenciesMeta:
+      fibers:
+        optional: true
+      node-sass:
+        optional: true
+      sass:
+        optional: true
+    dependencies:
+      klona: 2.0.5
+      loader-utils: 2.0.2
+      neo-async: 2.6.2
+      sass: 1.32.13
+      schema-utils: 3.1.1
+      semver: 7.3.8
+    dev: true
+
+  /sass-loader/10.3.1_sass@1.32.13:
+    resolution: {integrity: 
sha512-y2aBdtYkbqorVavkC3fcJIUDGIegzDWPn3/LAFhsf3G+MzPKTJx37sROf5pXtUeggSVbNbmfj8TgRaSLMelXRA==}
+    engines: {node: '>= 10.13.0'}
+    peerDependencies:
+      fibers: '>= 3.1.0'
+      node-sass: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0
+      sass: ^1.3.0
+      webpack: ^4.36.0 || ^5.0.0
+    peerDependenciesMeta:
+      fibers:
+        optional: true
+      node-sass:
+        optional: true
+      sass:
+        optional: true
+    dependencies:
+      klona: 2.0.5
+      loader-utils: 2.0.2
+      neo-async: 2.6.2
+      sass: 1.32.13
+      schema-utils: 3.1.1
+      semver: 7.3.8
+    dev: true
+
   /sass/1.32.13:
     resolution: {integrity: 
sha512-dEgI9nShraqP7cXQH+lEXVf73WOPCse0QlFzSD8k+1TcOxCMwVXfQlr0jtoluZysQOyJGnfr21dLvYKDJq8HkA==}
     engines: {node: '>=8.9.0'}
@@ -12165,6 +24401,27 @@ packages:
       xmlchars: 2.2.0
     dev: true
 
+  /saxes/5.0.1:
+    resolution: {integrity: 
sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==}
+    engines: {node: '>=10'}
+    dependencies:
+      xmlchars: 2.2.0
+    dev: true
+
+  /scheduler/0.19.1:
+    resolution: {integrity: 
sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==}
+    dependencies:
+      loose-envify: 1.4.0
+      object-assign: 4.1.1
+    dev: true
+
+  /schema-utils/0.4.7:
+    resolution: {integrity: 
sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==}
+    engines: {node: '>= 4'}
+    dependencies:
+      ajv: 6.12.6
+      ajv-keywords: 3.5.2_ajv@6.12.6
+
   /schema-utils/1.0.0:
     resolution: {integrity: 
sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==}
     engines: {node: '>= 4'}
@@ -12174,11 +24431,20 @@ packages:
       ajv-keywords: 3.5.2_ajv@6.12.6
     dev: true
 
+  /schema-utils/2.7.0:
+    resolution: {integrity: 
sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==}
+    engines: {node: '>= 8.9.0'}
+    dependencies:
+      '@types/json-schema': 7.0.11
+      ajv: 6.12.6
+      ajv-keywords: 3.5.2_ajv@6.12.6
+    dev: true
+
   /schema-utils/2.7.1:
     resolution: {integrity: 
sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==}
     engines: {node: '>= 8.9.0'}
     dependencies:
-      '@types/json-schema': 7.0.9
+      '@types/json-schema': 7.0.11
       ajv: 6.12.6
       ajv-keywords: 3.5.2_ajv@6.12.6
     dev: true
@@ -12187,7 +24453,7 @@ packages:
     resolution: {integrity: 
sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==}
     engines: {node: '>= 10.13.0'}
     dependencies:
-      '@types/json-schema': 7.0.9
+      '@types/json-schema': 7.0.11
       ajv: 6.12.6
       ajv-keywords: 3.5.2_ajv@6.12.6
     dev: true
@@ -12196,14 +24462,32 @@ packages:
     resolution: {integrity: 
sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==}
     engines: {node: '>= 12.13.0'}
     dependencies:
-      '@types/json-schema': 7.0.9
+      '@types/json-schema': 7.0.11
       ajv: 8.10.0
       ajv-formats: 2.1.1
       ajv-keywords: 5.1.0_ajv@8.10.0
     dev: true
 
+  /script-ext-html-webpack-plugin/2.1.5:
+    resolution: {integrity: 
sha512-nMjd5dtsnoB8dS+pVM9ZL4mC9O1uVtTxrDS99OGZsZxFbkZE6pw0HCMued/cncDrKivIShO9vwoyOTvsGqQHEQ==}
+    engines: {node: '>=6.11.5'}
+    peerDependencies:
+      html-webpack-plugin: ^3.0.0 || ^4.0.0
+      webpack: ^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.0
+    dependencies:
+      debug: 4.3.4
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /select-hose/2.0.0:
-    resolution: {integrity: sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=}
+    resolution: {integrity: 
sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==}
+    dev: true
+
+  /selfsigned/1.10.14:
+    resolution: {integrity: 
sha512-lkjaiAye+wBZDCBsu5BGi0XiLRxeUlsGod5ZP924CRSEoGuZAw/f7y9RKu28rwTfiHVhdavhB0qH0INV6P1lEA==}
+    dependencies:
+      node-forge: 0.10.0
     dev: true
 
   /selfsigned/2.0.0:
@@ -12213,6 +24497,11 @@ packages:
       node-forge: 1.2.1
     dev: true
 
+  /semiver/1.1.0:
+    resolution: {integrity: 
sha512-QNI2ChmuioGC1/xjyYwyZYADILWyW6AmS1UH6gDj/SFUUUS4MBAWs/7mxnkRPc/F4iHezDP+O8t0dO8WHiEOdg==}
+    engines: {node: '>=6'}
+    dev: true
+
   /semver-diff/3.1.1:
     resolution: {integrity: 
sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==}
     engines: {node: '>=8'}
@@ -12280,6 +24569,27 @@ packages:
       - supports-color
     dev: true
 
+  /send/0.17.2_supports-color@6.1.0:
+    resolution: {integrity: 
sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==}
+    engines: {node: '>= 0.8.0'}
+    dependencies:
+      debug: 2.6.9_supports-color@6.1.0
+      depd: 1.1.2
+      destroy: 1.0.4
+      encodeurl: 1.0.2
+      escape-html: 1.0.3
+      etag: 1.8.1
+      fresh: 0.5.2
+      http-errors: 1.8.1
+      mime: 1.6.0
+      ms: 2.1.3
+      on-finished: 2.3.0
+      range-parser: 1.2.1
+      statuses: 1.5.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /serialize-error/7.0.1:
     resolution: {integrity: 
sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==}
     engines: {node: '>=10'}
@@ -12305,29 +24615,67 @@ packages:
       randombytes: 2.1.0
     dev: true
 
+  /serve-favicon/2.5.0:
+    resolution: {integrity: 
sha512-FMW2RvqNr03x+C0WxTyu6sOv21oOjkq5j8tjquWccwa6ScNyGFOGJVpuS1NmTVGBAHS07xnSKotgf2ehQmf9iA==}
+    engines: {node: '>= 0.8.0'}
+    dependencies:
+      etag: 1.8.1
+      fresh: 0.5.2
+      ms: 2.1.1
+      parseurl: 1.3.3
+      safe-buffer: 5.1.1
+    dev: true
+
   /serve-index/1.9.1:
-    resolution: {integrity: sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=}
+    resolution: {integrity: 
sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==}
     engines: {node: '>= 0.8.0'}
     dependencies:
       accepts: 1.3.8
       batch: 0.6.1
       debug: 2.6.9
       escape-html: 1.0.3
-      http-errors: 1.6.3
-      mime-types: 2.1.34
+      http-errors: 1.6.3
+      mime-types: 2.1.35
+      parseurl: 1.3.3
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /serve-index/1.9.1_supports-color@6.1.0:
+    resolution: {integrity: 
sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==}
+    engines: {node: '>= 0.8.0'}
+    dependencies:
+      accepts: 1.3.8
+      batch: 0.6.1
+      debug: 2.6.9_supports-color@6.1.0
+      escape-html: 1.0.3
+      http-errors: 1.6.3
+      mime-types: 2.1.35
+      parseurl: 1.3.3
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /serve-static/1.14.2:
+    resolution: {integrity: 
sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==}
+    engines: {node: '>= 0.8.0'}
+    dependencies:
+      encodeurl: 1.0.2
+      escape-html: 1.0.3
       parseurl: 1.3.3
+      send: 0.17.2
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /serve-static/1.14.2:
+  /serve-static/1.14.2_supports-color@6.1.0:
     resolution: {integrity: 
sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==}
     engines: {node: '>= 0.8.0'}
     dependencies:
       encodeurl: 1.0.2
       escape-html: 1.0.3
       parseurl: 1.3.3
-      send: 0.17.2
+      send: 0.17.2_supports-color@6.1.0
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -12347,7 +24695,7 @@ packages:
     dev: true
 
   /setimmediate/1.0.5:
-    resolution: {integrity: sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=}
+    resolution: {integrity: 
sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==}
     dev: true
 
   /setprototypeof/1.1.0:
@@ -12373,8 +24721,12 @@ packages:
       kind-of: 6.0.3
     dev: true
 
+  /shallowequal/1.1.0:
+    resolution: {integrity: 
sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==}
+    dev: true
+
   /shebang-command/1.2.0:
-    resolution: {integrity: sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=}
+    resolution: {integrity: 
sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==}
     engines: {node: '>=0.10.0'}
     dependencies:
       shebang-regex: 1.0.0
@@ -12388,7 +24740,7 @@ packages:
     dev: true
 
   /shebang-regex/1.0.0:
-    resolution: {integrity: sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=}
+    resolution: {integrity: 
sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==}
     engines: {node: '>=0.10.0'}
     dev: true
 
@@ -12397,6 +24749,25 @@ packages:
     engines: {node: '>=8'}
     dev: true
 
+  /shell-quote/1.7.2:
+    resolution: {integrity: 
sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==}
+    dev: true
+
+  /shelljs/0.8.5:
+    resolution: {integrity: 
sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==}
+    engines: {node: '>=4'}
+    hasBin: true
+    dependencies:
+      glob: 7.2.3
+      interpret: 1.4.0
+      rechoir: 0.6.2
+    dev: true
+
+  /shellwords/0.1.1:
+    resolution: {integrity: 
sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==}
+    dev: true
+    optional: true
+
   /shiki/0.11.1:
     resolution: {integrity: 
sha512-EugY9VASFuDqOexOgXR18ZV+TbFrQHeCpEYaXamO+SZlsnT/2LxuLBX25GGtIrwaEVFXUAbUQ601SWE2rMwWHA==}
     dependencies:
@@ -12405,6 +24776,14 @@ packages:
       vscode-textmate: 6.0.0
     dev: true
 
+  /shiki/0.9.15:
+    resolution: {integrity: 
sha512-/Y0z9IzhJ8nD9nbceORCqu6NgT9X6I8Fk8c3SICHI5NbZRLdZYFaB233gwct9sU0vvSypyaL/qaKvzyQGJBZSw==}
+    dependencies:
+      jsonc-parser: 3.2.0
+      vscode-oniguruma: 1.6.2
+      vscode-textmate: 5.2.0
+    dev: true
+
   /side-channel/1.0.4:
     resolution: {integrity: 
sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==}
     dependencies:
@@ -12422,11 +24801,26 @@ packages:
     dev: true
 
   /simple-swizzle/0.2.2:
-    resolution: {integrity: sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=}
+    resolution: {integrity: 
sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
     dependencies:
       is-arrayish: 0.3.2
     dev: true
 
+  /sirv-cli/1.0.14:
+    resolution: {integrity: 
sha512-yyUTNr984ANKDloqepkYbBSqvx3buwYg2sQKPWjSU+IBia5loaoka2If8N9CMwt8AfP179cdEl7kYJ//iWJHjQ==}
+    engines: {node: '>= 10'}
+    hasBin: true
+    dependencies:
+      console-clear: 1.1.1
+      get-port: 3.2.0
+      kleur: 3.0.3
+      local-access: 1.1.0
+      sade: 1.8.1
+      semiver: 1.1.0
+      sirv: 1.0.19
+      tinydate: 1.3.0
+    dev: true
+
   /sirv/1.0.19:
     resolution: {integrity: 
sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==}
     engines: {node: '>= 10'}
@@ -12440,6 +24834,25 @@ packages:
     resolution: {integrity: 
sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
     dev: true
 
+  /size-plugin/2.0.2_webpack@4.46.0:
+    resolution: {integrity: 
sha512-pnPH6XX3TcdXTk6qsaKI6pXuOuKCpepJFTj96vjHcW/mY2zd1LhqNu7qsdkMnZS1LnA+PHaJ2C+uNveg32Loqg==}
+    peerDependencies:
+      webpack: '*'
+    dependencies:
+      axios: 0.21.4
+      chalk: 2.4.2
+      ci-env: 1.17.0
+      escape-string-regexp: 1.0.5
+      glob: 7.2.3
+      gzip-size: 5.1.1
+      minimatch: 3.1.2
+      pretty-bytes: 5.6.0
+      util.promisify: 1.1.1
+      webpack: 4.46.0
+    transitivePeerDependencies:
+      - debug
+    dev: true
+
   /size-plugin/3.0.0_webpack@4.46.0:
     resolution: {integrity: 
sha512-RPMSkgbvmS1e5XUwPNFZre7DLqcK9MhWARIm8UmGLgbUCAs173JLI6DPHco68wvo0cUdft8+GGRaJtNl5RWfew==}
     peerDependencies:
@@ -12449,8 +24862,8 @@ packages:
       chalk: 2.4.2
       ci-env: 1.17.0
       escape-string-regexp: 1.0.5
-      glob: 7.2.0
-      minimatch: 3.0.5
+      glob: 7.2.3
+      minimatch: 3.1.2
       pretty-bytes: 5.6.0
       util.promisify: 1.1.1
       webpack: 4.46.0
@@ -12458,6 +24871,16 @@ packages:
       - debug
     dev: true
 
+  /slash/1.0.0:
+    resolution: {integrity: 
sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /slash/2.0.0:
+    resolution: {integrity: 
sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==}
+    engines: {node: '>=6'}
+    dev: true
+
   /slash/3.0.0:
     resolution: {integrity: 
sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
     engines: {node: '>=8'}
@@ -12468,6 +24891,15 @@ packages:
     engines: {node: '>=12'}
     dev: true
 
+  /slice-ansi/4.0.0:
+    resolution: {integrity: 
sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==}
+    engines: {node: '>=10'}
+    dependencies:
+      ansi-styles: 4.3.0
+      astral-regex: 2.0.0
+      is-fullwidth-code-point: 3.0.0
+    dev: true
+
   /slice-ansi/5.0.0:
     resolution: {integrity: 
sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==}
     engines: {node: '>=12'}
@@ -12508,6 +24940,35 @@ packages:
       - supports-color
     dev: true
 
+  /snapdragon/0.8.2_supports-color@6.1.0:
+    resolution: {integrity: 
sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      base: 0.11.2
+      debug: 2.6.9_supports-color@6.1.0
+      define-property: 0.2.5
+      extend-shallow: 2.0.1
+      map-cache: 0.2.2
+      source-map: 0.5.7
+      source-map-resolve: 0.5.3
+      use: 3.1.1
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /sockjs-client/1.6.1_supports-color@6.1.0:
+    resolution: {integrity: 
sha512-2g0tjOR+fRs0amxENLi/q5TiJTqY+WXFOzb5UwXndlK6TO3U/mirZznpx6w34HVMoc3g7cY24yC/ZMIYnDlfkw==}
+    engines: {node: '>=12'}
+    dependencies:
+      debug: 3.2.7_supports-color@6.1.0
+      eventsource: 2.0.2
+      faye-websocket: 0.11.4
+      inherits: 2.0.4
+      url-parse: 1.5.10
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /sockjs/0.3.24:
     resolution: {integrity: 
sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==}
     dependencies:
@@ -12516,6 +24977,13 @@ packages:
       websocket-driver: 0.7.4
     dev: true
 
+  /sort-keys/1.1.2:
+    resolution: {integrity: 
sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      is-plain-obj: 1.1.0
+    dev: true
+
   /source-list-map/2.0.1:
     resolution: {integrity: 
sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==}
     dev: true
@@ -12580,6 +25048,10 @@ packages:
     resolution: {integrity: 
sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
     dev: true
 
+  /space-separated-tokens/1.1.5:
+    resolution: {integrity: 
sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==}
+    dev: true
+
   /spawn-wrap/2.0.0:
     resolution: {integrity: 
sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==}
     engines: {node: '>=8'}
@@ -12592,10 +25064,45 @@ packages:
       which: 2.0.2
     dev: true
 
+  /spdx-correct/3.1.1:
+    resolution: {integrity: 
sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==}
+    dependencies:
+      spdx-expression-parse: 3.0.1
+      spdx-license-ids: 3.0.12
+    dev: true
+
+  /spdx-exceptions/2.3.0:
+    resolution: {integrity: 
sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==}
+    dev: true
+
+  /spdx-expression-parse/3.0.1:
+    resolution: {integrity: 
sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==}
+    dependencies:
+      spdx-exceptions: 2.3.0
+      spdx-license-ids: 3.0.12
+    dev: true
+
+  /spdx-license-ids/3.0.12:
+    resolution: {integrity: 
sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==}
+    dev: true
+
   /spdy-transport/3.0.0:
     resolution: {integrity: 
sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==}
     dependencies:
-      debug: 4.3.3
+      debug: 4.3.4
+      detect-node: 2.1.0
+      hpack.js: 2.1.6
+      obuf: 1.1.2
+      readable-stream: 3.6.0
+      wbuf: 1.7.3
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /spdy-transport/3.0.0_supports-color@6.1.0:
+    resolution: {integrity: 
sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==}
+    dependencies:
+      debug: 4.3.4_supports-color@6.1.0
       detect-node: 2.1.0
       hpack.js: 2.1.6
       obuf: 1.1.2
@@ -12609,7 +25116,7 @@ packages:
     resolution: {integrity: 
sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==}
     engines: {node: '>=6.0.0'}
     dependencies:
-      debug: 4.3.3
+      debug: 4.3.4
       handle-thing: 2.0.1
       http-deceiver: 1.2.7
       select-hose: 2.0.0
@@ -12618,6 +25125,19 @@ packages:
       - supports-color
     dev: true
 
+  /spdy/4.0.2_supports-color@6.1.0:
+    resolution: {integrity: 
sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==}
+    engines: {node: '>=6.0.0'}
+    dependencies:
+      debug: 4.3.4_supports-color@6.1.0
+      handle-thing: 2.0.1
+      http-deceiver: 1.2.7
+      select-hose: 2.0.0
+      spdy-transport: 3.0.0_supports-color@6.1.0
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /split-string/3.1.0:
     resolution: {integrity: 
sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==}
     engines: {node: '>=0.10.0'}
@@ -12626,7 +25146,7 @@ packages:
     dev: true
 
   /sprintf-js/1.0.3:
-    resolution: {integrity: sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=}
+    resolution: {integrity: 
sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
     dev: true
 
   /sshpk/1.17.0:
@@ -12660,6 +25180,7 @@ packages:
 
   /stable/0.1.8:
     resolution: {integrity: 
sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==}
+    deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, 
so this library is deprecated. See the compatibility table on MDN: 
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility'
     dev: true
 
   /stack-trace/0.0.10:
@@ -12673,8 +25194,12 @@ packages:
       escape-string-regexp: 2.0.0
     dev: true
 
+  /state-toggle/1.0.3:
+    resolution: {integrity: 
sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==}
+    dev: true
+
   /static-extend/0.1.2:
-    resolution: {integrity: sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=}
+    resolution: {integrity: 
sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==}
     engines: {node: '>=0.10.0'}
     dependencies:
       define-property: 0.2.5
@@ -12682,15 +25207,19 @@ packages:
     dev: true
 
   /statuses/1.5.0:
-    resolution: {integrity: sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=}
+    resolution: {integrity: 
sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==}
     engines: {node: '>= 0.6'}
     dev: true
 
   /stealthy-require/1.1.1:
-    resolution: {integrity: sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=}
+    resolution: {integrity: 
sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==}
     engines: {node: '>=0.10.0'}
     dev: true
 
+  /store2/2.14.2:
+    resolution: {integrity: 
sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w==}
+    dev: true
+
   /stream-browserify/2.0.2:
     resolution: {integrity: 
sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==}
     dependencies:
@@ -12719,6 +25248,45 @@ packages:
     resolution: {integrity: 
sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==}
     dev: true
 
+  /strict-uri-encode/1.1.0:
+    resolution: {integrity: 
sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /string-length/4.0.2:
+    resolution: {integrity: 
sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==}
+    engines: {node: '>=10'}
+    dependencies:
+      char-regex: 1.0.2
+      strip-ansi: 6.0.1
+    dev: true
+
+  /string-length/5.0.1:
+    resolution: {integrity: 
sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==}
+    engines: {node: '>=12.20'}
+    dependencies:
+      char-regex: 2.0.1
+      strip-ansi: 7.0.1
+    dev: true
+
+  /string-width/1.0.2:
+    resolution: {integrity: 
sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      code-point-at: 1.1.0
+      is-fullwidth-code-point: 1.0.0
+      strip-ansi: 3.0.1
+    dev: true
+
+  /string-width/3.1.0:
+    resolution: {integrity: 
sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==}
+    engines: {node: '>=6'}
+    dependencies:
+      emoji-regex: 7.0.3
+      is-fullwidth-code-point: 2.0.0
+      strip-ansi: 5.2.0
+    dev: true
+
   /string-width/4.2.3:
     resolution: {integrity: 
sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
     engines: {node: '>=8'}
@@ -12750,18 +25318,61 @@ packages:
       side-channel: 1.0.4
     dev: true
 
+  /string.prototype.padend/3.1.3:
+    resolution: {integrity: 
sha512-jNIIeokznm8SD/TZISQsZKYu7RJyheFNt84DUPrh482GC8RVp2MKqm2O5oBRdGxbDQoXrhhWtPIWQOiy20svUg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.2
+      define-properties: 1.1.4
+      es-abstract: 1.20.4
+    dev: true
+
+  /string.prototype.padstart/3.1.3:
+    resolution: {integrity: 
sha512-NZydyOMtYxpTjGqp0VN5PYUF/tsU15yDMZnUdj16qRUIUiMJkHHSDElYyQFrMu+/WloTpA7MQSiADhBicDfaoA==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.2
+      define-properties: 1.1.4
+      es-abstract: 1.20.4
+    dev: true
+
+  /string.prototype.trim/1.2.6:
+    resolution: {integrity: 
sha512-8lMR2m+U0VJTPp6JjvJTtGyc4FIGq9CdRt7O9p6T0e6K4vjU+OP+SQJpbe/SBmRcCUIvNUnjsbmY6lnMp8MhsQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.2
+      define-properties: 1.1.4
+      es-abstract: 1.20.4
+    dev: true
+
   /string.prototype.trimend/1.0.4:
     resolution: {integrity: 
sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==}
     dependencies:
       call-bind: 1.0.2
-      define-properties: 1.1.3
+      define-properties: 1.1.4
+    dev: true
+
+  /string.prototype.trimend/1.0.5:
+    resolution: {integrity: 
sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==}
+    dependencies:
+      call-bind: 1.0.2
+      define-properties: 1.1.4
+      es-abstract: 1.20.4
     dev: true
 
   /string.prototype.trimstart/1.0.4:
     resolution: {integrity: 
sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==}
     dependencies:
       call-bind: 1.0.2
-      define-properties: 1.1.3
+      define-properties: 1.1.4
+    dev: true
+
+  /string.prototype.trimstart/1.0.5:
+    resolution: {integrity: 
sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==}
+    dependencies:
+      call-bind: 1.0.2
+      define-properties: 1.1.4
+      es-abstract: 1.20.4
     dev: true
 
   /string_decoder/1.1.1:
@@ -12786,18 +25397,32 @@ packages:
     dev: true
 
   /strip-ansi/0.1.1:
-    resolution: {integrity: sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=}
+    resolution: {integrity: 
sha512-behete+3uqxecWlDAm5lmskaSaISA+ThQ4oNNBDTBJt0x2ppR6IPqfZNuj6BLaLJ/Sji4TPZlcRyOis8wXQTLg==}
     engines: {node: '>=0.8.0'}
     hasBin: true
     dev: true
 
   /strip-ansi/3.0.1:
-    resolution: {integrity: sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=}
+    resolution: {integrity: 
sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==}
     engines: {node: '>=0.10.0'}
     dependencies:
       ansi-regex: 2.1.1
     dev: true
 
+  /strip-ansi/5.2.0:
+    resolution: {integrity: 
sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==}
+    engines: {node: '>=6'}
+    dependencies:
+      ansi-regex: 4.1.1
+    dev: true
+
+  /strip-ansi/6.0.0:
+    resolution: {integrity: 
sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==}
+    engines: {node: '>=8'}
+    dependencies:
+      ansi-regex: 5.0.1
+    dev: true
+
   /strip-ansi/6.0.1:
     resolution: {integrity: 
sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
     engines: {node: '>=8'}
@@ -12812,6 +25437,14 @@ packages:
       ansi-regex: 6.0.1
     dev: true
 
+  /strip-bom/2.0.0:
+    resolution: {integrity: 
sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      is-utf8: 0.2.1
+    dev: true
+    optional: true
+
   /strip-bom/3.0.0:
     resolution: {integrity: sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=}
     engines: {node: '>=4'}
@@ -12822,18 +25455,47 @@ packages:
     engines: {node: '>=8'}
     dev: true
 
+  /strip-comments/1.0.2:
+    resolution: {integrity: 
sha512-kL97alc47hoyIQSV165tTt9rG5dn4w1dNnBhOQ3bOU1Nc1hel09jnXANaHJ7vzHLd4Ju8kseDGzlev96pghLFw==}
+    engines: {node: '>=4'}
+    dependencies:
+      babel-extract-comments: 1.0.0
+      babel-plugin-transform-object-rest-spread: 6.26.0
+    dev: true
+
   /strip-comments/2.0.1:
     resolution: {integrity: 
sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==}
     engines: {node: '>=10'}
     dev: true
 
+  /strip-eof/1.0.0:
+    resolution: {integrity: 
sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
   /strip-final-newline/2.0.0:
     resolution: {integrity: 
sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
     engines: {node: '>=6'}
     dev: true
 
+  /strip-indent/1.0.1:
+    resolution: {integrity: 
sha512-I5iQq6aFMM62fBEAIB/hXzwJD6EEZ0xEGCX2t7oXqaKPIRgt4WruAQ285BISgdkP+HLGWyeGmNJcpIwFeRYRUA==}
+    engines: {node: '>=0.10.0'}
+    hasBin: true
+    dependencies:
+      get-stdin: 4.0.1
+    dev: true
+    optional: true
+
+  /strip-indent/3.0.0:
+    resolution: {integrity: 
sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==}
+    engines: {node: '>=8'}
+    dependencies:
+      min-indent: 1.0.1
+    dev: true
+
   /strip-json-comments/2.0.1:
-    resolution: {integrity: sha1-PFMZQukIwml8DsNEhYwobHygpgo=}
+    resolution: {integrity: 
sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==}
     engines: {node: '>=0.10.0'}
     dev: true
 
@@ -12842,6 +25504,17 @@ packages:
     engines: {node: '>=8'}
     dev: true
 
+  /style-loader/1.3.0_webpack@4.46.0:
+    resolution: {integrity: 
sha512-V7TCORko8rs9rIqkSrlMfkqA63DfoGBBJmK1kKGCcSi+BWb4cqz0SRsnp4l6rU5iwOEd0/2ePv68SV22VXon4Q==}
+    engines: {node: '>= 8.9.0'}
+    peerDependencies:
+      webpack: ^4.0.0 || ^5.0.0
+    dependencies:
+      loader-utils: 2.0.2
+      schema-utils: 2.7.1
+      webpack: 4.46.0
+    dev: true
+
   /style-loader/2.0.0_webpack@4.46.0:
     resolution: {integrity: 
sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ==}
     engines: {node: '>= 10.13.0'}
@@ -12853,11 +25526,17 @@ packages:
       webpack: 4.46.0
     dev: true
 
+  /style-to-object/0.3.0:
+    resolution: {integrity: 
sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==}
+    dependencies:
+      inline-style-parser: 0.1.1
+    dev: true
+
   /stylehacks/4.0.3:
     resolution: {integrity: 
sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      browserslist: 4.19.1
+      browserslist: 4.21.4
       postcss: 7.0.39
       postcss-selector-parser: 3.1.2
     dev: true
@@ -12868,7 +25547,7 @@ packages:
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
-      browserslist: 4.19.1
+      browserslist: 4.21.4
       postcss: 8.4.6
       postcss-selector-parser: 6.0.9
     dev: true
@@ -12894,6 +25573,13 @@ packages:
       has-flag: 3.0.0
     dev: true
 
+  /supports-color/6.1.0:
+    resolution: {integrity: 
sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==}
+    engines: {node: '>=6'}
+    dependencies:
+      has-flag: 3.0.0
+    dev: true
+
   /supports-color/7.2.0:
     resolution: {integrity: 
sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
     engines: {node: '>=8'}
@@ -12908,6 +25594,14 @@ packages:
       has-flag: 4.0.0
     dev: true
 
+  /supports-hyperlinks/2.3.0:
+    resolution: {integrity: 
sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==}
+    engines: {node: '>=8'}
+    dependencies:
+      has-flag: 4.0.0
+      supports-color: 7.2.0
+    dev: true
+
   /supports-preserve-symlinks-flag/1.0.0:
     resolution: {integrity: 
sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
     engines: {node: '>= 0.4'}
@@ -12948,10 +25642,55 @@ packages:
       stable: 0.1.8
     dev: true
 
+  /swr/0.5.7:
+    resolution: {integrity: 
sha512-Jh1Efgu8nWZV9rU4VLUMzBzcwaZgi4znqbVXvAtUy/0JzSiN6bNjLaJK8vhY/Rtp7a83dosz5YuehfBNwC/ZoQ==}
+    peerDependencies:
+      react: ^16.11.0 || ^17.0.0
+    dependencies:
+      dequal: 2.0.2
+    dev: false
+
+  /swr/1.1.0:
+    resolution: {integrity: 
sha512-MFL3mkl752Uap81nLA1tEu7vQmikPamSziW+6dBidYKAo4oLOlUx/x5GZy4ZCkCwfZe2uedylkz1UMGnatUX4g==}
+    peerDependencies:
+      react: ^16.11.0 || ^17.0.0 || ^18.0.0
+    dev: false
+
+  /swr/1.1.2:
+    resolution: {integrity: 
sha512-UsM0eo5T+kRPyWFZtWRx2XR5qzohs/LS4lDC0GCyLpCYFmsfTk28UCVDbOE9+KtoXY4FnwHYiF+ZYEU3hnJ1lQ==}
+    peerDependencies:
+      react: ^16.11.0 || ^17.0.0 || ^18.0.0
+    dev: false
+
   /symbol-tree/3.2.4:
     resolution: {integrity: 
sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
     dev: true
 
+  /symbol.prototype.description/1.0.5:
+    resolution: {integrity: 
sha512-x738iXRYsrAt9WBhRCVG5BtIC3B7CUkFwbHW2zOvGtwM33s7JjrCDyq8V0zgMYVb5ymsL8+qkzzpANH63CPQaQ==}
+    engines: {node: '>= 0.11.15'}
+    dependencies:
+      call-bind: 1.0.2
+      get-symbol-description: 1.0.0
+      has-symbols: 1.0.3
+      object.getownpropertydescriptors: 2.1.3
+    dev: true
+
+  /synchronous-promise/2.0.16:
+    resolution: {integrity: 
sha512-qImOD23aDfnIDNqlG1NOehdB9IYsn1V9oByPjKY1nakv2MQYCEMyX033/q+aEtYCpmYK1cv2+NTmlH+ra6GA5A==}
+    dev: true
+
+  /table/6.8.0:
+    resolution: {integrity: 
sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==}
+    engines: {node: '>=10.0.0'}
+    dependencies:
+      ajv: 8.10.0
+      lodash.truncate: 4.4.2
+      slice-ansi: 4.0.0
+      string-width: 4.2.3
+      strip-ansi: 6.0.1
+    dev: true
+
   /tapable/1.1.3:
     resolution: {integrity: 
sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==}
     engines: {node: '>=6'}
@@ -12987,11 +25726,51 @@ packages:
       yallist: 4.0.0
     dev: true
 
+  /telejson/5.3.3:
+    resolution: {integrity: 
sha512-PjqkJZpzEggA9TBpVtJi1LVptP7tYtXB6rEubwlHap76AMjzvOdKX41CxyaW7ahhzDU1aftXnMCx5kAPDZTQBA==}
+    dependencies:
+      '@types/is-function': 1.0.1
+      global: 4.4.0
+      is-function: 1.0.2
+      is-regex: 1.1.4
+      is-symbol: 1.0.4
+      isobject: 4.0.0
+      lodash: 4.17.21
+      memoizerific: 1.11.3
+    dev: true
+
+  /telejson/6.0.8:
+    resolution: {integrity: 
sha512-nerNXi+j8NK1QEfBHtZUN/aLdDcyupA//9kAboYLrtzZlPLpUfqbVGWb9zz91f/mIjRbAYhbgtnJHY8I1b5MBg==}
+    dependencies:
+      '@types/is-function': 1.0.1
+      global: 4.4.0
+      is-function: 1.0.2
+      is-regex: 1.1.4
+      is-symbol: 1.0.4
+      isobject: 4.0.0
+      lodash: 4.17.21
+      memoizerific: 1.11.3
+    dev: true
+
+  /temp-dir/1.0.0:
+    resolution: {integrity: 
sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ==}
+    engines: {node: '>=4'}
+    dev: true
+
   /temp-dir/2.0.0:
     resolution: {integrity: 
sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==}
     engines: {node: '>=8'}
     dev: true
 
+  /tempy/0.3.0:
+    resolution: {integrity: 
sha512-WrH/pui8YCwmeiAoxV+lpRH9HpRtgBhSR2ViBPgpGb/wnYDzp21R4MN45fsCGvLROvY67o3byhJRYRONJyImVQ==}
+    engines: {node: '>=8'}
+    dependencies:
+      temp-dir: 1.0.0
+      type-fest: 0.3.1
+      unique-string: 1.0.0
+    dev: true
+
   /tempy/0.6.0:
     resolution: {integrity: 
sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==}
     engines: {node: '>=10'}
@@ -13002,6 +25781,19 @@ packages:
       unique-string: 2.0.0
     dev: true
 
+  /term-size/2.2.1:
+    resolution: {integrity: 
sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==}
+    engines: {node: '>=8'}
+    dev: true
+
+  /terminal-link/2.1.1:
+    resolution: {integrity: 
sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==}
+    engines: {node: '>=8'}
+    dependencies:
+      ansi-escapes: 4.3.2
+      supports-hyperlinks: 2.3.0
+    dev: true
+
   /terser-webpack-plugin/1.4.5_webpack@4.46.0:
     resolution: {integrity: 
sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==}
     engines: {node: '>= 6.9.0'}
@@ -13020,6 +25812,26 @@ packages:
       worker-farm: 1.7.0
     dev: true
 
+  /terser-webpack-plugin/3.1.0_webpack@4.46.0:
+    resolution: {integrity: 
sha512-cjdZte66fYkZ65rQ2oJfrdCAkkhJA7YLYk5eGOcGCSGlq0ieZupRdjedSQXYknMPo2IveQL+tPdrxUkERENCFA==}
+    engines: {node: '>= 10.13.0'}
+    peerDependencies:
+      webpack: ^4.0.0 || ^5.0.0
+    dependencies:
+      cacache: 15.3.0
+      find-cache-dir: 3.3.2
+      jest-worker: 26.6.2
+      p-limit: 3.1.0
+      schema-utils: 2.7.1
+      serialize-javascript: 4.0.0
+      source-map: 0.6.1
+      terser: 4.8.0
+      webpack: 4.46.0
+      webpack-sources: 1.4.3
+    transitivePeerDependencies:
+      - bluebird
+    dev: true
+
   /terser-webpack-plugin/4.2.3_webpack@4.46.0:
     resolution: {integrity: 
sha512-jTgXh40RnvOrLQNgIkwEKnQ8rmHjHK4u+6UBEi+W+FPmvb+uo+chJXntKe7/3lW5mNysgSWD60KyesnhW8D6MQ==}
     engines: {node: '>= 10.13.0'}
@@ -13045,7 +25857,7 @@ packages:
     engines: {node: '>=6.0.0'}
     hasBin: true
     dependencies:
-      acorn: 8.7.0
+      acorn: 8.8.0
       commander: 2.20.3
       source-map: 0.6.1
       source-map-support: 0.5.21
@@ -13070,7 +25882,7 @@ packages:
     engines: {node: '>=8'}
     dependencies:
       '@istanbuljs/schema': 0.1.3
-      glob: 7.2.0
+      glob: 7.2.3
       minimatch: 3.1.2
     dev: true
 
@@ -13078,6 +25890,19 @@ packages:
     resolution: {integrity: sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=}
     dev: true
 
+  /throat/5.0.0:
+    resolution: {integrity: 
sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==}
+    dev: true
+
+  /throat/6.0.1:
+    resolution: {integrity: 
sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==}
+    dev: true
+
+  /throttle-debounce/3.0.1:
+    resolution: {integrity: 
sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==}
+    engines: {node: '>=10'}
+    dev: true
+
   /through2/2.0.5:
     resolution: {integrity: 
sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==}
     dependencies:
@@ -13102,7 +25927,7 @@ packages:
     dev: true
 
   /timsort/0.3.0:
-    resolution: {integrity: sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=}
+    resolution: {integrity: 
sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==}
     dev: true
 
   /tiny-invariant/1.1.0:
@@ -13113,22 +25938,31 @@ packages:
     resolution: {integrity: 
sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==}
     dev: false
 
+  /tinydate/1.3.0:
+    resolution: {integrity: 
sha512-7cR8rLy2QhYHpsBDBVYnnWXm8uRTr38RoZakFSW7Bs7PzfMPNZthuMLkwqZv7MTu8lhQ91cOFYS5a7iFj2oR3w==}
+    engines: {node: '>=4'}
+    dev: true
+
+  /tmpl/1.0.5:
+    resolution: {integrity: 
sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==}
+    dev: true
+
   /to-arraybuffer/1.0.1:
-    resolution: {integrity: sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=}
+    resolution: {integrity: 
sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==}
     dev: true
 
   /to-fast-properties/1.0.3:
-    resolution: {integrity: sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=}
+    resolution: {integrity: 
sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==}
     engines: {node: '>=0.10.0'}
     dev: true
 
   /to-fast-properties/2.0.0:
-    resolution: {integrity: sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=}
+    resolution: {integrity: 
sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
     engines: {node: '>=4'}
     dev: true
 
   /to-object-path/0.3.0:
-    resolution: {integrity: sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=}
+    resolution: {integrity: 
sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==}
     engines: {node: '>=0.10.0'}
     dependencies:
       kind-of: 3.2.2
@@ -13140,7 +25974,7 @@ packages:
     dev: true
 
   /to-regex-range/2.1.1:
-    resolution: {integrity: sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=}
+    resolution: {integrity: 
sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==}
     engines: {node: '>=0.10.0'}
     dependencies:
       is-number: 3.0.0
@@ -13164,15 +25998,23 @@ packages:
       safe-regex: 1.1.0
     dev: true
 
+  /toggle-selection/1.0.6:
+    resolution: {integrity: 
sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==}
+    dev: true
+
   /toidentifier/1.0.1:
     resolution: {integrity: 
sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
     engines: {node: '>=0.6'}
     dev: true
 
   /toposort/1.0.7:
-    resolution: {integrity: sha1-LmhELZ9k7HILjMieZEOsbKqVACk=}
+    resolution: {integrity: 
sha512-FclLrw8b9bMWf4QlCJuHBEVhSRsqDj6u3nIjAzPeJvgl//1hBlffdlk0MALceL14+koWEdU4ofRAXofbODxQzg==}
     dev: true
 
+  /toposort/2.0.2:
+    resolution: {integrity: 
sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==}
+    dev: false
+
   /totalist/1.1.0:
     resolution: {integrity: 
sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==}
     engines: {node: '>=6'}
@@ -13186,20 +26028,71 @@ packages:
       punycode: 2.1.1
     dev: true
 
+  /tough-cookie/4.1.2:
+    resolution: {integrity: 
sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==}
+    engines: {node: '>=6'}
+    dependencies:
+      psl: 1.8.0
+      punycode: 2.1.1
+      universalify: 0.2.0
+      url-parse: 1.5.10
+    dev: true
+
   /tr46/0.0.3:
     resolution: {integrity: sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=}
 
   /tr46/1.0.1:
-    resolution: {integrity: sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=}
+    resolution: {integrity: 
sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==}
+    dependencies:
+      punycode: 2.1.1
+    dev: true
+
+  /tr46/2.1.0:
+    resolution: {integrity: 
sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==}
+    engines: {node: '>=8'}
     dependencies:
       punycode: 2.1.1
     dev: true
 
+  /trim-newlines/1.0.0:
+    resolution: {integrity: 
sha512-Nm4cF79FhSTzrLKGDMi3I4utBtFv8qKy4sq1enftf2gMdpqI8oVQTAfySkTz5r49giVzDj88SVZXP4CeYQwjaw==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+    optional: true
+
+  /trim-trailing-lines/1.1.4:
+    resolution: {integrity: 
sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==}
+    dev: true
+
+  /trim/0.0.1:
+    resolution: {integrity: sha1-WFhUf2spB1fulczMZm+1AITEYN0=}
+    dev: true
+
+  /trough/1.0.5:
+    resolution: {integrity: 
sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==}
+    dev: true
+
+  /tryer/1.0.1:
+    resolution: {integrity: 
sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==}
+    dev: true
+
+  /ts-dedent/2.2.0:
+    resolution: {integrity: 
sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==}
+    engines: {node: '>=6.10'}
+    dev: true
+
+  /ts-invariant/0.10.3:
+    resolution: {integrity: 
sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==}
+    engines: {node: '>=8'}
+    dependencies:
+      tslib: 2.4.0
+    dev: true
+
   /ts-invariant/0.9.4:
     resolution: {integrity: 
sha512-63jtX/ZSwnUNi/WhXjnK8kz4cHHpYS60AnmA6ixz17l7E12a5puCWFlNpkne5Rl0J8TBPVHpGjsj4fxs8ObVLQ==}
     engines: {node: '>=8'}
     dependencies:
-      tslib: 2.3.1
+      tslib: 2.4.0
     dev: true
 
   /ts-pnp/1.2.0_typescript@4.2.4:
@@ -13214,6 +26107,18 @@ packages:
       typescript: 4.2.4
     dev: true
 
+  /ts-pnp/1.2.0_typescript@4.8.4:
+    resolution: {integrity: 
sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==}
+    engines: {node: '>=6'}
+    peerDependencies:
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+    dependencies:
+      typescript: 4.8.4
+    dev: true
+
   /tsconfig-paths/3.12.0:
     resolution: {integrity: 
sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==}
     dependencies:
@@ -13227,13 +26132,8 @@ packages:
     resolution: {integrity: 
sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
     dev: true
 
-  /tslib/2.3.1:
-    resolution: {integrity: 
sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==}
-    dev: true
-
   /tslib/2.4.0:
     resolution: {integrity: 
sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==}
-    dev: false
 
   /tsutils/3.21.0_typescript@4.8.4:
     resolution: {integrity: 
sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
@@ -13250,17 +26150,17 @@ packages:
     dev: true
 
   /tunnel-agent/0.6.0:
-    resolution: {integrity: sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=}
+    resolution: {integrity: 
sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==}
     dependencies:
       safe-buffer: 5.2.1
     dev: true
 
   /tweetnacl/0.14.5:
-    resolution: {integrity: sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=}
+    resolution: {integrity: 
sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==}
     dev: true
 
   /type-check/0.3.2:
-    resolution: {integrity: sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=}
+    resolution: {integrity: 
sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==}
     engines: {node: '>= 0.8.0'}
     dependencies:
       prelude-ls: 1.1.2
@@ -13292,6 +26192,21 @@ packages:
     engines: {node: '>=10'}
     dev: true
 
+  /type-fest/0.21.3:
+    resolution: {integrity: 
sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==}
+    engines: {node: '>=10'}
+    dev: true
+
+  /type-fest/0.3.1:
+    resolution: {integrity: 
sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==}
+    engines: {node: '>=6'}
+    dev: true
+
+  /type-fest/0.6.0:
+    resolution: {integrity: 
sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==}
+    engines: {node: '>=8'}
+    dev: true
+
   /type-fest/0.8.1:
     resolution: {integrity: 
sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==}
     engines: {node: '>=8'}
@@ -13302,7 +26217,7 @@ packages:
     engines: {node: '>= 0.6'}
     dependencies:
       media-typer: 0.3.0
-      mime-types: 2.1.34
+      mime-types: 2.1.35
     dev: true
 
   /typedarray-to-buffer/3.1.5:
@@ -13312,7 +26227,33 @@ packages:
     dev: true
 
   /typedarray/0.0.6:
-    resolution: {integrity: sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=}
+    resolution: {integrity: 
sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==}
+    dev: true
+
+  /typedoc-default-themes/0.12.10:
+    resolution: {integrity: 
sha512-fIS001cAYHkyQPidWXmHuhs8usjP5XVJjWB8oZGqkTowZaz3v7g3KDZeeqE82FBrmkAnIBOY3jgy7lnPnqATbA==}
+    engines: {node: '>= 8'}
+    dev: true
+
+  /typedoc/0.20.37_typescript@4.8.4:
+    resolution: {integrity: 
sha512-9+qDhdc4X00qTNOtii6QX2z7ndAeWVOso7w3MPSoSJdXlVhpwPfm1yEp4ooKuWA9fiQILR8FKkyjmeqa13hBbw==}
+    engines: {node: '>= 10.8.0'}
+    hasBin: true
+    peerDependencies:
+      typescript: 3.9.x || 4.0.x || 4.1.x || 4.2.x
+    dependencies:
+      colors: 1.4.0
+      fs-extra: 9.1.0
+      handlebars: 4.7.7
+      lodash: 4.17.21
+      lunr: 2.3.9
+      marked: 2.0.7
+      minimatch: 3.1.2
+      progress: 2.0.3
+      shelljs: 0.8.5
+      shiki: 0.9.15
+      typedoc-default-themes: 0.12.10
+      typescript: 4.8.4
     dev: true
 
   /typedoc/0.23.16_typescript@4.8.4:
@@ -13329,6 +26270,12 @@ packages:
       typescript: 4.8.4
     dev: true
 
+  /typescript/3.9.10:
+    resolution: {integrity: 
sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==}
+    engines: {node: '>=4.2.0'}
+    hasBin: true
+    dev: true
+
   /typescript/4.2.4:
     resolution: {integrity: 
sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==}
     engines: {node: '>=4.2.0'}
@@ -13355,7 +26302,16 @@ packages:
     dependencies:
       function-bind: 1.1.1
       has-bigints: 1.0.1
-      has-symbols: 1.0.2
+      has-symbols: 1.0.3
+      which-boxed-primitive: 1.0.2
+    dev: true
+
+  /unbox-primitive/1.0.2:
+    resolution: {integrity: 
sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==}
+    dependencies:
+      call-bind: 1.0.2
+      has-bigints: 1.0.2
+      has-symbols: 1.0.3
       which-boxed-primitive: 1.0.2
     dev: true
 
@@ -13367,6 +26323,13 @@ packages:
     resolution: {integrity: 
sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==}
     dev: true
 
+  /unherit/1.1.3:
+    resolution: {integrity: 
sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==}
+    dependencies:
+      inherits: 2.0.4
+      xtend: 4.0.2
+    dev: true
+
   /unicode-canonical-property-names-ecmascript/2.0.0:
     resolution: {integrity: 
sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==}
     engines: {node: '>=4'}
@@ -13390,6 +26353,18 @@ packages:
     engines: {node: '>=4'}
     dev: true
 
+  /unified/9.2.0:
+    resolution: {integrity: 
sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg==}
+    dependencies:
+      '@types/unist': 2.0.6
+      bail: 1.0.5
+      extend: 3.0.2
+      is-buffer: 2.0.5
+      is-plain-obj: 2.1.0
+      trough: 1.0.5
+      vfile: 4.2.1
+    dev: true
+
   /union-value/1.0.1:
     resolution: {integrity: 
sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==}
     engines: {node: '>=0.10.0'}
@@ -13401,11 +26376,11 @@ packages:
     dev: true
 
   /uniq/1.0.1:
-    resolution: {integrity: sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=}
+    resolution: {integrity: 
sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==}
     dev: true
 
   /uniqs/2.0.0:
-    resolution: {integrity: sha1-/+3ks2slKQaW5uFl1KWe25mOawI=}
+    resolution: {integrity: 
sha512-mZdDpf3vBV5Efh29kMw5tXoup/buMgxLzOt/XKFKcVmi+15ManNQWr6HfZ2aiZTYlYixbdNJ0KFmIZIv52tHSQ==}
     dev: true
 
   /unique-filename/1.1.1:
@@ -13420,6 +26395,13 @@ packages:
       imurmurhash: 0.1.4
     dev: true
 
+  /unique-string/1.0.0:
+    resolution: {integrity: 
sha512-ODgiYu03y5g76A1I9Gt0/chLCzQjvzDy7DsZGsLOE/1MrF6wriEskSncj1+/C58Xk/kPZDppSctDybCwOSaGAg==}
+    engines: {node: '>=4'}
+    dependencies:
+      crypto-random-string: 1.0.0
+    dev: true
+
   /unique-string/2.0.0:
     resolution: {integrity: 
sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==}
     engines: {node: '>=8'}
@@ -13427,38 +26409,130 @@ packages:
       crypto-random-string: 2.0.0
     dev: true
 
+  /unist-builder/2.0.3:
+    resolution: {integrity: 
sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw==}
+    dev: true
+
+  /unist-util-generated/1.1.6:
+    resolution: {integrity: 
sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg==}
+    dev: true
+
+  /unist-util-is/4.1.0:
+    resolution: {integrity: 
sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==}
+    dev: true
+
+  /unist-util-position/3.1.0:
+    resolution: {integrity: 
sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==}
+    dev: true
+
+  /unist-util-remove-position/2.0.1:
+    resolution: {integrity: 
sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA==}
+    dependencies:
+      unist-util-visit: 2.0.3
+    dev: true
+
+  /unist-util-remove/2.1.0:
+    resolution: {integrity: 
sha512-J8NYPyBm4baYLdCbjmf1bhPu45Cr1MWTm77qd9istEkzWpnN6O9tMsEbB2JhNnBCqGENRqEWomQ+He6au0B27Q==}
+    dependencies:
+      unist-util-is: 4.1.0
+    dev: true
+
+  /unist-util-stringify-position/2.0.3:
+    resolution: {integrity: 
sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==}
+    dependencies:
+      '@types/unist': 2.0.6
+    dev: true
+
+  /unist-util-visit-parents/3.1.1:
+    resolution: {integrity: 
sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==}
+    dependencies:
+      '@types/unist': 2.0.6
+      unist-util-is: 4.1.0
+    dev: true
+
+  /unist-util-visit/2.0.3:
+    resolution: {integrity: 
sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==}
+    dependencies:
+      '@types/unist': 2.0.6
+      unist-util-is: 4.1.0
+      unist-util-visit-parents: 3.1.1
+    dev: true
+
   /universalify/0.1.2:
     resolution: {integrity: 
sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
     engines: {node: '>= 4.0.0'}
     dev: true
 
+  /universalify/0.2.0:
+    resolution: {integrity: 
sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==}
+    engines: {node: '>= 4.0.0'}
+    dev: true
+
   /universalify/2.0.0:
     resolution: {integrity: 
sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==}
     engines: {node: '>= 10.0.0'}
     dev: true
 
   /unpipe/1.0.0:
-    resolution: {integrity: sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=}
+    resolution: {integrity: 
sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
     engines: {node: '>= 0.8'}
     dev: true
 
   /unquote/1.1.1:
-    resolution: {integrity: sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=}
+    resolution: {integrity: 
sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==}
     dev: true
 
   /unset-value/1.0.0:
-    resolution: {integrity: sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=}
+    resolution: {integrity: 
sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==}
     engines: {node: '>=0.10.0'}
     dependencies:
       has-value: 0.3.1
       isobject: 3.0.1
     dev: true
 
+  /untildify/2.1.0:
+    resolution: {integrity: 
sha512-sJjbDp2GodvkB0FZZcn7k6afVisqX5BZD7Yq3xp4nN2O15BBK0cLm3Vwn2vQaF7UDS0UUsrQMkkplmDI5fskig==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      os-homedir: 1.0.2
+    dev: true
+    optional: true
+
   /upath/1.2.0:
     resolution: {integrity: 
sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==}
     engines: {node: '>=4'}
     dev: true
 
+  /update-browserslist-db/1.0.10_browserslist@4.21.4:
+    resolution: {integrity: 
sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==}
+    hasBin: true
+    peerDependencies:
+      browserslist: '>= 4.21.0'
+    dependencies:
+      browserslist: 4.21.4
+      escalade: 3.1.1
+      picocolors: 1.0.0
+    dev: true
+
+  /update-notifier/4.1.3:
+    resolution: {integrity: 
sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==}
+    engines: {node: '>=8'}
+    dependencies:
+      boxen: 4.2.0
+      chalk: 3.0.0
+      configstore: 5.0.1
+      has-yarn: 2.1.0
+      import-lazy: 2.1.0
+      is-ci: 2.0.0
+      is-installed-globally: 0.3.2
+      is-npm: 4.0.0
+      is-yarn-global: 0.3.0
+      latest-version: 5.1.0
+      pupa: 2.1.1
+      semver-diff: 3.1.1
+      xdg-basedir: 4.0.0
+    dev: true
+
   /update-notifier/5.1.0:
     resolution: {integrity: 
sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==}
     engines: {node: '>=10'}
@@ -13474,23 +26548,22 @@ packages:
       is-yarn-global: 0.3.0
       latest-version: 5.1.0
       pupa: 2.1.1
-      semver: 7.3.5
+      semver: 7.3.8
       semver-diff: 3.1.1
       xdg-basedir: 4.0.0
     dev: true
 
   /upper-case/1.1.3:
-    resolution: {integrity: sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=}
+    resolution: {integrity: 
sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==}
     dev: true
 
   /uri-js/4.4.1:
     resolution: {integrity: 
sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
     dependencies:
       punycode: 2.1.1
-    dev: true
 
   /urix/0.1.0:
-    resolution: {integrity: sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=}
+    resolution: {integrity: 
sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==}
     deprecated: Please see https://github.com/lydell/urix#deprecated
     dev: true
 
@@ -13506,47 +26579,115 @@ packages:
     dependencies:
       file-loader: 6.2.0_webpack@4.46.0
       loader-utils: 2.0.2
-      mime-types: 2.1.34
+      mime-types: 2.1.35
       schema-utils: 3.1.1
       webpack: 4.46.0
     dev: true
 
   /url-parse-lax/3.0.0:
-    resolution: {integrity: sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=}
+    resolution: {integrity: 
sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==}
     engines: {node: '>=4'}
     dependencies:
       prepend-http: 2.0.0
     dev: true
 
+  /url-parse/1.5.10:
+    resolution: {integrity: 
sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==}
+    dependencies:
+      querystringify: 2.2.0
+      requires-port: 1.0.0
+    dev: true
+
   /url/0.11.0:
-    resolution: {integrity: sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=}
+    resolution: {integrity: 
sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==}
     dependencies:
       punycode: 1.3.2
       querystring: 0.2.0
     dev: true
 
+  /use-composed-ref/1.3.0:
+    resolution: {integrity: 
sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dev: true
+
+  /use-composed-ref/1.3.0_react@16.14.0:
+    resolution: {integrity: 
sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==}
+    peerDependencies:
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+    dependencies:
+      react: 16.14.0
+    dev: true
+
+  /use-isomorphic-layout-effect/1.1.2:
+    resolution: {integrity: 
sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==}
+    peerDependencies:
+      '@types/react': '*'
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+    peerDependenciesMeta:
+      '@types/react':
+        optional: true
+    dev: true
+
+  /use-isomorphic-layout-effect/1.1.2_react@16.14.0:
+    resolution: {integrity: 
sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==}
+    peerDependencies:
+      '@types/react': '*'
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+    peerDependenciesMeta:
+      '@types/react':
+        optional: true
+    dependencies:
+      react: 16.14.0
+    dev: true
+
+  /use-latest/1.2.1:
+    resolution: {integrity: 
sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==}
+    peerDependencies:
+      '@types/react': '*'
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+    peerDependenciesMeta:
+      '@types/react':
+        optional: true
+    dependencies:
+      use-isomorphic-layout-effect: 1.1.2
+    dev: true
+
+  /use-latest/1.2.1_react@16.14.0:
+    resolution: {integrity: 
sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==}
+    peerDependencies:
+      '@types/react': '*'
+      react: ^16.8.0 || ^17.0.0 || ^18.0.0
+    peerDependenciesMeta:
+      '@types/react':
+        optional: true
+    dependencies:
+      react: 16.14.0
+      use-isomorphic-layout-effect: 1.1.2_react@16.14.0
+    dev: true
+
   /use/3.1.1:
     resolution: {integrity: 
sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==}
     engines: {node: '>=0.10.0'}
     dev: true
 
   /util-deprecate/1.0.2:
-    resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=}
+    resolution: {integrity: 
sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
     dev: true
 
   /util.promisify/1.0.0:
     resolution: {integrity: 
sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==}
     dependencies:
-      define-properties: 1.1.3
+      define-properties: 1.1.4
       object.getownpropertydescriptors: 2.1.3
     dev: true
 
   /util.promisify/1.0.1:
-    resolution: {integrity: 
sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==}
-    dependencies:
-      define-properties: 1.1.3
-      es-abstract: 1.19.1
-      has-symbols: 1.0.2
+    resolution: {integrity: 
sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==}
+    dependencies:
+      define-properties: 1.1.4
+      es-abstract: 1.20.4
+      has-symbols: 1.0.3
       object.getownpropertydescriptors: 2.1.3
     dev: true
 
@@ -13554,14 +26695,14 @@ packages:
     resolution: {integrity: 
sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw==}
     dependencies:
       call-bind: 1.0.2
-      define-properties: 1.1.3
+      define-properties: 1.1.4
       for-each: 0.3.3
-      has-symbols: 1.0.2
+      has-symbols: 1.0.3
       object.getownpropertydescriptors: 2.1.3
     dev: true
 
   /util/0.10.3:
-    resolution: {integrity: sha1-evsa/lCAUkZInj23/g7TeTNqwPk=}
+    resolution: {integrity: 
sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==}
     dependencies:
       inherits: 2.0.1
     dev: true
@@ -13573,7 +26714,7 @@ packages:
     dev: true
 
   /utila/0.4.0:
-    resolution: {integrity: sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=}
+    resolution: {integrity: 
sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==}
     dev: true
 
   /utils-merge/1.0.1:
@@ -13581,6 +26722,10 @@ packages:
     engines: {node: '>= 0.4.0'}
     dev: true
 
+  /uuid-browser/3.1.0:
+    resolution: {integrity: 
sha512-dsNgbLaTrd6l3MMxTtouOCFw4CBFc/3a+GgYA2YyrJvyQ1u6q4pcu3ktLoUZ/VN/Aw9WsauazbgsgdfVWgAKQg==}
+    dev: true
+
   /uuid/3.4.0:
     resolution: {integrity: 
sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==}
     deprecated: Please upgrade  to version 7 or higher.  Older versions may 
use Math.random() in certain circumstances, which is known to be problematic.  
See https://v8.dev/blog/math-random for details.
@@ -13596,6 +26741,15 @@ packages:
     resolution: {integrity: 
sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==}
     dev: true
 
+  /v8-to-istanbul/7.1.2:
+    resolution: {integrity: 
sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==}
+    engines: {node: '>=10.10.0'}
+    dependencies:
+      '@types/istanbul-lib-coverage': 2.0.4
+      convert-source-map: 1.8.0
+      source-map: 0.7.3
+    dev: true
+
   /v8-to-istanbul/8.1.1:
     resolution: {integrity: 
sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==}
     engines: {node: '>=10.12.0'}
@@ -13605,8 +26759,15 @@ packages:
       source-map: 0.7.3
     dev: true
 
+  /validate-npm-package-license/3.0.4:
+    resolution: {integrity: 
sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
+    dependencies:
+      spdx-correct: 3.1.1
+      spdx-expression-parse: 3.0.1
+    dev: true
+
   /validate-npm-package-name/3.0.0:
-    resolution: {integrity: sha1-X6kS2B630MdK/BQN5zF/DKffQ34=}
+    resolution: {integrity: 
sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==}
     dependencies:
       builtins: 1.0.3
     dev: true
@@ -13616,7 +26777,7 @@ packages:
     dev: false
 
   /vary/1.1.2:
-    resolution: {integrity: sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=}
+    resolution: {integrity: 
sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
     engines: {node: '>= 0.8'}
     dev: true
 
@@ -13633,6 +26794,26 @@ packages:
       extsprintf: 1.3.0
     dev: true
 
+  /vfile-location/3.2.0:
+    resolution: {integrity: 
sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA==}
+    dev: true
+
+  /vfile-message/2.0.4:
+    resolution: {integrity: 
sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==}
+    dependencies:
+      '@types/unist': 2.0.6
+      unist-util-stringify-position: 2.0.3
+    dev: true
+
+  /vfile/4.2.1:
+    resolution: {integrity: 
sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==}
+    dependencies:
+      '@types/unist': 2.0.6
+      is-buffer: 2.0.5
+      unist-util-stringify-position: 2.0.3
+      vfile-message: 2.0.4
+    dev: true
+
   /vm-browserify/1.1.2:
     resolution: {integrity: 
sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==}
     dev: true
@@ -13641,16 +26822,40 @@ packages:
     resolution: {integrity: 
sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==}
     dev: true
 
+  /vscode-textmate/5.2.0:
+    resolution: {integrity: 
sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==}
+    dev: true
+
   /vscode-textmate/6.0.0:
     resolution: {integrity: 
sha512-gu73tuZfJgu+mvCSy4UZwd2JXykjK9zAZsfmDeut5dx/1a7FeTk0XwJsSuqQn+cuMCGVbIBfl+s53X4T19DnzQ==}
     dev: true
 
   /w3c-hr-time/1.0.2:
     resolution: {integrity: 
sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==}
+    deprecated: Use your platform's native performance.now() and 
performance.timeOrigin.
     dependencies:
       browser-process-hrtime: 1.0.0
     dev: true
 
+  /w3c-xmlserializer/2.0.0:
+    resolution: {integrity: 
sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==}
+    engines: {node: '>=10'}
+    dependencies:
+      xml-name-validator: 3.0.0
+    dev: true
+
+  /walker/1.0.8:
+    resolution: {integrity: 
sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==}
+    dependencies:
+      makeerror: 1.0.12
+    dev: true
+
+  /warning/4.0.3:
+    resolution: {integrity: 
sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==}
+    dependencies:
+      loose-envify: 1.4.0
+    dev: true
+
   /watchpack-chokidar2/2.0.1:
     resolution: {integrity: 
sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==}
     requiresBuild: true
@@ -13664,7 +26869,7 @@ packages:
   /watchpack/1.7.5:
     resolution: {integrity: 
sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==}
     dependencies:
-      graceful-fs: 4.2.9
+      graceful-fs: 4.2.10
       neo-async: 2.6.2
     optionalDependencies:
       chokidar: 3.5.3
@@ -13673,6 +26878,14 @@ packages:
       - supports-color
     dev: true
 
+  /watchpack/2.4.0:
+    resolution: {integrity: 
sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==}
+    engines: {node: '>=10.13.0'}
+    dependencies:
+      glob-to-regexp: 0.4.1
+      graceful-fs: 4.2.10
+    dev: true
+
   /wbuf/1.7.3:
     resolution: {integrity: 
sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==}
     dependencies:
@@ -13680,11 +26893,15 @@ packages:
     dev: true
 
   /wcwidth/1.0.1:
-    resolution: {integrity: sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=}
+    resolution: {integrity: 
sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==}
     dependencies:
       defaults: 1.0.3
     dev: true
 
+  /web-namespaces/1.1.4:
+    resolution: {integrity: 
sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==}
+    dev: true
+
   /web-streams-polyfill/3.2.0:
     resolution: {integrity: 
sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA==}
     engines: {node: '>= 8'}
@@ -13697,6 +26914,40 @@ packages:
     resolution: {integrity: 
sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==}
     dev: true
 
+  /webidl-conversions/5.0.0:
+    resolution: {integrity: 
sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==}
+    engines: {node: '>=8'}
+    dev: true
+
+  /webidl-conversions/6.1.0:
+    resolution: {integrity: 
sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==}
+    engines: {node: '>=10.4'}
+    dev: true
+
+  /webpack-bundle-analyzer/3.9.0:
+    resolution: {integrity: 
sha512-Ob8amZfCm3rMB1ScjQVlbYYUEJyEjdEtQ92jqiFUYt5VkEeO2v5UMbv49P/gnmCZm3A6yaFQzCBvpZqN4MUsdA==}
+    engines: {node: '>= 6.14.4'}
+    hasBin: true
+    dependencies:
+      acorn: 7.4.1
+      acorn-walk: 7.2.0
+      bfj: 6.1.2
+      chalk: 2.4.2
+      commander: 2.20.3
+      ejs: 2.7.4
+      express: 4.17.2
+      filesize: 3.6.1
+      gzip-size: 5.1.1
+      lodash: 4.17.21
+      mkdirp: 0.5.5
+      opener: 1.5.2
+      ws: 6.2.2
+    transitivePeerDependencies:
+      - bufferutil
+      - supports-color
+      - utf-8-validate
+    dev: true
+
   /webpack-bundle-analyzer/4.5.0:
     resolution: {integrity: 
sha512-GUMZlM3SKwS8Z+CKeIFx7CVoHn3dXFcUAjT/dcZQQmfSZGvitPfMob2ipjai7ovFFqPvTqkEZ/leL4O0YOdAYQ==}
     engines: {node: '>= 10.13.0'}
@@ -13716,6 +26967,20 @@ packages:
       - utf-8-validate
     dev: true
 
+  /webpack-dev-middleware/3.7.3_webpack@4.46.0:
+    resolution: {integrity: 
sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==}
+    engines: {node: '>= 6'}
+    peerDependencies:
+      webpack: ^4.0.0 || ^5.0.0
+    dependencies:
+      memory-fs: 0.4.1
+      mime: 2.6.0
+      mkdirp: 0.5.5
+      range-parser: 1.2.1
+      webpack: 4.46.0
+      webpack-log: 2.0.0
+    dev: true
+
   /webpack-dev-middleware/5.3.1_webpack@4.46.0:
     resolution: {integrity: 
sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg==}
     engines: {node: '>= 12.13.0'}
@@ -13724,12 +26989,62 @@ packages:
     dependencies:
       colorette: 2.0.16
       memfs: 3.4.1
-      mime-types: 2.1.34
+      mime-types: 2.1.35
       range-parser: 1.2.1
       schema-utils: 4.0.0
       webpack: 4.46.0
     dev: true
 
+  /webpack-dev-server/3.11.3_webpack@4.46.0:
+    resolution: {integrity: 
sha512-3x31rjbEQWKMNzacUZRE6wXvUFuGpH7vr0lIEbYpMAG9BOxi0928QU1BBswOAP3kg3H1O4hiS+sq4YyAn6ANnA==}
+    engines: {node: '>= 6.11.5'}
+    hasBin: true
+    peerDependencies:
+      webpack: ^4.0.0 || ^5.0.0
+      webpack-cli: '*'
+    peerDependenciesMeta:
+      webpack-cli:
+        optional: true
+    dependencies:
+      ansi-html-community: 0.0.8
+      bonjour: 3.5.0
+      chokidar: 2.1.8_supports-color@6.1.0
+      compression: 1.7.4_supports-color@6.1.0
+      connect-history-api-fallback: 1.6.0
+      debug: 4.3.4_supports-color@6.1.0
+      del: 4.1.1
+      express: 4.17.2_supports-color@6.1.0
+      html-entities: 1.4.0
+      http-proxy-middleware: 0.19.1_tmpgdztspuwvsxzgjkhoqk7duq
+      import-local: 2.0.0
+      internal-ip: 4.3.0
+      ip: 1.1.5
+      is-absolute-url: 3.0.3
+      killable: 1.0.1
+      loglevel: 1.8.0
+      opn: 5.5.0
+      p-retry: 3.0.1
+      portfinder: 1.0.28_supports-color@6.1.0
+      schema-utils: 1.0.0
+      selfsigned: 1.10.14
+      semver: 6.3.0
+      serve-index: 1.9.1_supports-color@6.1.0
+      sockjs: 0.3.24
+      sockjs-client: 1.6.1_supports-color@6.1.0
+      spdy: 4.0.2_supports-color@6.1.0
+      strip-ansi: 3.0.1
+      supports-color: 6.1.0
+      url: 0.11.0
+      webpack: 4.46.0
+      webpack-dev-middleware: 3.7.3_webpack@4.46.0
+      webpack-log: 2.0.0
+      ws: 6.2.2
+      yargs: 13.3.2
+    transitivePeerDependencies:
+      - bufferutil
+      - utf-8-validate
+    dev: true
+
   /webpack-dev-server/4.7.4_webpack@4.46.0:
     resolution: {integrity: 
sha512-nfdsb02Zi2qzkNmgtZjkrMOcXnYZ6FLKcQwpxT7MvmHKc+oTtDsBju8j+NMyAygZ9GW1jMEUpy3itHtqgEhe1A==}
     engines: {node: '>= 12.13.0'}
@@ -13779,10 +27094,31 @@ packages:
       - utf-8-validate
     dev: true
 
+  /webpack-filter-warnings-plugin/1.2.1_webpack@4.46.0:
+    resolution: {integrity: 
sha512-Ez6ytc9IseDMLPo0qCuNNYzgtUl8NovOqjIq4uAU8LTD4uoa1w1KpZyyzFtLTEMZpkkOkLfL9eN+KGYdk1Qtwg==}
+    engines: {node: '>= 4.3 < 5.0.0 || >= 5.10'}
+    peerDependencies:
+      webpack: ^2.0.0 || ^3.0.0 || ^4.0.0
+    dependencies:
+      webpack: 4.46.0
+    dev: true
+
+  /webpack-fix-style-only-entries/0.5.2:
+    resolution: {integrity: 
sha512-BlJyvvLSmQmvVY+sWbXMoS3qkcglXDKB16sM3Mao0Ce5oeGF6goyLZ2g89gWk29pA0/CDS6En8aNAMIPMOk3wQ==}
+    dev: true
+
   /webpack-fix-style-only-entries/0.6.1:
     resolution: {integrity: 
sha512-wyIhoxS3DD3Fr9JA8hQPA+ZmaWnqPxx12Nv166wcsI/0fbReqyEtiIk2llOFYIg57WVS3XX5cZJxw2ji70R0sA==}
     dev: true
 
+  /webpack-hot-middleware/2.25.2:
+    resolution: {integrity: 
sha512-CVgm3NAQyfdIonRvXisRwPTUYuSbyZ6BY7782tMeUzWOO7RmVI2NaBYuCp41qyD4gYCkJyTneAJdK69A13B0+A==}
+    dependencies:
+      ansi-html-community: 0.0.8
+      html-entities: 2.3.2
+      strip-ansi: 6.0.1
+    dev: true
+
   /webpack-log/2.0.0:
     resolution: {integrity: 
sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==}
     engines: {node: '>= 6'}
@@ -13791,6 +27127,12 @@ packages:
       uuid: 3.4.0
     dev: true
 
+  /webpack-merge/4.2.2:
+    resolution: {integrity: 
sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==}
+    dependencies:
+      lodash: 4.17.21
+    dev: true
+
   /webpack-merge/5.8.0:
     resolution: {integrity: 
sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==}
     engines: {node: '>=10.0.0'}
@@ -13811,6 +27153,14 @@ packages:
       source-map: 0.6.1
     dev: true
 
+  /webpack-virtual-modules/0.2.2:
+    resolution: {integrity: 
sha512-kDUmfm3BZrei0y+1NTHJInejzxfhtU8eDj2M7OKb2IWrPFAeO1SOH2KuQ68MSZu9IGEHcxbkKKR1v18FrUSOmA==}
+    dependencies:
+      debug: 3.2.7
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /webpack/4.46.0:
     resolution: {integrity: 
sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q==}
     engines: {node: '>=6.11.5'}
@@ -13894,6 +27244,15 @@ packages:
       webidl-conversions: 4.0.2
     dev: true
 
+  /whatwg-url/8.7.0:
+    resolution: {integrity: 
sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==}
+    engines: {node: '>=10'}
+    dependencies:
+      lodash: 4.17.21
+      tr46: 2.1.0
+      webidl-conversions: 6.1.0
+    dev: true
+
   /which-boxed-primitive/1.0.2:
     resolution: {integrity: 
sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==}
     dependencies:
@@ -13904,10 +27263,31 @@ packages:
       is-symbol: 1.0.4
     dev: true
 
+  /which-collection/1.0.1:
+    resolution: {integrity: 
sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==}
+    dependencies:
+      is-map: 2.0.2
+      is-set: 2.0.2
+      is-weakmap: 2.0.1
+      is-weakset: 2.0.2
+    dev: true
+
   /which-module/2.0.0:
     resolution: {integrity: sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=}
     dev: true
 
+  /which-typed-array/1.1.8:
+    resolution: {integrity: 
sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      available-typed-arrays: 1.0.5
+      call-bind: 1.0.2
+      es-abstract: 1.20.4
+      for-each: 0.3.3
+      has-tostringtag: 1.0.0
+      is-typed-array: 1.1.9
+    dev: true
+
   /which/1.3.1:
     resolution: {integrity: 
sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==}
     hasBin: true
@@ -13923,6 +27303,12 @@ packages:
       isexe: 2.0.0
     dev: true
 
+  /wide-align/1.1.5:
+    resolution: {integrity: 
sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==}
+    dependencies:
+      string-width: 4.2.3
+    dev: true
+
   /widest-line/3.1.0:
     resolution: {integrity: 
sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==}
     engines: {node: '>=8'}
@@ -13939,6 +27325,16 @@ packages:
     engines: {node: '>=0.10.0'}
     dev: true
 
+  /wordwrap/1.0.0:
+    resolution: {integrity: 
sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==}
+    dev: true
+
+  /workbox-background-sync/5.1.4:
+    resolution: {integrity: 
sha512-AH6x5pYq4vwQvfRDWH+vfOePfPIYQ00nCEB7dJRU1e0n9+9HMRyvI63FlDvtFT2AvXVRsXvUt7DNMEToyJLpSA==}
+    dependencies:
+      workbox-core: 5.1.4
+    dev: true
+
   /workbox-background-sync/6.4.2:
     resolution: {integrity: 
sha512-P7c8uG5X2k+DMICH9xeSA9eUlCOjHHYoB42Rq+RtUpuwBxUOflAXR1zdsMWj81LopE4gjKXlTw7BFd1BDAHo7g==}
     dependencies:
@@ -13946,21 +27342,71 @@ packages:
       workbox-core: 6.4.2
     dev: true
 
+  /workbox-broadcast-update/5.1.4:
+    resolution: {integrity: 
sha512-HTyTWkqXvHRuqY73XrwvXPud/FN6x3ROzkfFPsRjtw/kGZuZkPzfeH531qdUGfhtwjmtO/ZzXcWErqVzJNdXaA==}
+    dependencies:
+      workbox-core: 5.1.4
+    dev: true
+
   /workbox-broadcast-update/6.4.2:
     resolution: {integrity: 
sha512-qnBwQyE0+PWFFc/n4ISXINE49m44gbEreJUYt2ldGH3+CNrLmJ1egJOOyUqqu9R4Eb7QrXcmB34ClXG7S37LbA==}
     dependencies:
       workbox-core: 6.4.2
     dev: true
 
+  /workbox-build/5.1.4:
+    resolution: {integrity: 
sha512-xUcZn6SYU8usjOlfLb9Y2/f86Gdo+fy1fXgH8tJHjxgpo53VVsqRX0lUDw8/JuyzNmXuo8vXX14pXX2oIm9Bow==}
+    engines: {node: '>=8.0.0'}
+    dependencies:
+      '@babel/core': 7.19.6
+      '@babel/preset-env': 7.16.11_@babel+core@7.19.6
+      '@babel/runtime': 7.17.8
+      '@hapi/joi': 15.1.1
+      '@rollup/plugin-node-resolve': 7.1.3_rollup@1.32.1
+      '@rollup/plugin-replace': 2.4.2_rollup@1.32.1
+      '@surma/rollup-plugin-off-main-thread': 1.4.2
+      common-tags: 1.8.2
+      fast-json-stable-stringify: 2.1.0
+      fs-extra: 8.1.0
+      glob: 7.2.3
+      lodash.template: 4.5.0
+      pretty-bytes: 5.6.0
+      rollup: 1.32.1
+      rollup-plugin-babel: 4.4.0_n6u4oijhaodubo5gx2ecrhe56e
+      rollup-plugin-terser: 5.3.1_rollup@1.32.1
+      source-map: 0.7.3
+      source-map-url: 0.4.1
+      stringify-object: 3.3.0
+      strip-comments: 1.0.2
+      tempy: 0.3.0
+      upath: 1.2.0
+      workbox-background-sync: 5.1.4
+      workbox-broadcast-update: 5.1.4
+      workbox-cacheable-response: 5.1.4
+      workbox-core: 5.1.4
+      workbox-expiration: 5.1.4
+      workbox-google-analytics: 5.1.4
+      workbox-navigation-preload: 5.1.4
+      workbox-precaching: 5.1.4
+      workbox-range-requests: 5.1.4
+      workbox-routing: 5.1.4
+      workbox-strategies: 5.1.4
+      workbox-streams: 5.1.4
+      workbox-sw: 5.1.4
+      workbox-window: 5.1.4
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /workbox-build/6.4.2:
     resolution: {integrity: 
sha512-WMdYLhDIsuzViOTXDH+tJ1GijkFp5khSYolnxR/11zmfhNDtuo7jof72xPGFy+KRpsz6tug39RhivCj77qqO0w==}
     engines: {node: '>=10.0.0'}
     dependencies:
       '@apideck/better-ajv-errors': 0.3.3_ajv@8.10.0
-      '@babel/core': 7.17.2
-      '@babel/preset-env': 7.16.11_@babel+core@7.17.2
-      '@babel/runtime': 7.17.2
-      '@rollup/plugin-babel': 5.3.0_lubkdqoa5gexe4rox23cswxwm4
+      '@babel/core': 7.19.6
+      '@babel/preset-env': 7.16.11_@babel+core@7.19.6
+      '@babel/runtime': 7.17.8
+      '@rollup/plugin-babel': 5.3.0_s45mkc5s7is4owdeow33qgy2s4
       '@rollup/plugin-node-resolve': 11.2.1_rollup@2.79.0
       '@rollup/plugin-replace': 2.4.2_rollup@2.79.0
       '@surma/rollup-plugin-off-main-thread': 2.2.3
@@ -13968,7 +27414,7 @@ packages:
       common-tags: 1.8.2
       fast-json-stable-stringify: 2.1.0
       fs-extra: 9.1.0
-      glob: 7.2.0
+      glob: 7.2.3
       lodash: 4.17.21
       pretty-bytes: 5.6.0
       rollup: 2.79.0
@@ -13999,16 +27445,32 @@ packages:
       - supports-color
     dev: true
 
+  /workbox-cacheable-response/5.1.4:
+    resolution: {integrity: 
sha512-0bfvMZs0Of1S5cdswfQK0BXt6ulU5kVD4lwer2CeI+03czHprXR3V4Y8lPTooamn7eHP8Iywi5QjyAMjw0qauA==}
+    dependencies:
+      workbox-core: 5.1.4
+    dev: true
+
   /workbox-cacheable-response/6.4.2:
     resolution: {integrity: 
sha512-9FE1W/cKffk1AJzImxgEN0ceWpyz1tqNjZVtA3/LAvYL3AC5SbIkhc7ZCO82WmO9IjTfu8Vut2X/C7ViMSF7TA==}
     dependencies:
       workbox-core: 6.4.2
     dev: true
 
+  /workbox-core/5.1.4:
+    resolution: {integrity: 
sha512-+4iRQan/1D8I81nR2L5vcbaaFskZC2CL17TLbvWVzQ4qiF/ytOGF6XeV54pVxAvKUtkLANhk8TyIUMtiMw2oDg==}
+    dev: true
+
   /workbox-core/6.4.2:
     resolution: {integrity: 
sha512-1U6cdEYPcajRXiboSlpJx6U7TvhIKbxRRerfepAJu2hniKwJ3DHILjpU/zx3yvzSBCWcNJDoFalf7Vgd7ey/rw==}
     dev: true
 
+  /workbox-expiration/5.1.4:
+    resolution: {integrity: 
sha512-oDO/5iC65h2Eq7jctAv858W2+CeRW5e0jZBMNRXpzp0ZPvuT6GblUiHnAsC5W5lANs1QS9atVOm4ifrBiYY7AQ==}
+    dependencies:
+      workbox-core: 5.1.4
+    dev: true
+
   /workbox-expiration/6.4.2:
     resolution: {integrity: 
sha512-0hbpBj0tDnW+DZOUmwZqntB/8xrXOgO34i7s00Si/VlFJvvpRKg1leXdHHU8ykoSBd6+F2KDcMP3swoCi5guLw==}
     dependencies:
@@ -14016,6 +27478,15 @@ packages:
       workbox-core: 6.4.2
     dev: true
 
+  /workbox-google-analytics/5.1.4:
+    resolution: {integrity: 
sha512-0IFhKoEVrreHpKgcOoddV+oIaVXBFKXUzJVBI+nb0bxmcwYuZMdteBTp8AEDJacENtc9xbR0wa9RDCnYsCDLjA==}
+    dependencies:
+      workbox-background-sync: 5.1.4
+      workbox-core: 5.1.4
+      workbox-routing: 5.1.4
+      workbox-strategies: 5.1.4
+    dev: true
+
   /workbox-google-analytics/6.4.2:
     resolution: {integrity: 
sha512-u+gxs3jXovPb1oul4CTBOb+T9fS1oZG+ZE6AzS7l40vnyfJV79DaLBvlpEZfXGv3CjMdV1sT/ltdOrKzo7HcGw==}
     dependencies:
@@ -14025,12 +27496,24 @@ packages:
       workbox-strategies: 6.4.2
     dev: true
 
+  /workbox-navigation-preload/5.1.4:
+    resolution: {integrity: 
sha512-Wf03osvK0wTflAfKXba//QmWC5BIaIZARU03JIhAEO2wSB2BDROWI8Q/zmianf54kdV7e1eLaIEZhth4K4MyfQ==}
+    dependencies:
+      workbox-core: 5.1.4
+    dev: true
+
   /workbox-navigation-preload/6.4.2:
     resolution: {integrity: 
sha512-viyejlCtlKsbJCBHwhSBbWc57MwPXvUrc8P7d+87AxBGPU+JuWkT6nvBANgVgFz6FUhCvRC8aYt+B1helo166g==}
     dependencies:
       workbox-core: 6.4.2
     dev: true
 
+  /workbox-precaching/5.1.4:
+    resolution: {integrity: 
sha512-gCIFrBXmVQLFwvAzuGLCmkUYGVhBb7D1k/IL7pUJUO5xacjLcFUaLnnsoVepBGAiKw34HU1y/YuqvTKim9qAZA==}
+    dependencies:
+      workbox-core: 5.1.4
+    dev: true
+
   /workbox-precaching/6.4.2:
     resolution: {integrity: 
sha512-CZ6uwFN/2wb4noHVlALL7UqPFbLfez/9S2GAzGAb0Sk876ul9ukRKPJJ6gtsxfE2HSTwqwuyNVa6xWyeyJ1XSA==}
     dependencies:
@@ -14039,6 +27522,12 @@ packages:
       workbox-strategies: 6.4.2
     dev: true
 
+  /workbox-range-requests/5.1.4:
+    resolution: {integrity: 
sha512-1HSujLjgTeoxHrMR2muDW2dKdxqCGMc1KbeyGcmjZZAizJTFwu7CWLDmLv6O1ceWYrhfuLFJO+umYMddk2XMhw==}
+    dependencies:
+      workbox-core: 5.1.4
+    dev: true
+
   /workbox-range-requests/6.4.2:
     resolution: {integrity: 
sha512-SowF3z69hr3Po/w7+xarWfzxJX/3Fo0uSG72Zg4g5FWWnHpq2zPvgbWerBZIa81zpJVUdYpMa3akJJsv+LaO1Q==}
     dependencies:
@@ -14056,18 +27545,38 @@ packages:
       workbox-strategies: 6.4.2
     dev: true
 
+  /workbox-routing/5.1.4:
+    resolution: {integrity: 
sha512-8ljknRfqE1vEQtnMtzfksL+UXO822jJlHTIR7+BtJuxQ17+WPZfsHqvk1ynR/v0EHik4x2+826Hkwpgh4GKDCw==}
+    dependencies:
+      workbox-core: 5.1.4
+    dev: true
+
   /workbox-routing/6.4.2:
     resolution: {integrity: 
sha512-0ss/n9PAcHjTy4Ad7l2puuod4WtsnRYu9BrmHcu6Dk4PgWeJo1t5VnGufPxNtcuyPGQ3OdnMdlmhMJ57sSrrSw==}
     dependencies:
       workbox-core: 6.4.2
     dev: true
 
+  /workbox-strategies/5.1.4:
+    resolution: {integrity: 
sha512-VVS57LpaJTdjW3RgZvPwX0NlhNmscR7OQ9bP+N/34cYMDzXLyA6kqWffP6QKXSkca1OFo/v6v7hW7zrrguo6EA==}
+    dependencies:
+      workbox-core: 5.1.4
+      workbox-routing: 5.1.4
+    dev: true
+
   /workbox-strategies/6.4.2:
     resolution: {integrity: 
sha512-YXh9E9dZGEO1EiPC3jPe2CbztO5WT8Ruj8wiYZM56XqEJp5YlGTtqRjghV+JovWOqkWdR+amJpV31KPWQUvn1Q==}
     dependencies:
       workbox-core: 6.4.2
     dev: true
 
+  /workbox-streams/5.1.4:
+    resolution: {integrity: 
sha512-xU8yuF1hI/XcVhJUAfbQLa1guQUhdLMPQJkdT0kn6HP5CwiPOGiXnSFq80rAG4b1kJUChQQIGPrq439FQUNVrw==}
+    dependencies:
+      workbox-core: 5.1.4
+      workbox-routing: 5.1.4
+    dev: true
+
   /workbox-streams/6.4.2:
     resolution: {integrity: 
sha512-ROEGlZHGVEgpa5bOZefiJEVsi5PsFjJG9Xd+wnDbApsCO9xq9rYFopF+IRq9tChyYzhBnyk2hJxbQVWphz3sog==}
     dependencies:
@@ -14075,10 +27584,31 @@ packages:
       workbox-routing: 6.4.2
     dev: true
 
+  /workbox-sw/5.1.4:
+    resolution: {integrity: 
sha512-9xKnKw95aXwSNc8kk8gki4HU0g0W6KXu+xks7wFuC7h0sembFnTrKtckqZxbSod41TDaGh+gWUA5IRXrL0ECRA==}
+    dev: true
+
   /workbox-sw/6.4.2:
     resolution: {integrity: 
sha512-A2qdu9TLktfIM5NE/8+yYwfWu+JgDaCkbo5ikrky2c7r9v2X6DcJ+zSLphNHHLwM/0eVk5XVf1mC5HGhYpMhhg==}
     dev: true
 
+  /workbox-webpack-plugin/5.1.4_webpack@4.46.0:
+    resolution: {integrity: 
sha512-PZafF4HpugZndqISi3rZ4ZK4A4DxO8rAqt2FwRptgsDx7NF8TVKP86/huHquUsRjMGQllsNdn4FNl8CD/UvKmQ==}
+    engines: {node: '>=8.0.0'}
+    peerDependencies:
+      webpack: ^4.0.0
+    dependencies:
+      '@babel/runtime': 7.17.8
+      fast-json-stable-stringify: 2.1.0
+      source-map-url: 0.4.1
+      upath: 1.2.0
+      webpack: 4.46.0
+      webpack-sources: 1.4.3
+      workbox-build: 5.1.4
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /workbox-webpack-plugin/6.4.2_webpack@4.46.0:
     resolution: {integrity: 
sha512-CiEwM6kaJRkx1cP5xHksn13abTzUqMHiMMlp5Eh/v4wRcedgDTyv6Uo8+Hg9MurRbHDosO5suaPyF9uwVr4/CQ==}
     engines: {node: '>=10.0.0'}
@@ -14097,6 +27627,12 @@ packages:
       - supports-color
     dev: true
 
+  /workbox-window/5.1.4:
+    resolution: {integrity: 
sha512-vXQtgTeMCUq/4pBWMfQX8Ee7N2wVC4Q7XYFqLnfbXJ2hqew/cU1uMTD2KqGEgEpE4/30luxIxgE+LkIa8glBYw==}
+    dependencies:
+      workbox-core: 5.1.4
+    dev: true
+
   /workbox-window/6.4.2:
     resolution: {integrity: 
sha512-KVyRKmrJg7iB+uym/B/CnEUEFG9CvnTU1Bq5xpXHbtgD9l+ShDekSl1wYpqw/O0JfeeQVOFb8CiNfvnwWwqnWQ==}
     dependencies:
@@ -14120,6 +27656,15 @@ packages:
     resolution: {integrity: 
sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==}
     dev: true
 
+  /wrap-ansi/5.1.0:
+    resolution: {integrity: 
sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==}
+    engines: {node: '>=6'}
+    dependencies:
+      ansi-styles: 3.2.1
+      string-width: 3.1.0
+      strip-ansi: 5.2.0
+    dev: true
+
   /wrap-ansi/6.2.0:
     resolution: {integrity: 
sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
     engines: {node: '>=8'}
@@ -14210,6 +27755,13 @@ packages:
         optional: true
     dev: true
 
+  /x-default-browser/0.4.0:
+    resolution: {integrity: 
sha512-7LKo7RtWfoFN/rHx1UELv/2zHGMx8MkZKDq1xENmOCTkfIqZJ0zZ26NEJX8czhnPXVcqS0ARjjfJB+eJ0/5Cvw==}
+    hasBin: true
+    optionalDependencies:
+      default-browser-id: 1.0.4
+    dev: true
+
   /xdg-basedir/4.0.0:
     resolution: {integrity: 
sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==}
     engines: {node: '>=8'}
@@ -14238,7 +27790,7 @@ packages:
     dev: true
 
   /yallist/2.1.2:
-    resolution: {integrity: sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=}
+    resolution: {integrity: 
sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==}
     dev: true
 
   /yallist/3.1.1:
@@ -14254,6 +27806,13 @@ packages:
     engines: {node: '>= 6'}
     dev: true
 
+  /yargs-parser/13.1.2:
+    resolution: {integrity: 
sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==}
+    dependencies:
+      camelcase: 5.3.1
+      decamelize: 1.2.0
+    dev: true
+
   /yargs-parser/18.1.3:
     resolution: {integrity: 
sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==}
     engines: {node: '>=6'}
@@ -14287,6 +27846,21 @@ packages:
       is-plain-obj: 2.1.0
     dev: true
 
+  /yargs/13.3.2:
+    resolution: {integrity: 
sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==}
+    dependencies:
+      cliui: 5.0.0
+      find-up: 3.0.0
+      get-caller-file: 2.0.5
+      require-directory: 2.1.1
+      require-main-filename: 2.0.0
+      set-blocking: 2.0.0
+      string-width: 3.1.0
+      which-module: 2.0.0
+      y18n: 4.0.3
+      yargs-parser: 13.1.2
+    dev: true
+
   /yargs/15.4.1:
     resolution: {integrity: 
sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==}
     engines: {node: '>=8'}
@@ -14339,3 +27913,20 @@ packages:
     resolution: {integrity: 
sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==}
     engines: {node: '>=12.20'}
     dev: true
+
+  /yup/0.32.11:
+    resolution: {integrity: 
sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==}
+    engines: {node: '>=10'}
+    dependencies:
+      '@babel/runtime': 7.17.8
+      '@types/lodash': 4.14.186
+      lodash: 4.17.21
+      lodash-es: 4.17.21
+      nanoclone: 0.2.1
+      property-expr: 2.0.5
+      toposort: 2.0.2
+    dev: false
+
+  /zwitch/1.0.5:
+    resolution: {integrity: 
sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==}
+    dev: true

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]