[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-wallet-core] 02/02: repo: integrate packages from former merchant
From: |
gnunet |
Subject: |
[taler-wallet-core] 02/02: repo: integrate packages from former merchant-backoffice.git |
Date: |
Mon, 24 Oct 2022 10:46:20 +0200 |
This is an automated email from the git hooks/post-receive script.
dold pushed a commit to branch master
in repository wallet-core.
commit 3e060b80428943c6562250a6ff77eff10a0259b7
Author: Florian Dold <florian@dold.me>
AuthorDate: Mon Oct 24 10:46:14 2022 +0200
repo: integrate packages from former merchant-backoffice.git
---
packages/demobank-ui/.gitignore | 5 +
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 +
packages/demobank-ui/contrib/po2ts | 42 +
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 +
packages/demobank-ui/src/assets/empty.png | Bin 0 -> 2785 bytes
packages/demobank-ui/src/assets/example/id1.jpg | Bin 0 -> 103558 bytes
packages/demobank-ui/src/assets/favicon.ico | Bin 0 -> 15086 bytes
.../src/assets/icons/android-chrome-192x192.png | Bin 0 -> 14058 bytes
.../src/assets/icons/android-chrome-512x512.png | Bin 0 -> 51484 bytes
.../src/assets/icons/apple-touch-icon.png | Bin 0 -> 12746 bytes
.../src/assets/icons/auth_method/email.svg | 1 +
.../src/assets/icons/auth_method/postal.svg | 1 +
.../src/assets/icons/auth_method/question.svg | 1 +
.../src/assets/icons/auth_method/sms.svg | 1 +
.../src/assets/icons/auth_method/video.svg | 1 +
.../demobank-ui/src/assets/icons/favicon-16x16.png | Bin 0 -> 626 bytes
.../demobank-ui/src/assets/icons/favicon-32x32.png | Bin 0 -> 1487 bytes
.../demobank-ui/src/assets/icons/languageicon.svg | 48 +
.../src/assets/icons/mstile-150x150.png | Bin 0 -> 9050 bytes
packages/demobank-ui/src/assets/logo-white.svg | 45 +
packages/demobank-ui/src/assets/logo.jpeg | Bin 0 -> 39336 bytes
.../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 +
packages/demobank-ui/src/pages/notfound/style.css | 0
.../src/pages/profile/index.stories.tsx | 38 +
packages/demobank-ui/src/pages/profile/index.tsx | 42 +
packages/demobank-ui/src/pages/profile/style.css | 0
packages/demobank-ui/src/scss/DurationPicker.scss | 70 +
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 0 -> 43752 bytes
packages/demobank-ui/src/scss/fonts/nunito.css | 22 +
.../fonts/materialdesignicons-webfont-4.9.95.eot | Bin 0 -> 844600 bytes
.../fonts/materialdesignicons-webfont-4.9.95.ttf | Bin 0 -> 844380 bytes
.../fonts/materialdesignicons-webfont-4.9.95.woff | Bin 0 -> 404384 bytes
.../fonts/materialdesignicons-webfont-4.9.95.woff2 | Bin 0 -> 283040 bytes
.../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 ++
packages/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 +
packages/merchant-backend-ui/contrib/po2ts | 42 +
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 +
packages/merchant-backend-ui/src/assets/empty.png | Bin 0 -> 2785 bytes
.../src/assets/icons/android-chrome-192x192.png | Bin 0 -> 14058 bytes
.../src/assets/icons/android-chrome-512x512.png | Bin 0 -> 51484 bytes
.../src/assets/icons/apple-touch-icon.png | Bin 0 -> 12746 bytes
.../src/assets/icons/favicon-16x16.png | Bin 0 -> 626 bytes
.../src/assets/icons/favicon-32x32.png | Bin 0 -> 1487 bytes
.../src/assets/icons/languageicon.svg | 48 +
.../src/assets/icons/mstile-150x150.png | Bin 0 -> 9050 bytes
.../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 +
packages/merchant-backoffice-ui/contrib/po2ts | 42 +
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 +
.../merchant-backoffice-ui/src/assets/empty.png | Bin 0 -> 2785 bytes
.../src/assets/icons/android-chrome-192x192.png | Bin 0 -> 14058 bytes
.../src/assets/icons/android-chrome-512x512.png | Bin 0 -> 51484 bytes
.../src/assets/icons/apple-touch-icon.png | Bin 0 -> 12746 bytes
.../src/assets/icons/favicon-16x16.png | Bin 0 -> 626 bytes
.../src/assets/icons/favicon-32x32.png | Bin 0 -> 1487 bytes
.../src/assets/icons/languageicon.svg | 48 +
.../src/assets/icons/mstile-150x150.png | Bin 0 -> 9050 bytes
.../merchant-backoffice-ui/src/assets/logo.jpeg | Bin 0 -> 39336 bytes
.../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 0 -> 43752 bytes
.../src/scss/fonts/nunito.css | 22 +
.../fonts/materialdesignicons-webfont-4.9.95.eot | Bin 0 -> 844600 bytes
.../fonts/materialdesignicons-webfont-4.9.95.ttf | Bin 0 -> 844380 bytes
.../fonts/materialdesignicons-webfont-4.9.95.woff | Bin 0 -> 404384 bytes
.../fonts/materialdesignicons-webfont-4.9.95.woff2 | Bin 0 -> 283040 bytes
.../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 +
pnpm-lock.yaml | 23139 +++++++++++++++----
402 files changed, 82573 insertions(+), 4774 deletions(-)
diff --git a/packages/demobank-ui/.gitignore b/packages/demobank-ui/.gitignore
new file mode 100644
index 000000000..32d0a5057
--- /dev/null
+++ b/packages/demobank-ui/.gitignore
@@ -0,0 +1,5 @@
+node_modules
+/build
+/*.log
+/size-plugin.json
+/storybook-static/
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/packages/demobank-ui/contrib/po2ts
b/packages/demobank-ui/contrib/po2ts
new file mode 100755
index 000000000..a135da61b
--- /dev/null
+++ b/packages/demobank-ui/contrib/po2ts
@@ -0,0 +1,42 @@
+#!/usr/bin/env node
+/*
+ This file is part of GNU Taler
+ (C) 2020 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ * Convert a <lang>.po file into a JavaScript / TypeScript expression.
+ */
+
+const po2json = require("po2json");
+
+const filename = process.argv[2];
+
+if (!filename) {
+ console.error("error: missing filename");
+ process.exit(1);
+}
+
+const m = filename.match(/([a-zA-Z0-9-_]+).po/);
+
+if (!m) {
+ console.error("error: unexpected filename (expected <lang>.po)");
+ process.exit(1);
+}
+
+const lang = m[1];
+const pojson = po2json.parseFileSync(filename, { format: "jed1.x", fuzzy: true
});
+const s =
+ "strings['" + lang + "'] = " + JSON.stringify(pojson, null, " ") + ";\n";
+console.log(s);
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/demobank-ui/src/assets/empty.png
b/packages/demobank-ui/src/assets/empty.png
new file mode 100644
index 000000000..5120d3138
Binary files /dev/null and b/packages/demobank-ui/src/assets/empty.png differ
diff --git a/packages/demobank-ui/src/assets/example/id1.jpg
b/packages/demobank-ui/src/assets/example/id1.jpg
new file mode 100644
index 000000000..5d022a379
Binary files /dev/null and b/packages/demobank-ui/src/assets/example/id1.jpg
differ
diff --git a/packages/demobank-ui/src/assets/favicon.ico
b/packages/demobank-ui/src/assets/favicon.ico
new file mode 100644
index 000000000..07419145b
Binary files /dev/null and b/packages/demobank-ui/src/assets/favicon.ico differ
diff --git a/packages/demobank-ui/src/assets/icons/android-chrome-192x192.png
b/packages/demobank-ui/src/assets/icons/android-chrome-192x192.png
new file mode 100644
index 000000000..93ebe2e2c
Binary files /dev/null and
b/packages/demobank-ui/src/assets/icons/android-chrome-192x192.png differ
diff --git a/packages/demobank-ui/src/assets/icons/android-chrome-512x512.png
b/packages/demobank-ui/src/assets/icons/android-chrome-512x512.png
new file mode 100644
index 000000000..52d1623ea
Binary files /dev/null and
b/packages/demobank-ui/src/assets/icons/android-chrome-512x512.png differ
diff --git a/packages/demobank-ui/src/assets/icons/apple-touch-icon.png
b/packages/demobank-ui/src/assets/icons/apple-touch-icon.png
new file mode 100644
index 000000000..254e4bb4d
Binary files /dev/null and
b/packages/demobank-ui/src/assets/icons/apple-touch-icon.png differ
diff --git a/packages/demobank-ui/src/assets/icons/auth_method/email.svg
b/packages/demobank-ui/src/assets/icons/auth_method/email.svg
new file mode 100644
index 000000000..3e44b8779
--- /dev/null
+++ b/packages/demobank-ui/src/assets/icons/auth_method/email.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24"
width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M22
6c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6zm-2
0l-8 5-8-5h16zm0 12H4V8l8 5 8-5v10z"/></svg>
\ No newline at end of file
diff --git a/packages/demobank-ui/src/assets/icons/auth_method/postal.svg
b/packages/demobank-ui/src/assets/icons/auth_method/postal.svg
new file mode 100644
index 000000000..3787b8350
--- /dev/null
+++ b/packages/demobank-ui/src/assets/icons/auth_method/postal.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24"
width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M17
15h2v2h-2zM17 11h2v2h-2zM17 7h2v2h-2zM13.74 7l1.26.84V7z"/><path d="M10
3v1.51l2 1.33V5h9v14h-4v2h6V3z"/><path d="M8.17 5.7L15 10.25V21H1V10.48L8.17
5.7zM10 19h3v-7.84L8.17 8.09 3 11.38V19h3v-6h4v6z"/></svg>
\ No newline at end of file
diff --git a/packages/demobank-ui/src/assets/icons/auth_method/question.svg
b/packages/demobank-ui/src/assets/icons/auth_method/question.svg
new file mode 100644
index 000000000..a346556b2
--- /dev/null
+++ b/packages/demobank-ui/src/assets/icons/auth_method/question.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24"
width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M11
23.59v-3.6c-5.01-.26-9-4.42-9-9.49C2 5.26 6.26 1 11.5 1S21 5.26 21 10.5c0
4.95-3.44 9.93-8.57 12.4l-1.43.69zM11.5 3C7.36 3 4 6.36 4 10.5S7.36 18 11.5
18H13v2.3c3.64-2.3 6-6.08 6-9.8C19 6.36 15.64 3 11.5 3zm-1
11.5h2v2h-2zm2-1.5h-2c0-3.25 3-3 3-5 0-1.1-.9-2-2-2s-2 .9-2 2h-2c0-2.21 1.79-4
4-4s4 1.79 4 4c0 2.5-3 2.75-3 5z"/></svg>
\ No newline at end of file
diff --git a/packages/demobank-ui/src/assets/icons/auth_method/sms.svg
b/packages/demobank-ui/src/assets/icons/auth_method/sms.svg
new file mode 100644
index 000000000..ed15679bf
--- /dev/null
+++ b/packages/demobank-ui/src/assets/icons/auth_method/sms.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24"
width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M17
1.01L7 1c-1.1 0-1.99.9-1.99 2v18c0 1.1.89 2 1.99 2h10c1.1 0 2-.9
2-2V3c0-1.1-.9-1.99-2-1.99zM17 19H7V5h10v14z"/></svg>
\ No newline at end of file
diff --git a/packages/demobank-ui/src/assets/icons/auth_method/video.svg
b/packages/demobank-ui/src/assets/icons/auth_method/video.svg
new file mode 100644
index 000000000..69de5e0b4
--- /dev/null
+++ b/packages/demobank-ui/src/assets/icons/auth_method/video.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24"
height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><rect
fill="none" height="24" width="24"/></g><g><g><path
d="M18,10.48V6c0-1.1-0.9-2-2-2H4C2.9,4,2,4.9,2,6v12c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2v-4.48l4,3.98v-11L18,10.48z
M16,9.69V18H4V6h12V9.69z"/><circle cx="10" cy="10" r="2"/><path
d="M14,15.43c0-0.81-0.48-1.53-1.22-1.85C11.93,13.21,10.99,13,10,13c-0.99,0-1.93,0.21-2.78,0.58C6.48,13.9,6,14.62,6,15
[...]
\ No newline at end of file
diff --git a/packages/demobank-ui/src/assets/icons/favicon-16x16.png
b/packages/demobank-ui/src/assets/icons/favicon-16x16.png
new file mode 100644
index 000000000..e81177dcb
Binary files /dev/null and
b/packages/demobank-ui/src/assets/icons/favicon-16x16.png differ
diff --git a/packages/demobank-ui/src/assets/icons/favicon-32x32.png
b/packages/demobank-ui/src/assets/icons/favicon-32x32.png
new file mode 100644
index 000000000..40e9b5b47
Binary files /dev/null and
b/packages/demobank-ui/src/assets/icons/favicon-32x32.png differ
diff --git a/packages/demobank-ui/src/assets/icons/languageicon.svg
b/packages/demobank-ui/src/assets/icons/languageicon.svg
new file mode 100644
index 000000000..22d58da65
--- /dev/null
+++ b/packages/demobank-ui/src/assets/icons/languageicon.svg
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version:
6.00 Build 0) -->
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 2411.2 2794" style="enable-background:new 0 0 2411.2
2794;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill:#FFFFFF;}
+ .st1{fill-rule:evenodd;clip-rule:evenodd;}
+ .st2{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
+</style>
+<g id="Layer_2">
+</g>
+<g id="Layer_x5F_1_x5F_1">
+ <g>
+ <polygon points="1204.6,359.2 271.8,30 271.8,2060.1
1204.6,1758.3 "/>
+ <polygon class="st0" points="1182.2,358.1 2150.6,29 2150.6,2059
1182.2,1757.3 "/>
+ <polygon class="st0" points="30,2415.4 1182.2,2031.4
1182.2,357.9 30,742 "/>
+ <polygon points="1707.2,2440.7 1870.5,2709.4 1956.6,2459.8
"/>
+ <g>
+ <path
d="M421.7,934.8c-6.1-6,8,49.1,27.6,68.9c34.8,35.1,61.9,39.6,76.4,40.2c32,1.3,71.5-8,94.9-17.8
+
c22.7-9.7,62.4-30,77.5-59.6c3.2-6.3,11.9-17,6.4-43.2c-4.2-20.2-17-27.3-32.7-26.2c-15.7,1.1-63.2,13.7-86.1,20.8
+
c-23,7-70.3,21.4-90.9,25.8C474.3,948.2,429,941.7,421.7,934.8z"/>
+ <path
d="M1003.1,1593.7c-9.1-3.3-196.9-81.1-223.6-93.9c-21.8-10.5-75.2-33.1-100.4-43.3c70.8-109.2,115.5-191.6,121.5-204.1
+
c11-23,86-169.6,87.7-178.7c1.7-9.1,3.8-42.9,2.2-51c-1.7-8.2-29.1,7.6-66.4,20.2c-37.4,12.6-108.4,58.8-135.8,64.6
+
c-27.5,5.7-115.5,39.1-160.5,54c-45,14.9-130.2,40.9-165.2,50.4c-35.1,9.5-65.7,10.2-85.3,16.2c0,0,2.6,27.5,7.8,35.7
+
c5.2,8.2,23.7,28.4,45.3,34.1c21.6,5.7,57.3,3.4,73.6-0.3c16.3-3.8,44.4-17.5,48.2-23.6c3.8-6.1-2-24.9,4.5-30.6
+
c6.5-5.6,92.2-25.7,124.6-35.4c32.4-10,156.3-52.6,173.1-50.5c-5.3,17.7-105,215.1-137.1,274c-32.1,58.9-218.6,318-258.3,363.6
+
c-30.1,34.7-103.2,123.5-128.5,143.6c6.4,1.8,51.6-2.1,59.9-7.2c51.3-31.6,136.9-138.1,164.4-170.5
+
c81.9-96,153.8-196.8,210.8-283.4h0.1c11.1,4.6,100.9,77.8,124.4,94c23.4,16.2,115.9,67.8,136,76.4c20,8.7,97.1,44.2,100.3,32.2
+ C1029.4,1668,1012.2,1597.1,1003.1,1593.7z"/>
+ </g>
+ <path class="st1"
d="M569,2572c18,11,35,20,54,29c38,19,81,39,122,54c56,21,112,38,168,51c31,7,65,13,98,18c3,0,92,11,110,11h90
+
c35-3,68-5,103-10c28-4,59-9,89-16c22-5,45-10,67-17c21-6,45-14,68-22c15-5,31-12,47-18c13-6,29-13,44-19c18-8,39-19,59-29
+
c16-8,34-18,51-28c13-7,43-30,59-30c18,0,30,16,30,30c0,29-39,38-57,51c-19,13-42,23-62,34c-40,21-81,39-120,54
+
c-51,19-107,37-157,49c-19,4-38,9-57,12c-10,2-114,18-143,18h-132c-35-3-72-7-107-12c-31-5-64-11-95-18c-24-5-50-12-73-19
+
c-40-11-79-25-117-40c-69-26-141-60-209-105c-12-8-13-16-13-25c0-15,11-29,29-29C531,2546,563,2569,569,2572z"/>
+ <path class="st1" d="M1151,2009L61,2372V764l1090-363V2009z
M1212,354v1680c-1,5-3,10-7,15c-2,3-6,7-9,8c-25,10-1151,388-1166,388
+
c-12,0-23-8-29-21c0-1-1-2-1-4V739c2-5,3-12,7-16c8-11,22-13,31-16c17-6,1126-378,1142-378C1190,329,1212,336,1212,354z"/>
+ <path class="st1" d="M2120,2017l-907-282V380l907-308V2017z
M2181,32v2023c-1,23-17,33-32,33c-13,0-107-32-123-37
+
c-126-39-253-78-378-117c-28-9-57-18-84-27c-24-7-50-15-74-23c-107-33-216-66-323-102c-4-1-14-15-14-18V351c2-5,4-11,9-15
+
c8-9,351-123,486-168c36-13,487-168,501-168C2167,0,2181,13,2181,32z"/>
+ <polygon points="2411.2,2440.7 1199.5,2054.5 1204.6,373.2
2411.2,757.2 "/>
+ <g>
+ <path class="st2"
d="M1800.3,1124.6L1681.4,1412l218.6,66.3L1800.3,1124.6z
M1729,853.2l156.1,47.3l284.4,1025l-160.3-48.7
+
l-57.6-210.4L1620.2,1566l-71.3,171.4l-160.4-48.7L1729,853.2z"/>
+ </g>
+ </g>
+</g>
+</svg>
diff --git a/packages/demobank-ui/src/assets/icons/mstile-150x150.png
b/packages/demobank-ui/src/assets/icons/mstile-150x150.png
new file mode 100644
index 000000000..9cfb889be
Binary files /dev/null and
b/packages/demobank-ui/src/assets/icons/mstile-150x150.png differ
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/demobank-ui/src/assets/logo.jpeg
b/packages/demobank-ui/src/assets/logo.jpeg
new file mode 100644
index 000000000..489832f7c
Binary files /dev/null and b/packages/demobank-ui/src/assets/logo.jpeg differ
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 © 2014—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>
+ <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>
+ <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>
+ <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(',', '.'),
+ }))
+ }} />
+
+ <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>
+ <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`} <em>{captchaNumbers.a} + {captchaNumbers.b}</em>? </label>
+ <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>
+
+ <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>
+ <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;
+ }} />
+
+ <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> <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't exist.</p>
+ <Link href="/">
+ <h4>Back to Home</h4>
+ </Link>
+ </div>
+ );
+};
+
+export default Notfound;
diff --git a/packages/demobank-ui/src/pages/notfound/style.css
b/packages/demobank-ui/src/pages/notfound/style.css
new file mode 100644
index 000000000..e69de29bb
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/demobank-ui/src/pages/profile/style.css
b/packages/demobank-ui/src/pages/profile/style.css
new file mode 100644
index 000000000..e69de29bb
diff --git a/packages/demobank-ui/src/scss/DurationPicker.scss
b/packages/demobank-ui/src/scss/DurationPicker.scss
new file mode 100644
index 000000000..aa75b9916
--- /dev/null
+++ b/packages/demobank-ui/src/scss/DurationPicker.scss
@@ -0,0 +1,70 @@
+.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/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/demobank-ui/src/scss/fonts/XRXV3I6Li01BKofINeaE.ttf
b/packages/demobank-ui/src/scss/fonts/XRXV3I6Li01BKofINeaE.ttf
new file mode 100644
index 000000000..7665ee336
Binary files /dev/null and
b/packages/demobank-ui/src/scss/fonts/XRXV3I6Li01BKofINeaE.ttf differ
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/demobank-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.eot
b/packages/demobank-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.eot
new file mode 100644
index 000000000..ab6b25ded
Binary files /dev/null and
b/packages/demobank-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.eot
differ
diff --git
a/packages/demobank-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.ttf
b/packages/demobank-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.ttf
new file mode 100644
index 000000000..824be10fa
Binary files /dev/null and
b/packages/demobank-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.ttf
differ
diff --git
a/packages/demobank-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.woff
b/packages/demobank-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.woff
new file mode 100644
index 000000000..7e087c1de
Binary files /dev/null and
b/packages/demobank-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.woff
differ
diff --git
a/packages/demobank-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.woff2
b/packages/demobank-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.woff2
new file mode 100644
index 000000000..b5caa4ddc
Binary files /dev/null and
b/packages/demobank-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.woff2
differ
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/demobank-ui/src/style/index.css
b/packages/demobank-ui/src/style/index.css
new file mode 100644
index 000000000..e69de29bb
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/packages/merchant-backend-ui/contrib/po2ts
b/packages/merchant-backend-ui/contrib/po2ts
new file mode 100755
index 000000000..a135da61b
--- /dev/null
+++ b/packages/merchant-backend-ui/contrib/po2ts
@@ -0,0 +1,42 @@
+#!/usr/bin/env node
+/*
+ This file is part of GNU Taler
+ (C) 2020 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ * Convert a <lang>.po file into a JavaScript / TypeScript expression.
+ */
+
+const po2json = require("po2json");
+
+const filename = process.argv[2];
+
+if (!filename) {
+ console.error("error: missing filename");
+ process.exit(1);
+}
+
+const m = filename.match(/([a-zA-Z0-9-_]+).po/);
+
+if (!m) {
+ console.error("error: unexpected filename (expected <lang>.po)");
+ process.exit(1);
+}
+
+const lang = m[1];
+const pojson = po2json.parseFileSync(filename, { format: "jed1.x", fuzzy: true
});
+const s =
+ "strings['" + lang + "'] = " + JSON.stringify(pojson, null, " ") + ";\n";
+console.log(s);
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/merchant-backend-ui/src/assets/empty.png
b/packages/merchant-backend-ui/src/assets/empty.png
new file mode 100644
index 000000000..5120d3138
Binary files /dev/null and b/packages/merchant-backend-ui/src/assets/empty.png
differ
diff --git
a/packages/merchant-backend-ui/src/assets/icons/android-chrome-192x192.png
b/packages/merchant-backend-ui/src/assets/icons/android-chrome-192x192.png
new file mode 100644
index 000000000..93ebe2e2c
Binary files /dev/null and
b/packages/merchant-backend-ui/src/assets/icons/android-chrome-192x192.png
differ
diff --git
a/packages/merchant-backend-ui/src/assets/icons/android-chrome-512x512.png
b/packages/merchant-backend-ui/src/assets/icons/android-chrome-512x512.png
new file mode 100644
index 000000000..52d1623ea
Binary files /dev/null and
b/packages/merchant-backend-ui/src/assets/icons/android-chrome-512x512.png
differ
diff --git a/packages/merchant-backend-ui/src/assets/icons/apple-touch-icon.png
b/packages/merchant-backend-ui/src/assets/icons/apple-touch-icon.png
new file mode 100644
index 000000000..254e4bb4d
Binary files /dev/null and
b/packages/merchant-backend-ui/src/assets/icons/apple-touch-icon.png differ
diff --git a/packages/merchant-backend-ui/src/assets/icons/favicon-16x16.png
b/packages/merchant-backend-ui/src/assets/icons/favicon-16x16.png
new file mode 100644
index 000000000..e81177dcb
Binary files /dev/null and
b/packages/merchant-backend-ui/src/assets/icons/favicon-16x16.png differ
diff --git a/packages/merchant-backend-ui/src/assets/icons/favicon-32x32.png
b/packages/merchant-backend-ui/src/assets/icons/favicon-32x32.png
new file mode 100644
index 000000000..40e9b5b47
Binary files /dev/null and
b/packages/merchant-backend-ui/src/assets/icons/favicon-32x32.png differ
diff --git a/packages/merchant-backend-ui/src/assets/icons/languageicon.svg
b/packages/merchant-backend-ui/src/assets/icons/languageicon.svg
new file mode 100644
index 000000000..22d58da65
--- /dev/null
+++ b/packages/merchant-backend-ui/src/assets/icons/languageicon.svg
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version:
6.00 Build 0) -->
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 2411.2 2794" style="enable-background:new 0 0 2411.2
2794;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill:#FFFFFF;}
+ .st1{fill-rule:evenodd;clip-rule:evenodd;}
+ .st2{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
+</style>
+<g id="Layer_2">
+</g>
+<g id="Layer_x5F_1_x5F_1">
+ <g>
+ <polygon points="1204.6,359.2 271.8,30 271.8,2060.1
1204.6,1758.3 "/>
+ <polygon class="st0" points="1182.2,358.1 2150.6,29 2150.6,2059
1182.2,1757.3 "/>
+ <polygon class="st0" points="30,2415.4 1182.2,2031.4
1182.2,357.9 30,742 "/>
+ <polygon points="1707.2,2440.7 1870.5,2709.4 1956.6,2459.8
"/>
+ <g>
+ <path
d="M421.7,934.8c-6.1-6,8,49.1,27.6,68.9c34.8,35.1,61.9,39.6,76.4,40.2c32,1.3,71.5-8,94.9-17.8
+
c22.7-9.7,62.4-30,77.5-59.6c3.2-6.3,11.9-17,6.4-43.2c-4.2-20.2-17-27.3-32.7-26.2c-15.7,1.1-63.2,13.7-86.1,20.8
+
c-23,7-70.3,21.4-90.9,25.8C474.3,948.2,429,941.7,421.7,934.8z"/>
+ <path
d="M1003.1,1593.7c-9.1-3.3-196.9-81.1-223.6-93.9c-21.8-10.5-75.2-33.1-100.4-43.3c70.8-109.2,115.5-191.6,121.5-204.1
+
c11-23,86-169.6,87.7-178.7c1.7-9.1,3.8-42.9,2.2-51c-1.7-8.2-29.1,7.6-66.4,20.2c-37.4,12.6-108.4,58.8-135.8,64.6
+
c-27.5,5.7-115.5,39.1-160.5,54c-45,14.9-130.2,40.9-165.2,50.4c-35.1,9.5-65.7,10.2-85.3,16.2c0,0,2.6,27.5,7.8,35.7
+
c5.2,8.2,23.7,28.4,45.3,34.1c21.6,5.7,57.3,3.4,73.6-0.3c16.3-3.8,44.4-17.5,48.2-23.6c3.8-6.1-2-24.9,4.5-30.6
+
c6.5-5.6,92.2-25.7,124.6-35.4c32.4-10,156.3-52.6,173.1-50.5c-5.3,17.7-105,215.1-137.1,274c-32.1,58.9-218.6,318-258.3,363.6
+
c-30.1,34.7-103.2,123.5-128.5,143.6c6.4,1.8,51.6-2.1,59.9-7.2c51.3-31.6,136.9-138.1,164.4-170.5
+
c81.9-96,153.8-196.8,210.8-283.4h0.1c11.1,4.6,100.9,77.8,124.4,94c23.4,16.2,115.9,67.8,136,76.4c20,8.7,97.1,44.2,100.3,32.2
+ C1029.4,1668,1012.2,1597.1,1003.1,1593.7z"/>
+ </g>
+ <path class="st1"
d="M569,2572c18,11,35,20,54,29c38,19,81,39,122,54c56,21,112,38,168,51c31,7,65,13,98,18c3,0,92,11,110,11h90
+
c35-3,68-5,103-10c28-4,59-9,89-16c22-5,45-10,67-17c21-6,45-14,68-22c15-5,31-12,47-18c13-6,29-13,44-19c18-8,39-19,59-29
+
c16-8,34-18,51-28c13-7,43-30,59-30c18,0,30,16,30,30c0,29-39,38-57,51c-19,13-42,23-62,34c-40,21-81,39-120,54
+
c-51,19-107,37-157,49c-19,4-38,9-57,12c-10,2-114,18-143,18h-132c-35-3-72-7-107-12c-31-5-64-11-95-18c-24-5-50-12-73-19
+
c-40-11-79-25-117-40c-69-26-141-60-209-105c-12-8-13-16-13-25c0-15,11-29,29-29C531,2546,563,2569,569,2572z"/>
+ <path class="st1" d="M1151,2009L61,2372V764l1090-363V2009z
M1212,354v1680c-1,5-3,10-7,15c-2,3-6,7-9,8c-25,10-1151,388-1166,388
+
c-12,0-23-8-29-21c0-1-1-2-1-4V739c2-5,3-12,7-16c8-11,22-13,31-16c17-6,1126-378,1142-378C1190,329,1212,336,1212,354z"/>
+ <path class="st1" d="M2120,2017l-907-282V380l907-308V2017z
M2181,32v2023c-1,23-17,33-32,33c-13,0-107-32-123-37
+
c-126-39-253-78-378-117c-28-9-57-18-84-27c-24-7-50-15-74-23c-107-33-216-66-323-102c-4-1-14-15-14-18V351c2-5,4-11,9-15
+
c8-9,351-123,486-168c36-13,487-168,501-168C2167,0,2181,13,2181,32z"/>
+ <polygon points="2411.2,2440.7 1199.5,2054.5 1204.6,373.2
2411.2,757.2 "/>
+ <g>
+ <path class="st2"
d="M1800.3,1124.6L1681.4,1412l218.6,66.3L1800.3,1124.6z
M1729,853.2l156.1,47.3l284.4,1025l-160.3-48.7
+
l-57.6-210.4L1620.2,1566l-71.3,171.4l-160.4-48.7L1729,853.2z"/>
+ </g>
+ </g>
+</g>
+</svg>
diff --git a/packages/merchant-backend-ui/src/assets/icons/mstile-150x150.png
b/packages/merchant-backend-ui/src/assets/icons/mstile-150x150.png
new file mode 100644
index 000000000..9cfb889be
Binary files /dev/null and
b/packages/merchant-backend-ui/src/assets/icons/mstile-150x150.png differ
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 © 2014—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/packages/merchant-backoffice-ui/contrib/po2ts
b/packages/merchant-backoffice-ui/contrib/po2ts
new file mode 100755
index 000000000..a135da61b
--- /dev/null
+++ b/packages/merchant-backoffice-ui/contrib/po2ts
@@ -0,0 +1,42 @@
+#!/usr/bin/env node
+/*
+ This file is part of GNU Taler
+ (C) 2020 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ * Convert a <lang>.po file into a JavaScript / TypeScript expression.
+ */
+
+const po2json = require("po2json");
+
+const filename = process.argv[2];
+
+if (!filename) {
+ console.error("error: missing filename");
+ process.exit(1);
+}
+
+const m = filename.match(/([a-zA-Z0-9-_]+).po/);
+
+if (!m) {
+ console.error("error: unexpected filename (expected <lang>.po)");
+ process.exit(1);
+}
+
+const lang = m[1];
+const pojson = po2json.parseFileSync(filename, { format: "jed1.x", fuzzy: true
});
+const s =
+ "strings['" + lang + "'] = " + JSON.stringify(pojson, null, " ") + ";\n";
+console.log(s);
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/merchant-backoffice-ui/src/assets/empty.png
b/packages/merchant-backoffice-ui/src/assets/empty.png
new file mode 100644
index 000000000..5120d3138
Binary files /dev/null and
b/packages/merchant-backoffice-ui/src/assets/empty.png differ
diff --git
a/packages/merchant-backoffice-ui/src/assets/icons/android-chrome-192x192.png
b/packages/merchant-backoffice-ui/src/assets/icons/android-chrome-192x192.png
new file mode 100644
index 000000000..93ebe2e2c
Binary files /dev/null and
b/packages/merchant-backoffice-ui/src/assets/icons/android-chrome-192x192.png
differ
diff --git
a/packages/merchant-backoffice-ui/src/assets/icons/android-chrome-512x512.png
b/packages/merchant-backoffice-ui/src/assets/icons/android-chrome-512x512.png
new file mode 100644
index 000000000..52d1623ea
Binary files /dev/null and
b/packages/merchant-backoffice-ui/src/assets/icons/android-chrome-512x512.png
differ
diff --git
a/packages/merchant-backoffice-ui/src/assets/icons/apple-touch-icon.png
b/packages/merchant-backoffice-ui/src/assets/icons/apple-touch-icon.png
new file mode 100644
index 000000000..254e4bb4d
Binary files /dev/null and
b/packages/merchant-backoffice-ui/src/assets/icons/apple-touch-icon.png differ
diff --git a/packages/merchant-backoffice-ui/src/assets/icons/favicon-16x16.png
b/packages/merchant-backoffice-ui/src/assets/icons/favicon-16x16.png
new file mode 100644
index 000000000..e81177dcb
Binary files /dev/null and
b/packages/merchant-backoffice-ui/src/assets/icons/favicon-16x16.png differ
diff --git a/packages/merchant-backoffice-ui/src/assets/icons/favicon-32x32.png
b/packages/merchant-backoffice-ui/src/assets/icons/favicon-32x32.png
new file mode 100644
index 000000000..40e9b5b47
Binary files /dev/null and
b/packages/merchant-backoffice-ui/src/assets/icons/favicon-32x32.png differ
diff --git a/packages/merchant-backoffice-ui/src/assets/icons/languageicon.svg
b/packages/merchant-backoffice-ui/src/assets/icons/languageicon.svg
new file mode 100644
index 000000000..22d58da65
--- /dev/null
+++ b/packages/merchant-backoffice-ui/src/assets/icons/languageicon.svg
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version:
6.00 Build 0) -->
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 2411.2 2794" style="enable-background:new 0 0 2411.2
2794;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill:#FFFFFF;}
+ .st1{fill-rule:evenodd;clip-rule:evenodd;}
+ .st2{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
+</style>
+<g id="Layer_2">
+</g>
+<g id="Layer_x5F_1_x5F_1">
+ <g>
+ <polygon points="1204.6,359.2 271.8,30 271.8,2060.1
1204.6,1758.3 "/>
+ <polygon class="st0" points="1182.2,358.1 2150.6,29 2150.6,2059
1182.2,1757.3 "/>
+ <polygon class="st0" points="30,2415.4 1182.2,2031.4
1182.2,357.9 30,742 "/>
+ <polygon points="1707.2,2440.7 1870.5,2709.4 1956.6,2459.8
"/>
+ <g>
+ <path
d="M421.7,934.8c-6.1-6,8,49.1,27.6,68.9c34.8,35.1,61.9,39.6,76.4,40.2c32,1.3,71.5-8,94.9-17.8
+
c22.7-9.7,62.4-30,77.5-59.6c3.2-6.3,11.9-17,6.4-43.2c-4.2-20.2-17-27.3-32.7-26.2c-15.7,1.1-63.2,13.7-86.1,20.8
+
c-23,7-70.3,21.4-90.9,25.8C474.3,948.2,429,941.7,421.7,934.8z"/>
+ <path
d="M1003.1,1593.7c-9.1-3.3-196.9-81.1-223.6-93.9c-21.8-10.5-75.2-33.1-100.4-43.3c70.8-109.2,115.5-191.6,121.5-204.1
+
c11-23,86-169.6,87.7-178.7c1.7-9.1,3.8-42.9,2.2-51c-1.7-8.2-29.1,7.6-66.4,20.2c-37.4,12.6-108.4,58.8-135.8,64.6
+
c-27.5,5.7-115.5,39.1-160.5,54c-45,14.9-130.2,40.9-165.2,50.4c-35.1,9.5-65.7,10.2-85.3,16.2c0,0,2.6,27.5,7.8,35.7
+
c5.2,8.2,23.7,28.4,45.3,34.1c21.6,5.7,57.3,3.4,73.6-0.3c16.3-3.8,44.4-17.5,48.2-23.6c3.8-6.1-2-24.9,4.5-30.6
+
c6.5-5.6,92.2-25.7,124.6-35.4c32.4-10,156.3-52.6,173.1-50.5c-5.3,17.7-105,215.1-137.1,274c-32.1,58.9-218.6,318-258.3,363.6
+
c-30.1,34.7-103.2,123.5-128.5,143.6c6.4,1.8,51.6-2.1,59.9-7.2c51.3-31.6,136.9-138.1,164.4-170.5
+
c81.9-96,153.8-196.8,210.8-283.4h0.1c11.1,4.6,100.9,77.8,124.4,94c23.4,16.2,115.9,67.8,136,76.4c20,8.7,97.1,44.2,100.3,32.2
+ C1029.4,1668,1012.2,1597.1,1003.1,1593.7z"/>
+ </g>
+ <path class="st1"
d="M569,2572c18,11,35,20,54,29c38,19,81,39,122,54c56,21,112,38,168,51c31,7,65,13,98,18c3,0,92,11,110,11h90
+
c35-3,68-5,103-10c28-4,59-9,89-16c22-5,45-10,67-17c21-6,45-14,68-22c15-5,31-12,47-18c13-6,29-13,44-19c18-8,39-19,59-29
+
c16-8,34-18,51-28c13-7,43-30,59-30c18,0,30,16,30,30c0,29-39,38-57,51c-19,13-42,23-62,34c-40,21-81,39-120,54
+
c-51,19-107,37-157,49c-19,4-38,9-57,12c-10,2-114,18-143,18h-132c-35-3-72-7-107-12c-31-5-64-11-95-18c-24-5-50-12-73-19
+
c-40-11-79-25-117-40c-69-26-141-60-209-105c-12-8-13-16-13-25c0-15,11-29,29-29C531,2546,563,2569,569,2572z"/>
+ <path class="st1" d="M1151,2009L61,2372V764l1090-363V2009z
M1212,354v1680c-1,5-3,10-7,15c-2,3-6,7-9,8c-25,10-1151,388-1166,388
+
c-12,0-23-8-29-21c0-1-1-2-1-4V739c2-5,3-12,7-16c8-11,22-13,31-16c17-6,1126-378,1142-378C1190,329,1212,336,1212,354z"/>
+ <path class="st1" d="M2120,2017l-907-282V380l907-308V2017z
M2181,32v2023c-1,23-17,33-32,33c-13,0-107-32-123-37
+
c-126-39-253-78-378-117c-28-9-57-18-84-27c-24-7-50-15-74-23c-107-33-216-66-323-102c-4-1-14-15-14-18V351c2-5,4-11,9-15
+
c8-9,351-123,486-168c36-13,487-168,501-168C2167,0,2181,13,2181,32z"/>
+ <polygon points="2411.2,2440.7 1199.5,2054.5 1204.6,373.2
2411.2,757.2 "/>
+ <g>
+ <path class="st2"
d="M1800.3,1124.6L1681.4,1412l218.6,66.3L1800.3,1124.6z
M1729,853.2l156.1,47.3l284.4,1025l-160.3-48.7
+
l-57.6-210.4L1620.2,1566l-71.3,171.4l-160.4-48.7L1729,853.2z"/>
+ </g>
+ </g>
+</g>
+</svg>
diff --git
a/packages/merchant-backoffice-ui/src/assets/icons/mstile-150x150.png
b/packages/merchant-backoffice-ui/src/assets/icons/mstile-150x150.png
new file mode 100644
index 000000000..9cfb889be
Binary files /dev/null and
b/packages/merchant-backoffice-ui/src/assets/icons/mstile-150x150.png differ
diff --git a/packages/merchant-backoffice-ui/src/assets/logo.jpeg
b/packages/merchant-backoffice-ui/src/assets/logo.jpeg
new file mode 100644
index 000000000..489832f7c
Binary files /dev/null and
b/packages/merchant-backoffice-ui/src/assets/logo.jpeg differ
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'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/merchant-backoffice-ui/src/scss/fonts/XRXV3I6Li01BKofINeaE.ttf
b/packages/merchant-backoffice-ui/src/scss/fonts/XRXV3I6Li01BKofINeaE.ttf
new file mode 100644
index 000000000..7665ee336
Binary files /dev/null and
b/packages/merchant-backoffice-ui/src/scss/fonts/XRXV3I6Li01BKofINeaE.ttf differ
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/merchant-backoffice-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.eot
b/packages/merchant-backoffice-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.eot
new file mode 100644
index 000000000..ab6b25ded
Binary files /dev/null and
b/packages/merchant-backoffice-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.eot
differ
diff --git
a/packages/merchant-backoffice-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.ttf
b/packages/merchant-backoffice-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.ttf
new file mode 100644
index 000000000..824be10fa
Binary files /dev/null and
b/packages/merchant-backoffice-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.ttf
differ
diff --git
a/packages/merchant-backoffice-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.woff
b/packages/merchant-backoffice-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.woff
new file mode 100644
index 000000000..7e087c1de
Binary files /dev/null and
b/packages/merchant-backoffice-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.woff
differ
diff --git
a/packages/merchant-backoffice-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.woff2
b/packages/merchant-backoffice-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.woff2
new file mode 100644
index 000000000..b5caa4ddc
Binary files /dev/null and
b/packages/merchant-backoffice-ui/src/scss/icons/fonts/materialdesignicons-webfont-4.9.95.woff2
differ
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/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.