From 34fd42d42e925597b70c4ba783fe407b9abf9938 Mon Sep 17 00:00:00 2001 From: yuyi Date: Mon, 1 Apr 2024 14:15:14 +0800 Subject: [PATCH] Squashed commit of the following: commit 1871f64433ab58494705a04aed49b0b35e0f5ed3 Author: yangon <2689991790@qq.com> Date: Mon Apr 1 11:14:51 2024 +0800 Trim string (#276) * fix: Trim string fields * fix: Disabled delete button * fix: Remove backup medium editing commit b42863cf811cc54b9b791f785769db3e61ac6a75 Author: yangon <2689991790@qq.com> Date: Sun Mar 31 13:17:23 2024 +0800 Feat statistics (#275) * feat: Statistics * fix: Padding ajustment commit ccb5dbea419de0eca0847878c5dd98e43f9eb1f5 Author: Powerfool Date: Fri Mar 29 14:53:05 2024 +0800 Documentation website built with Docusaurus framework (#273) commit d57ad62945cb5ecacf3defd5639e7a98d631822b Author: yangon <2689991790@qq.com> Date: Thu Mar 28 21:13:57 2024 +0800 Feat behaviour statistics commit 84531025a40a7310454c845d1af0db17cff5b29b Author: Powerfool Date: Thu Mar 28 21:04:47 2024 +0800 Merge from 2.2.0_release (#272) commit c4540ee1c55a0ea0fef76541c17d50a0a975dc26 Author: Powerfool Date: Thu Mar 28 19:36:50 2024 +0800 Transform heading characters in logging sentence to uppercase (#267) --- .github/workflows/deploy-docsite.yml | 39 + Makefile | 2 +- README-CN.md | 28 +- README.md | 26 +- api/v1alpha1/obcluster_webhook.go | 9 +- api/v1alpha1/obtenantoperation_webhook.go | 2 +- charts/ob-operator/Chart.yaml | 4 +- charts/ob-operator/templates/operator.yaml | 2 +- cmd/operator/main.go | 47 +- config/manager/kustomization.yaml | 2 +- deploy/operator.yaml | 2 +- docs/en_US/gsoc-ideas.md | 69 - docs/img/oceanbase-dashboard-install.jpg | Bin 169869 -> 0 bytes docs/img/oceanbase-dashboard-service.jpg | Bin 41908 -> 0 bytes docsite/.gitignore | 20 + docsite/README.md | 41 + docsite/babel.config.js | 3 + .../en_US => docsite/docs/developer}/arch.md | 5 +- .../docs/developer/contributor-guidance.md | 53 + .../docs/developer}/deploy-locally.md | 2 +- .../docs/developer}/deploy.md | 8 +- .../docs/developer}/develop-locally.md | 2 +- .../docs/developer}/development.md | 4 +- .../docs/manual/100.what-is-ob-operator.md | 19 + .../manual/200.quick-start-of-ob-operator.md | 97 + docsite/docs/manual/300.deploy-ob-operator.md | 81 + .../docs/manual/400.ob-operator-upgrade.md | 27 + .../500.configuration-of-ob-operator.md | 90 + .../100.cluster-management-intro.md | 19 + .../200.create-cluster.md | 185 + .../300.zone-management/100.add-zone.md | 71 + .../300.zone-management/200.delete-zone.md | 68 + .../300.zone-management/_category_.yml | 4 + .../400.server-management/100.add-server.md | 77 + .../200.delete-server.md | 71 + .../400.server-management/_category_.yml | 4 + .../500.upgrade-cluster-of-ob-operator.md | 51 + .../600.parameter-management.md | 47 + .../650.update-resources.md | 102 + .../700.delete-cluster.md | 43 + .../_category_.yml | 4 + .../000.tenant-management-intro.md | 15 + .../100.create-tenant.md | 288 + .../100.resource-management-of-ob-operator.md | 135 + .../200.replica-management-of-ob-operator.md | 277 + ...ation-item-modifications-of-ob-operator.md | 40 + .../_category_.yml | 4 + .../300.delete-tenant-of-ob-operator.md | 21 + .../400.tenant-operation.md | 88 + .../_category_.yml | 4 + .../100.high-availability-intro.md | 7 + .../300.disaster-recovery-of-ob-operator.md | 40 + .../400.tenant-backup-of-ob-operator.md | 291 + .../500.data-recovery-of-ob-operator.md | 190 + .../600.standby-tenant-of-ob-operator.md | 60 + .../300.high-availability/_category_.yml | 4 + .../500.ob-operator-user-guide/_category_.yml | 4 + .../docs/manual/900.appendix/100.example.md | 288 + docsite/docs/manual/900.appendix/200.FAQ.md | 147 + .../docs/manual/900.appendix/_category_.yml | 4 + docsite/docusaurus.config.ts | 161 + docsite/i18n/zh-Hans/code.json | 444 + .../options.json | 14 + .../current.json | 82 + .../current/developer}/arch.md | 43 +- .../developer}/contributor-guidance.md | 6 +- .../current/developer/deploy-locally.md | 207 + .../current/developer}/deploy.md | 8 +- .../current/developer/develop-locally.md | 165 + .../current/developer/development.md | 70 + .../current/manual/100.what-is-ob-operator.md | 13 + .../manual/200.quick-start-of-ob-operator.md | 93 + .../current/manual/300.deploy-ob-operator.md | 76 + .../current/manual/400.ob-operator-upgrade.md | 23 + .../500.configuration-of-ob-operator.md | 86 + .../100.cluster-management-intro.md | 19 + .../200.create-cluster.md | 184 + .../300.zone-management/100.add-zone.md | 71 + .../300.zone-management/200.delete-zone.md | 68 + .../400.server-management/100.add-server.md | 77 + .../200.delete-server.md | 71 + .../500.upgrade-cluster-of-ob-operator.md | 51 + .../600.parameter-management.md | 47 + .../650.update-resources.md | 103 + .../700.delete-cluster.md | 43 + .../000.tenant-management-intro.md | 13 + .../100.create-tenant.md | 288 + .../100.resource-management-of-ob-operator.md | 135 + .../200.replica-management-of-ob-operator.md | 277 + ...ation-item-modifications-of-ob-operator.md | 40 + .../300.delete-tenant-of-ob-operator.md | 21 + .../400.tenant-operation.md | 88 + .../100.high-availability-intro.md | 7 + .../300.disaster-recovery-of-ob-operator.md | 40 + .../400.tenant-backup-of-ob-operator.md | 291 + .../500.data-recovery-of-ob-operator.md | 190 + .../600.standby-tenant-of-ob-operator.md | 60 + .../500.ob-operator-user-guide/_category_.yml | 3 + .../manual/900.appendix/100.example.md | 283 + .../current/manual/900.appendix/200.FAQ.md | 141 + .../manual/900.appendix/_category_.yml | 3 + .../current/manual/999.changelog.md | 81 + .../changelog.md | 81 + .../docusaurus-plugin-content-pages/index.mdx | 211 + .../docusaurus-theme-classic/footer.json | 66 + .../docusaurus-theme-classic/navbar.json | 70 + docsite/package.json | 47 + docsite/sidebars.ts | 31 + docsite/src/css/custom.css | 70 + docsite/src/pages/changelog.md | 81 + docsite/src/pages/index.mdx | 211 + docsite/static/.nojekyll | 0 .../static}/img/controller-manager.jpg | Bin {docs => docsite/static}/img/crd.jpg | Bin .../static}/img/debug-in-vscode.png | Bin .../static}/img/dingtalk-operator-users.png | Bin {docs => docsite/static}/img/docker-limit.png | Bin docsite/static/img/favicon.ico | Bin 0 -> 3465 bytes docsite/static/img/logo.png | Bin 0 -> 6140 bytes .../static}/img/ob-operator-arch.png | Bin .../img/oceanbase-dashboard-install.jpg | Bin 0 -> 169982 bytes .../img/oceanbase-dashboard-overview.jpg | Bin .../img/oceanbase-dashboard-service.jpg | Bin 0 -> 40609 bytes index.yaml => docsite/static/index.yaml | 20 + docsite/tsconfig.json | 7 + docsite/yarn.lock | 8385 +++++++++++++++++ internal/controller/obcluster_controller.go | 2 +- internal/controller/obparameter_controller.go | 2 +- .../controller/obresourcerescue_controller.go | 34 +- internal/controller/observer_controller.go | 4 +- internal/controller/obtenant_controller.go | 7 +- internal/controller/obzone_controller.go | 2 +- internal/dashboard/business/metric/metric.go | 2 +- .../dashboard/business/oceanbase/obcluster.go | 2 +- .../dashboard/generated/bindata/bindata.go | 12 +- .../dashboard/middleware/authentication.go | 4 +- .../resource/obcluster/obcluster_manager.go | 4 +- internal/resource/obcluster/obcluster_task.go | 8 +- internal/resource/obcluster/utils.go | 7 +- .../obparameter/obparameter_manager.go | 2 +- .../resource/observer/observer_manager.go | 2 +- internal/resource/observer/observer_task.go | 16 +- internal/resource/observer/utils.go | 6 +- .../resource/obtenant/obtenant_manager.go | 10 +- internal/resource/obtenant/obtenant_task.go | 4 +- internal/resource/obtenant/utils.go | 2 +- .../obtenantbackup/obtenantbackup_manager.go | 12 +- .../obtenantbackup/obtenantbackup_task.go | 2 +- .../obtenantbackuppolicy_manager.go | 8 +- .../obtenantoperation_manager.go | 2 +- .../obtenantrestore_manager.go | 2 +- internal/resource/obzone/obzone_manager.go | 2 +- internal/resource/obzone/obzone_task.go | 3 +- internal/resource/utils/util.go | 22 +- internal/telemetry/throttler.go | 21 +- pkg/helper/upgrade.go | 4 +- pkg/oceanbase-sdk/const/config/bootstrap.go | 2 +- pkg/oceanbase-sdk/operation/parameter.go | 2 +- pkg/oceanbase-sdk/operation/tenant.go | 4 +- pkg/oceanbase-sdk/operation/zone.go | 10 +- ui/config/routes.ts | 221 +- ui/src/components/TopoComponent/constants.ts | 22 +- ui/src/components/TopoComponent/helper.ts | 2 +- ui/src/components/TopoComponent/index.tsx | 14 +- .../customModal/ActivateTenantModal.tsx | 4 +- ui/src/components/customModal/AddNSModal.tsx | 2 +- .../components/customModal/AddZoneModal.tsx | 7 +- .../components/customModal/LogReplayModal.tsx | 2 +- .../customModal/ModifyPasswordModal.tsx | 2 +- .../customModal/ModifyUnitDetailModal.tsx | 9 +- .../customModal/ModifyUnitModal.tsx | 6 +- ui/src/components/customModal/ScaleModal.tsx | 6 +- .../customModal/SwitchTenantModal.tsx | 11 +- .../components/customModal/UpgradeModal.tsx | 7 +- .../customModal/UpgradeTenantModal.tsx | 8 +- ui/src/constants/index.ts | 8 + ui/src/hook/usePublicKey.ts | 6 +- ui/src/models/global.ts | 7 +- .../Cluster/Detail/Overview/ZoneTable.tsx | 10 +- .../pages/Cluster/Detail/Overview/index.tsx | 5 +- ui/src/pages/Cluster/Detail/index.tsx | 16 +- ui/src/pages/Cluster/New/index.tsx | 6 +- ui/src/pages/Layouts/BasicLayout/index.tsx | 22 +- .../pages/Layouts/StatisticsLayout/index.tsx | 30 + ui/src/pages/Layouts/index.tsx | 10 +- ui/src/pages/Login/index.tsx | 35 +- .../Detail/Backup/BackupConfiguration.tsx | 60 +- .../pages/Tenant/Detail/NewBackup/index.tsx | 8 +- ui/src/pages/Tenant/Detail/Overview/index.tsx | 4 +- ui/src/pages/Tenant/Detail/index.tsx | 14 +- ui/src/pages/Tenant/New/index.tsx | 7 +- ui/src/services/index.ts | 32 +- .../services/reportRequest/backupReportReq.ts | 56 + .../reportRequest/clusterReportReq.ts | 76 + ui/src/services/reportRequest/index.ts | 158 + .../services/reportRequest/tenantReportReq.ts | 153 + ui/src/services/tenant.ts | 6 +- ui/src/services/typings.d.ts | 260 +- ui/src/utils/helper.ts | 59 +- 199 files changed, 17803 insertions(+), 599 deletions(-) create mode 100644 .github/workflows/deploy-docsite.yml delete mode 100644 docs/en_US/gsoc-ideas.md delete mode 100644 docs/img/oceanbase-dashboard-install.jpg delete mode 100644 docs/img/oceanbase-dashboard-service.jpg create mode 100644 docsite/.gitignore create mode 100644 docsite/README.md create mode 100644 docsite/babel.config.js rename {docs/en_US => docsite/docs/developer}/arch.md (97%) create mode 100644 docsite/docs/developer/contributor-guidance.md rename {docs/en_US => docsite/docs/developer}/deploy-locally.md (99%) rename {docs/en_US => docsite/docs/developer}/deploy.md (94%) rename {docs/en_US => docsite/docs/developer}/develop-locally.md (99%) rename {docs/en_US => docsite/docs/developer}/development.md (95%) create mode 100644 docsite/docs/manual/100.what-is-ob-operator.md create mode 100644 docsite/docs/manual/200.quick-start-of-ob-operator.md create mode 100644 docsite/docs/manual/300.deploy-ob-operator.md create mode 100644 docsite/docs/manual/400.ob-operator-upgrade.md create mode 100644 docsite/docs/manual/500.configuration-of-ob-operator.md create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/100.cluster-management-intro.md create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/200.create-cluster.md create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/300.zone-management/100.add-zone.md create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/300.zone-management/200.delete-zone.md create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/300.zone-management/_category_.yml create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/400.server-management/100.add-server.md create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/400.server-management/200.delete-server.md create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/400.server-management/_category_.yml create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/500.upgrade-cluster-of-ob-operator.md create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/600.parameter-management.md create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/650.update-resources.md create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/700.delete-cluster.md create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/_category_.yml create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/000.tenant-management-intro.md create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/100.create-tenant.md create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/100.resource-management-of-ob-operator.md create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/200.replica-management-of-ob-operator.md create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/300.other-configuration-item-modifications-of-ob-operator.md create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/_category_.yml create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/300.delete-tenant-of-ob-operator.md create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/400.tenant-operation.md create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/_category_.yml create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/300.high-availability/100.high-availability-intro.md create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/300.high-availability/300.disaster-recovery-of-ob-operator.md create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/300.high-availability/400.tenant-backup-of-ob-operator.md create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/300.high-availability/500.data-recovery-of-ob-operator.md create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/300.high-availability/600.standby-tenant-of-ob-operator.md create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/300.high-availability/_category_.yml create mode 100644 docsite/docs/manual/500.ob-operator-user-guide/_category_.yml create mode 100644 docsite/docs/manual/900.appendix/100.example.md create mode 100644 docsite/docs/manual/900.appendix/200.FAQ.md create mode 100644 docsite/docs/manual/900.appendix/_category_.yml create mode 100644 docsite/docusaurus.config.ts create mode 100644 docsite/i18n/zh-Hans/code.json create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-blog/options.json create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current.json rename {docs/zh_CN => docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer}/arch.md (76%) rename {docs/en_US => docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer}/contributor-guidance.md (85%) create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer/deploy-locally.md rename {docs/zh_CN => docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer}/deploy.md (93%) create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer/develop-locally.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer/development.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/100.what-is-ob-operator.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/200.quick-start-of-ob-operator.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/300.deploy-ob-operator.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/400.ob-operator-upgrade.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.configuration-of-ob-operator.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/100.cluster-management-intro.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/200.create-cluster.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/300.zone-management/100.add-zone.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/300.zone-management/200.delete-zone.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/400.server-management/100.add-server.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/400.server-management/200.delete-server.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/500.upgrade-cluster-of-ob-operator.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/600.parameter-management.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/650.update-resources.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/700.delete-cluster.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/000.tenant-management-intro.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/100.create-tenant.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/100.resource-management-of-ob-operator.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/200.replica-management-of-ob-operator.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/300.other-configuration-item-modifications-of-ob-operator.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/300.delete-tenant-of-ob-operator.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/400.tenant-operation.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/300.high-availability/100.high-availability-intro.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/300.high-availability/300.disaster-recovery-of-ob-operator.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/300.high-availability/400.tenant-backup-of-ob-operator.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/300.high-availability/500.data-recovery-of-ob-operator.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/300.high-availability/600.standby-tenant-of-ob-operator.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/_category_.yml create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/900.appendix/100.example.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/900.appendix/200.FAQ.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/900.appendix/_category_.yml create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/999.changelog.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-pages/changelog.md create mode 100644 docsite/i18n/zh-Hans/docusaurus-plugin-content-pages/index.mdx create mode 100644 docsite/i18n/zh-Hans/docusaurus-theme-classic/footer.json create mode 100644 docsite/i18n/zh-Hans/docusaurus-theme-classic/navbar.json create mode 100644 docsite/package.json create mode 100644 docsite/sidebars.ts create mode 100644 docsite/src/css/custom.css create mode 100644 docsite/src/pages/changelog.md create mode 100644 docsite/src/pages/index.mdx create mode 100644 docsite/static/.nojekyll rename {docs => docsite/static}/img/controller-manager.jpg (100%) rename {docs => docsite/static}/img/crd.jpg (100%) rename {docs => docsite/static}/img/debug-in-vscode.png (100%) rename {docs => docsite/static}/img/dingtalk-operator-users.png (100%) rename {docs => docsite/static}/img/docker-limit.png (100%) create mode 100644 docsite/static/img/favicon.ico create mode 100644 docsite/static/img/logo.png rename {docs => docsite/static}/img/ob-operator-arch.png (100%) create mode 100644 docsite/static/img/oceanbase-dashboard-install.jpg rename {docs => docsite/static}/img/oceanbase-dashboard-overview.jpg (100%) create mode 100644 docsite/static/img/oceanbase-dashboard-service.jpg rename index.yaml => docsite/static/index.yaml (74%) create mode 100644 docsite/tsconfig.json create mode 100644 docsite/yarn.lock create mode 100644 ui/src/pages/Layouts/StatisticsLayout/index.tsx create mode 100644 ui/src/services/reportRequest/backupReportReq.ts create mode 100644 ui/src/services/reportRequest/clusterReportReq.ts create mode 100644 ui/src/services/reportRequest/index.ts create mode 100644 ui/src/services/reportRequest/tenantReportReq.ts diff --git a/.github/workflows/deploy-docsite.yml b/.github/workflows/deploy-docsite.yml new file mode 100644 index 000000000..3fbd1b3c9 --- /dev/null +++ b/.github/workflows/deploy-docsite.yml @@ -0,0 +1,39 @@ +name: Deploy to GitHub Pages + +on: + push: + branches: + - master + - test-docsite + paths: + - 'docsite/**' + +permissions: + contents: write + +jobs: + deploy: + name: Deploy to GitHub Pages + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: actions/setup-node@v4 + with: + node-version: 18 + cache: yarn + cache-dependency-path: './docsite' + - name: Install dependencies + run: cd docsite && yarn install --frozen-lockfile + - name: Build website + run: cd docsite && yarn build + + # Popular action to deploy to GitHub Pages: + # Docs: https://github.com/peaceiris/actions-gh-pages#%EF%B8%8F-docusaurus + - name: Deploy to GitHub Pages + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + # Build output to publish to the `gh-pages` branch: + publish_dir: ./docsite/build \ No newline at end of file diff --git a/Makefile b/Makefile index 2c1922754..d6a747c58 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ include make/* -VERSION ?= 2.1.2 +VERSION ?= 2.2.0 # Image URL to use all building/pushing image targets IMG ?= oceanbase/ob-operator:${VERSION} # ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. diff --git a/README-CN.md b/README-CN.md index f8a1623ac..0091b2d73 100644 --- a/README-CN.md +++ b/README-CN.md @@ -15,7 +15,7 @@ ob-operator 是满足 Kubernetes Operator 扩展范式的自动化工具,可 ob-operator 依赖 [cert-manager](https://cert-manager.io/docs/), cert-manager 的安装可以参考对应的[安装文档](https://cert-manager.io/docs/installation/),如果您无法访问官方制品托管在 `quay.io` 镜像站的镜像,可通过下面的指令安装我们转托在 `docker.io` 中的制品: ```shell -kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.2_release/deploy/cert-manager.yaml +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.2.0_release/deploy/cert-manager.yaml ``` 本例子中的 OceanBase 集群存储依赖 [local-path-provisioner](https://github.com/rancher/local-path-provisioner) 提供, 需要提前进行安装并确保其存储目的地有足够大的磁盘空间。 @@ -29,7 +29,7 @@ kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.2_r * 稳定版本 ```shell -kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.2_release/deploy/operator.yaml +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.2.0_release/deploy/operator.yaml ``` * 开发版本 @@ -45,7 +45,7 @@ Helm Chart 将 ob-operator 部署的命名空间进行了参数化,可在安 ```shell helm repo add ob-operator https://oceanbase.github.io/ob-operator/ helm repo update -helm install ob-operator ob-operator/ob-operator --namespace=oceanbase-system --create-namespace --version=2.1.2 +helm install ob-operator ob-operator/ob-operator --namespace=oceanbase-system --create-namespace --version=2.2.0 ``` #### 使用 terraform @@ -94,7 +94,7 @@ kubectl create secret generic root-password --from-literal=password='root_passwo 通过以下命令即可在 K8s 集群中部署 OceanBase: ```shell -kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.2_release/example/quickstart/obcluster.yaml +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.2.0_release/example/quickstart/obcluster.yaml ``` 一般初始化集群需要 2 分钟左右的时间,执行以下命令,查询集群状态,当集群状态变成 running 之后表示集群创建和初始化成功: @@ -109,7 +109,7 @@ test running 6m2s ### 连接集群 -通过以下命令查找 observer 的 POD IP,POD 名的规则是 {cluster_name}-{cluster_id}-{zone}-uuid: +通过以下命令查找 observer 的 POD IP,POD 名的规则是 `${cluster_name}-${cluster_id}-${zone}-uuid`: ```shell kubectl get pods -o wide @@ -130,7 +130,7 @@ helm repo add ob-operator https://oceanbase.github.io/ob-operator/ helm install oceanbase-dashboard ob-operator/oceanbase-dashboard --version=0.1.0 ``` -![oceanbase-dashboard-install](./docs/img/oceanbase-dashboard-install.jpg) +![oceanbase-dashboard-install](./docsite/static/img/oceanbase-dashboard-install.jpg) OceanBase Dashboard 成功安装之后, 会自动创建一个 admin 用户和随机密码,可以通过如下命令查看密码。 ``` @@ -140,18 +140,18 @@ echo $(kubectl get -n default secret oceanbase-dashboard-user-credentials -o jso ``` kubectl get svc oceanbase-dashboard-ob-dashboard ``` -![oceanbase-dashboard-service](./docs/img/oceanbase-dashboard-service.jpg) +![oceanbase-dashboard-service](./docsite/static/img/oceanbase-dashboard-service.jpg) 使用 admin 账号和查看到的密码登录。 -![oceanbase-dashboard-overview](./docs/img/oceanbase-dashboard-overview.jpg) +![oceanbase-dashboard-overview](./docsite/static/img/oceanbase-dashboard-overview.jpg) ## 项目架构 ob-operator 以 kubebuilder 为基础,通过统一的资源管理器接口、全局的任务管理器实例以及解决长调度的任务流机制完成对 OceanBase 集群及相关应用的控制和管理。ob-operator 的架构大致如下图所示: -![ob-operator 架构设计](./docs/img/ob-operator-arch.png) +![ob-operator 架构设计](./docsite/static/img/ob-operator-arch.png) -有关架构细节可参见[架构设计文档](./docs/zh_CN/arch.md)。 +有关架构细节可参见[架构设计文档](./docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer/arch.md)。 ## 特性 @@ -185,9 +185,9 @@ ob-operator 使用 [kubebuilder](https://book.kubebuilder.io/introduction) 项 ## 文档 -- [ob-operator 架构设计](docs/zh_CN/arch.md) -- [部署 ob-operator](docs/zh_CN/deploy.md) -- [开发手册](docs/en_US/development.md)(英文) +- [ob-operator 架构设计](docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer/arch.md) +- [部署 ob-operator](docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer/deploy.md) +- [开发手册](docsite/docs/developer/development.md)(英文) - [用户手册](https://www.oceanbase.com/docs/community-ob-operator-doc-1000000000408367) ## 获取帮助 @@ -197,7 +197,7 @@ ob-operator 使用 [kubebuilder](https://book.kubebuilder.io/introduction) 项 - [GitHub Issue](https://github.com/oceanbase/ob-operator/issues) - [官方网站](https://open.oceanbase.com/) - [Slack](https://oceanbase.slack.com/archives/C053PT371S7) -- 钉钉群([二维码](./docs/img/dingtalk-operator-users.png)) +- 钉钉群([二维码](./docsite/static/img/dingtalk-operator-users.png)) - 微信群(请添加小助手微信,微信号: OBCE666) ## 参与开发 diff --git a/README.md b/README.md index 61778cde3..a06e42c98 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ ob-operator relies on [cert-manager](https://cert-manager.io/docs/) for certific If you have trouble accessing `quay.io` image registry, our mirrored cert-manager manifests can be applied through following command: ```shell -kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.2_release/deploy/cert-manager.yaml +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.2.0_release/deploy/cert-manager.yaml ``` Storage of OceanBase cluster in this example relies on [local-path-provisioner](https://github.com/rancher/local-path-provisioner), which should be installed beforehand. You should confirm that there is enough disk space in storage destination of local-path-provisioner. @@ -30,7 +30,7 @@ You can deploy ob-operator in a Kubernetes cluster by executing the following co * Stable ```shell -kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.2_release/deploy/operator.yaml +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.2.0_release/deploy/operator.yaml ``` * Development @@ -46,7 +46,7 @@ Helm Chart parameterizes the namespace in which ob-operator is deployed, allowin ```shell helm repo add ob-operator https://oceanbase.github.io/ob-operator/ helm repo update -helm install ob-operator ob-operator/ob-operator --namespace=oceanbase-system --create-namespace --version=2.1.2 +helm install ob-operator ob-operator/ob-operator --namespace=oceanbase-system --create-namespace --version=2.2.0 ``` #### Using terraform @@ -95,7 +95,7 @@ kubectl create secret generic root-password --from-literal=password='root_passwo You can deploy OceanBase in a Kubernetes cluster by executing the following command: ```shell -kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.2_release/example/quickstart/obcluster.yaml +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.2.0_release/example/quickstart/obcluster.yaml ``` It generally takes around 2 minutes to bootstrap a cluster. Execute the following command to check the status of the cluster. Once the cluster status changes to "running," it indicates that the cluster has been successfully created and bootstrapped: @@ -110,7 +110,7 @@ test running 6m2s ### Connecting to the OceanBase Cluster -Use the following command to find the POD IP of the observer. The naming convention for PODs is {cluster_name}-{cluster_id}-{zone}-uuid: +Use the following command to find the POD IP of the observer. The naming convention for PODs is `${cluster_name}-${cluster_id}-${zone}-uuid`: ```shell kubectl get pods -o wide @@ -131,7 +131,7 @@ helm repo add ob-operator https://oceanbase.github.io/ob-operator/ helm install oceanbase-dashboard ob-operator/oceanbase-dashboard --version=0.1.0 ``` -![oceanbase-dashboard-install](./docs/img/oceanbase-dashboard-install.jpg) +![oceanbase-dashboard-install](./docsite/static/img/oceanbase-dashboard-install.jpg) After OceanBase Dashboard is successfully installed, a default user admin is created with a random password, you can check the password using the command printed after installation. ``` @@ -141,18 +141,18 @@ A service of type NodePort is created by default, you can check the address and ``` kubectl get svc oceanbase-dashboard-ob-dashboard ``` -![oceanbase-dashboard-service](./docs/img/oceanbase-dashboard-service.jpg) +![oceanbase-dashboard-service](./docsite/static/img/oceanbase-dashboard-service.jpg) Login with admin user and password -![oceanbase-dashboard-overview](./docs/img/oceanbase-dashboard-overview.jpg) +![oceanbase-dashboard-overview](./docsite/static/img/oceanbase-dashboard-overview.jpg) ## Project Architecture ob-operator is built on top of kubebuilder and provides control and management of OceanBase clusters and related applications through a unified resource manager interface, a global task manager instance, and a task flow mechanism for handling long-running tasks. The architecture diagram is approximately as follows: -![ob-operator Architecture](./docs/img/ob-operator-arch.png) +![ob-operator Architecture](./docsite/static/img/ob-operator-arch.png) -For more detailed information about the architecture, please refer to the [Architecture Document](./docs/en_US/arch.md). +For more detailed information about the architecture, please refer to the [Architecture Document](./docsite/docs/developer/arch.md). ## Features @@ -186,8 +186,8 @@ ob-operator is built using the [kubebuilder](https://book.kubebuilder.io/introdu ## Documents -- [Architecture](docs/en_US/arch.md) -- [Contributor Guidance](docs/en_US/contributor-guidance.md) +- [Architecture](docsite/docs/developer/arch.md) +- [Contributor Guidance](docsite/docs/developer/contributor-guidance.md) - [User Manual](https://en.oceanbase.com/docs/community-ob-operator-doc-en-10000000001123466) ## Getting Help @@ -197,7 +197,7 @@ If you encounter any issues while using ob-operator, please feel free to seek he - [GitHub Issue](https://github.com/oceanbase/ob-operator/issues) - [Official Website](https://open.oceanbase.com/) - [Slack](https://oceanbase.slack.com/archives/C053PT371S7) -- DingTalk Group ([QRCode](./docs/img/dingtalk-operator-users.png)) +- DingTalk Group ([QRCode](./docsite/static/img/dingtalk-operator-users.png)) - WeChat Group (Add the assistant with WeChat ID: OBCE666) ## Contributing diff --git a/api/v1alpha1/obcluster_webhook.go b/api/v1alpha1/obcluster_webhook.go index 45819a1dd..ff5d9885f 100644 --- a/api/v1alpha1/obcluster_webhook.go +++ b/api/v1alpha1/obcluster_webhook.go @@ -58,7 +58,6 @@ var _ webhook.Defaulter = &OBCluster{} func (r *OBCluster) Default() { // fill default essential parameters, memory_limit, datafile_maxsize and datafile_next - obclusterlog.Info("fill in default values of obcluster") parameterMap := make(map[string]apitypes.Parameter, 0) memorySize, ok := r.Spec.OBServerTemplate.Resource.Memory.AsInt64() if ok { @@ -68,7 +67,7 @@ func (r *OBCluster) Default() { Value: memoryLimit, } } else { - obclusterlog.Error(errors.New("failed to parse memory size"), "parse observer's memory size failed") + obclusterlog.Error(errors.New("Failed to parse memory size"), "parse observer's memory size failed") } datafileDiskSize, ok := r.Spec.OBServerTemplate.Storage.DataStorage.Size.AsInt64() if ok { @@ -83,7 +82,7 @@ func (r *OBCluster) Default() { Value: datafileNextSize, } } else { - obclusterlog.Error(errors.New("failed to parse datafile size"), "parse observer's datafile size failed") + obclusterlog.Error(errors.New("Failed to parse datafile size"), "parse observer's datafile size failed") } parameterMap["enable_syslog_recycle"] = apitypes.Parameter{ Name: "enable_syslog_recycle", @@ -304,7 +303,7 @@ func (r *OBCluster) validateMutation() error { if err != nil { allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("parameters"), "memory limit size", "Failed to parse memory limit")) } else if memoryLimit.AsApproximateFloat64() > r.Spec.OBServerTemplate.Resource.Memory.AsApproximateFloat64() { - allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("parameters"), "memory limit size overflow", "memory limit exceeds observer's resource")) + allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("parameters"), "memory limit size overflow", "Memory limit exceeds observer's resource")) } if r.Spec.OBServerTemplate.Storage.DataStorage.Size.AsApproximateFloat64() < 3*memoryLimit.AsApproximateFloat64() { @@ -323,7 +322,7 @@ func (r *OBCluster) validateMutation() error { if err != nil { allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("parameters"), "datafile max size", "Failed to parse datafile max size")) } else if datafileMax.AsApproximateFloat64() > r.Spec.OBServerTemplate.Storage.DataStorage.Size.AsApproximateFloat64() { - allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("parameters"), "datafile max size overflow", "datafile maxsize exceeds observer's data storage size")) + allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("parameters"), "datafile max size overflow", "Datafile maxsize exceeds observer's data storage size")) } } diff --git a/api/v1alpha1/obtenantoperation_webhook.go b/api/v1alpha1/obtenantoperation_webhook.go index 78554cd22..41aa667ee 100644 --- a/api/v1alpha1/obtenantoperation_webhook.go +++ b/api/v1alpha1/obtenantoperation_webhook.go @@ -105,7 +105,7 @@ func (r *OBTenantOperation) Default() { Name: secondaryTenantName, }, secondaryTenant) if err != nil { - obtenantoperationlog.Error(err, "get tenant") + // obtenantoperationlog.Error(err, "get tenant") return } secondMeta := secondaryTenant.GetObjectMeta() diff --git a/charts/ob-operator/Chart.yaml b/charts/ob-operator/Chart.yaml index cccea8a9d..3219ef7ac 100644 --- a/charts/ob-operator/Chart.yaml +++ b/charts/ob-operator/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 -appVersion: 2.1.2 +appVersion: 2.2.0 description: A Helm chart for OB-Operator name: ob-operator type: application -version: 2.1.2 +version: 2.2.0 diff --git a/charts/ob-operator/templates/operator.yaml b/charts/ob-operator/templates/operator.yaml index 7c3b5297b..e36332dcb 100644 --- a/charts/ob-operator/templates/operator.yaml +++ b/charts/ob-operator/templates/operator.yaml @@ -12713,7 +12713,7 @@ spec: - --log-verbosity=0 command: - /manager - image: oceanbase/ob-operator:2.1.2 + image: oceanbase/ob-operator:2.2.0 livenessProbe: httpGet: path: /healthz diff --git a/cmd/operator/main.go b/cmd/operator/main.go index c5aa9a6c9..085f807d7 100644 --- a/cmd/operator/main.go +++ b/cmd/operator/main.go @@ -21,15 +21,13 @@ import ( "flag" "os" - // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) - // to ensure that exec-entrypoint and run can make use of them. + //+kubebuilder:scaffold:imports "go.uber.org/zap/zapcore" - _ "k8s.io/client-go/plugin/pkg/client/auth" - "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" + _ "k8s.io/client-go/plugin/pkg/client/auth" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/log/zap" @@ -38,7 +36,6 @@ import ( "github.com/oceanbase/ob-operator/internal/controller" "github.com/oceanbase/ob-operator/internal/controller/config" "github.com/oceanbase/ob-operator/internal/telemetry" - //+kubebuilder:scaffold:imports ) var ( @@ -113,7 +110,7 @@ func main() { // LeaderElectionReleaseOnCancel: true, }) if err != nil { - setupLog.Error(err, "unable to start manager") + setupLog.Error(err, "Unable to start manager") os.Exit(1) } @@ -122,7 +119,7 @@ func main() { Scheme: mgr.GetScheme(), Recorder: mgr.GetEventRecorderFor(config.OBClusterControllerName), }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "OBCluster") + setupLog.Error(err, "Unable to create controller", "controller", "OBCluster") os.Exit(1) } if err = (&controller.OBZoneReconciler{ @@ -130,7 +127,7 @@ func main() { Scheme: mgr.GetScheme(), Recorder: mgr.GetEventRecorderFor(config.OBZoneControllerName), }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "OBZone") + setupLog.Error(err, "Unable to create controller", "controller", "OBZone") os.Exit(1) } if err = (&controller.OBServerReconciler{ @@ -138,7 +135,7 @@ func main() { Scheme: mgr.GetScheme(), Recorder: mgr.GetEventRecorderFor(config.OBServerControllerName), }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "OBServer") + setupLog.Error(err, "Unable to create controller", "controller", "OBServer") os.Exit(1) } if err = (&controller.OBParameterReconciler{ @@ -146,7 +143,7 @@ func main() { Scheme: mgr.GetScheme(), Recorder: mgr.GetEventRecorderFor(config.OBParameterControllerName), }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "OBParameter") + setupLog.Error(err, "Unable to create controller", "controller", "OBParameter") os.Exit(1) } if err = (&controller.OBTenantReconciler{ @@ -154,7 +151,7 @@ func main() { Scheme: mgr.GetScheme(), Recorder: mgr.GetEventRecorderFor(config.OBTenantControllerName), }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "OBTenant") + setupLog.Error(err, "Unable to create controller", "controller", "OBTenant") os.Exit(1) } if err = (&controller.OBTenantBackupReconciler{ @@ -162,7 +159,7 @@ func main() { Scheme: mgr.GetScheme(), Recorder: telemetry.NewRecorder(context.Background(), mgr.GetEventRecorderFor(config.OBTenantBackupControllerName)), }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "OBTenantBackup") + setupLog.Error(err, "Unable to create controller", "controller", "OBTenantBackup") os.Exit(1) } if err = (&controller.OBTenantRestoreReconciler{ @@ -170,7 +167,7 @@ func main() { Scheme: mgr.GetScheme(), Recorder: mgr.GetEventRecorderFor(config.OBTenantRestoreControllerName), }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "OBTenantRestore") + setupLog.Error(err, "Unable to create controller", "controller", "OBTenantRestore") os.Exit(1) } if err = (&controller.OBTenantBackupPolicyReconciler{ @@ -178,7 +175,7 @@ func main() { Scheme: mgr.GetScheme(), Recorder: mgr.GetEventRecorderFor(config.OBTenantBackupPolicyControllerName), }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "OBTenantBackupPolicy") + setupLog.Error(err, "Unable to create controller", "controller", "OBTenantBackupPolicy") os.Exit(1) } if err = (&controller.OBTenantOperationReconciler{ @@ -186,48 +183,48 @@ func main() { Scheme: mgr.GetScheme(), Recorder: mgr.GetEventRecorderFor(config.OBTenantOperationControllerName), }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "OBTenantOperation") + setupLog.Error(err, "Unable to create controller", "controller", "OBTenantOperation") os.Exit(1) } if err = (controller.NewOBResourceRescueReconciler(mgr)).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "OBResourceRescue") + setupLog.Error(err, "Unable to create controller", "controller", "OBResourceRescue") os.Exit(1) } if os.Getenv("DISABLE_WEBHOOKS") != "true" { if err = (&v1alpha1.OBTenantBackupPolicy{}).SetupWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "OBTenantBackupPolicy") + setupLog.Error(err, "Unable to create webhook", "webhook", "OBTenantBackupPolicy") os.Exit(1) } if err = (&v1alpha1.OBTenant{}).SetupWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "OBTenant") + setupLog.Error(err, "Unable to create webhook", "webhook", "OBTenant") os.Exit(1) } if err = (&v1alpha1.OBTenantOperation{}).SetupWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "OBTenantOperation") + setupLog.Error(err, "Unable to create webhook", "webhook", "OBTenantOperation") os.Exit(1) } if err = (&v1alpha1.OBCluster{}).SetupWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "OBCluster") + setupLog.Error(err, "Unable to create webhook", "webhook", "OBCluster") os.Exit(1) } if err = (&v1alpha1.OBResourceRescue{}).SetupWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "OBResourceRescue") + setupLog.Error(err, "Unable to create webhook", "webhook", "OBResourceRescue") os.Exit(1) } } //+kubebuilder:scaffold:builder if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { - setupLog.Error(err, "unable to set up health check") + setupLog.Error(err, "Unable to set up health check") os.Exit(1) } if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil { - setupLog.Error(err, "unable to set up ready check") + setupLog.Error(err, "Unable to set up ready check") os.Exit(1) } rcd := telemetry.NewRecorder(context.Background(), mgr.GetEventRecorderFor("ob-operator")) - rcd.GenerateTelemetryRecord(nil, telemetry.ObjectTypeOperator, "Start", "", "start ob-operator", nil) + rcd.GenerateTelemetryRecord(nil, telemetry.ObjectTypeOperator, "Start", "", "Start ob-operator", nil) setupLog.WithValues( "namespace", namespace, @@ -239,7 +236,7 @@ func main() { ).Info("starting manager") if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { - setupLog.Error(err, "problem running manager") + setupLog.Error(err, "Failed to start manager") os.Exit(1) } } diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 7e12705f9..967776462 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -5,4 +5,4 @@ kind: Kustomization images: - name: controller newName: oceanbase/ob-operator - newTag: 2.1.2 + newTag: 2.2.0 diff --git a/deploy/operator.yaml b/deploy/operator.yaml index 21a3c78e2..fdf66b4ae 100644 --- a/deploy/operator.yaml +++ b/deploy/operator.yaml @@ -12733,7 +12733,7 @@ spec: - --log-verbosity=0 command: - /manager - image: oceanbase/ob-operator:2.1.2 + image: oceanbase/ob-operator:2.2.0 livenessProbe: httpGet: path: /healthz diff --git a/docs/en_US/gsoc-ideas.md b/docs/en_US/gsoc-ideas.md deleted file mode 100644 index 8e4a6252b..000000000 --- a/docs/en_US/gsoc-ideas.md +++ /dev/null @@ -1,69 +0,0 @@ -# GSoC 2024 Ideas List - -Hi there! This is the ideas list of OceanBase for Google Summer of Code 2024! - -As a first-year mentor organization, we focus the development ideas on ob-operator, a kubernetes operator which helps deploy and manage OceanBase cluster on kubernetes cluster seamlessly. There are five projects for contributors, and we'll offer dedicated guidance for every choice. - -Enjoy your summer of code! - -## 1. CLI tool - -* Project Description: The primary method to manage CRDs of ob-operator currently is manipulating YAML manifests which is not easy enough for new-coming users to get started. We'd like to provide features such as component installation, demo setup and resource management within a CLI tool. -* Required Skills: Golang, Kubernetes -* Project Size: intermediate, about 175 hours -* Possible mentors: He Wang, Arthur -* Expected Outcomes: A complete CLI tool that helps to install necessary components, set up demo clusters and manage creation, update and deletion of CRDs such as clusters, tenants and backups. -* References: - * [kubernetes/client-go](https://github.com/kubernetes/client-go) - * [spf13/cobra](https://github.com/spf13/cobra) - * [manifoldco/promptui](https://github.com/manifoldco/promptui) - - -## 2. Light-weighted Operations - -* Project Description: Use Light-weighted operation task types to influence the configuration of resources instead of modifying specifications of those bigger resources directly. -* Required Skills: Golang, Development of Kubernetes controller, Docker -* Project Size: intermediate, about 175 hours -* Possible mentors: Jing Ding, Chris Sun -* Expected Outcomes: Implementation of CRD(s) and corresponding controller(s) for clusters, tenants and backups, which can trigger small operational actions and reveal the progress through their own status. -* References: - * [Tenant operation: Failover](https://en.oceanbase.com/docs/common-oceanbase-database-10000000001106036) - * [Tenant operation: Replay log](https://en.oceanbase.com/docs/common-oceanbase-database-10000000001103949) - * [Architecture of ob-operator](https://oceanbase.github.io/ob-operator/docs/en_US/arch.html) - - -## 3. Alertmanager Integration - -* Project Description: There are some features about cluster management in OceanBase dashboard, a web-based dashboard application. OceanBase dashboard has bundled prometheus to manage time series metrics data by now. However it lacks of alerting features like high resource utilization alerts. So integrating alertmanager into OceanBase dashboard could be an attracive feature. -* Required Skills: Web development(React), Kubernetes, Prometheus, Alertmanager -* Project Size: intermediate, about 175 hours -* Possible mentors: Rongfeng Fu, Arthur -* Expected Outcomes: An independent functional panel in OceanBase dashboard in which users could view alert events, configure alert rules, and define alert templates in the scope of alertmanager. -* References: - * [Alertmanager](https://prometheus.io/docs/alerting/latest/alertmanager/) - * [prometheus/alertmanager](https://github.com/prometheus/alertmanager) - * [OceanBase - Monitor - Overview](https://en.oceanbase.com/docs/common-oceanbase-database-10000000001103563) - - -## 4. ODP Management in OceanBase Dashboard - -* Project Description: OceanBase Database Proxy (ODP), also called OBProxy, is a dedicated proxy server for OceanBase Database. Core features of ODP include connection management, optimal routing, high-performance forwarding, easy O&M, high availability, and proprietary protocol. ODP should be integrated into OceanBase dashboard to enhance proxy management. -* Required Skills: Web development(React), Golang Kubernetes, -* Project Size: intermediate, about 175 hours -* Possible mentors: Quanqing Xu, Rongfeng Fu -* Expected Outcomes: A independent functional panel (the same level as cluster management) in OceanBase dashboard where users could set up, configure and even delete ODP for specific OceanBase clusters. -* References: - * [OceanBase Database Proxy](https://en.oceanbase.com/docs/odp-en) - - -## 5. Accounts management and RBAC admission control - -* Project Description: OceanBase Dashboard is a web-based management platform for ob-operator, with support for managing cluster and tenant clearly. Currently, it has a quite simple account system that stores and retrieves user credentials with `Secret` resource. And, it lacks any form of admission control. So it would be a good starting point to develop an account management module, complemented by a robust RBAC (Role-Based Access Control) permissions system. -* Required Skills: Golang, Kubernetes -* Project Size: intermediate, about 175 hours -* Possible mentors: Jing Ding, Chris Sun -* Expected Outcomes: an advanced account management module paired with an RBAC-aligned permissions system. -* References: - * [casbin/casbin](https://github.com/casbin/casbin) - * [Using RBAC Authorization](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) - * [Certificates and Certificate Signing Requests](https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/) \ No newline at end of file diff --git a/docs/img/oceanbase-dashboard-install.jpg b/docs/img/oceanbase-dashboard-install.jpg deleted file mode 100644 index 8a74808ec39f6c6e585b93f9ad60dd74c4aef0a4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 169869 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%0Ax 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 Xy;S(0kNe*@c3}C3z}F4=J^OzE*^y@A diff --git a/docs/img/oceanbase-dashboard-service.jpg b/docs/img/oceanbase-dashboard-service.jpg deleted file mode 100644 index 7de65b519a2d58a00e9360edea45052a213fc515..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41908 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 z 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 yarn deploy +``` + +If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. diff --git a/docsite/babel.config.js b/docsite/babel.config.js new file mode 100644 index 000000000..e00595dae --- /dev/null +++ b/docsite/babel.config.js @@ -0,0 +1,3 @@ +module.exports = { + presets: [require.resolve('@docusaurus/core/lib/babel/preset')], +}; diff --git a/docs/en_US/arch.md b/docsite/docs/developer/arch.md similarity index 97% rename from docs/en_US/arch.md rename to docsite/docs/developer/arch.md index 8391cbbb7..8aede5399 100644 --- a/docs/en_US/arch.md +++ b/docsite/docs/developer/arch.md @@ -1,7 +1,5 @@ # Architecture -该文档也提供[中文版](../zh_CN/arch.md)。 - This document does not cover the architecture and instructions for managing the OceanBase database itself. If you want to learn more, please refer to the [official documentation](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000217922). ob-operator follows the [Operator pattern of Kubernetes](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/), focusing on custom resources and their control logic. It is developed based on the Kubernetes Operator development framework, [kubebuilder@v3](https://book.kubebuilder.io/introduction), making its underlying architecture similar to [that of kubebuilder](https://book.kubebuilder.io/architecture). By globally registering a Controller Manager from the Kubernetes control plane and overseeing multiple controllers and webhooks, ob-operator controls custom resources like OBCluster and OBTenant etc. @@ -68,9 +66,8 @@ To address this issue, ob-operator adopts task flow mechanism and a global task The relationship among the control loop, resource manager, and task manager is depicted in the following figure. -![The relationship among the control loop, resource manager, and task manager](../img/ob-operator-arch.png) +![The relationship among the control loop, resource manager, and task manager](/img/ob-operator-arch.png) -## Interaction between Resource Manager and Task Manager Tasks in the task flow are submitted by the Resource Manager (`ResourceManager`) to the global Task Manager (`TaskManager`) for execution. The overall relationship and interaction flow between the resources, Resource Manager, and Task Manager are illustrated in the following sequence diagram: diff --git a/docsite/docs/developer/contributor-guidance.md b/docsite/docs/developer/contributor-guidance.md new file mode 100644 index 000000000..03333938a --- /dev/null +++ b/docsite/docs/developer/contributor-guidance.md @@ -0,0 +1,53 @@ +--- +title: Contributor Guidance +--- + +# Contributor Guidance for Our Project + +Welcome and thank you for your interest in contributing to our project! We are excited to have you join our community and look forward to your valuable contributions. This document serves as a guide to help you get started with contributing to our project in a way that is efficient and aligns with our community principles. + +By contributing to our project, you'll help achieve simplicity of controlling OceanBase resource like clusters, tenants, backups and so on, making its users more easier to manage OceanBase database and combine on various versions or distributions of Kubernetes. + +Whether you are fixing bugs, adding new features, or improving documentation, your work will make a significant impact on the project and its users. + +## Code of Conduct + +Before you start contributing, we strongly encourage you to review our [Code of Conduct](https://github.com/oceanbase/ob-operator?tab=coc-ov-file). It outlines the expectations for behavior within our community and provides a transparent process for reporting unacceptable behavior. We are committed to providing a welcoming and supportive environment for all contributors. + +## Getting Started with Development + +To get started with developing for our project, please refer to our [Development Guidelines](develop-locally.md). This document provides the necessary steps to set up the development environment on your laptop. + +## Deploying Changes + +If you are working on changes that require deployment, look at our [Deployment Guide](develop-locally.md) for detailed instructions on how to deploy and test your changes in a production-like environment. This ensures that all changes are vetted for stability and compatibility before being integrated. + +## How to Contribute + +Here is a brief overview of how you can contribute to our project: + +1. Familiarize Yourself: Get to know the project by reading the documentation, understanding the codebase, and identifying the areas you are interested in. + +2. Find an Issue: Look at our issue tracker to find tasks that interest you. We also welcome contributions that improve the project in ways not yet identified in our tracker. + +3. Communicate: Before starting to work on an issue, let the community know to avoid duplicate efforts and to get any necessary input or guidance. + +4. Fork and Clone: Fork the repository and clone it to your local machine. This will be your private workspace. + +5. Make Changes: Implement your changes in your local environment adhering to our development practices and coding standards. + +6. Write Tests: Ensure your changes are tested. We strive to maintain a high level of code quality and reliability. + +7. Document Your Work: Update existing documents or create new documents as needed. Good documentation is just as important as good code. + +8. Create a Pull Request: Once your changes are ready, submit a pull request. Provide a clear description of the problem and solution, including any relevant issues\. + +9. Polish the Code: Engage with the code review process, addressing any feedback provided by the project maintainers. + +10. Get Merged: Once your pull request has been approved, it will be merged into the main codebase. + +## Need Help? + +If you have any questions or need further assistance, don't hesitate to reach out to our community via [issues](https://github.com/oceanbase/ob-operator/issues), [slack workspace](https://oceanbase.slack.com) or [dingtalk](/img/dingtalk-operator-users.png). Our maintainers and community members are here to help you and make your contributing experience enjoyable. + +Once again, thank you for your interest in contributing to our project. Your efforts will help us build a better and stronger project for everyone. We look forward to your contributions and are thrilled to have you as part of our community! diff --git a/docs/en_US/deploy-locally.md b/docsite/docs/developer/deploy-locally.md similarity index 99% rename from docs/en_US/deploy-locally.md rename to docsite/docs/developer/deploy-locally.md index eb2f7298f..c00be9f81 100644 --- a/docs/en_US/deploy-locally.md +++ b/docsite/docs/developer/deploy-locally.md @@ -19,7 +19,7 @@ You need to install the following softwares before getting started. Installation Open Docker desktop - Settings - Resources, set `CPU limit`, `Memory limit` and `Virtual disk limit` to match the hardware requirements. -![Docker Limits](../img/docker-limit.png) +![Docker Limits](/img/docker-limit.png) ### 2. Start minikube cluster diff --git a/docs/en_US/deploy.md b/docsite/docs/developer/deploy.md similarity index 94% rename from docs/en_US/deploy.md rename to docsite/docs/developer/deploy.md index 79c9967cd..e3038c55f 100644 --- a/docs/en_US/deploy.md +++ b/docsite/docs/developer/deploy.md @@ -1,7 +1,5 @@ # Deploy ob-operator -该文档也提供[中文版](../zh_CN/deploy.md)。 - This article introduces the deployment methods for ob-operator. ## 1. Deployment Dependencies @@ -14,20 +12,20 @@ ob-operator supports deployment using Helm. Before deploying ob-operator with th ```shell helm repo add ob-operator https://oceanbase.github.io/ob-operator/ -helm install ob-operator ob-operator/ob-operator --namespace=oceanbase-system --create-namespace --version=2.1.2 +helm install ob-operator ob-operator/ob-operator --namespace=oceanbase-system --create-namespace --version=2.2.0 ``` Parameters: * namespace: Namespace, can be customized. It is recommended to use "oceanbase-system" as the namespace. -* version: ob-operator version number. It is recommended to use the latest version `2.1.2`. +* version: ob-operator version number. It is recommended to use the latest version `2.2.0`. ## 2.2 Deploying with Configuration Files * Stable ```shell -kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.2_release/deploy/operator.yaml +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.2.0_release/deploy/operator.yaml ``` * Development ```shell diff --git a/docs/en_US/develop-locally.md b/docsite/docs/developer/develop-locally.md similarity index 99% rename from docs/en_US/develop-locally.md rename to docsite/docs/developer/develop-locally.md index 7f45b9ba5..ab39f6d76 100644 --- a/docs/en_US/develop-locally.md +++ b/docsite/docs/developer/develop-locally.md @@ -162,4 +162,4 @@ Type help followed by a command for full documentation. If you are first to debugging in VSCode, enter `Cmd+Shift+P` to open commands panel. Then, type `Debug: Add Configuration...` and create debugging task for Go. After creating task successfully, open commands panel and type `Debug: Start Debugging`/`Debug: Select and Start Debugging` to start debugging. -![Debug in VSCode](../img/debug-in-vscode.png) \ No newline at end of file +![Debug in VSCode](/img/debug-in-vscode.png) \ No newline at end of file diff --git a/docs/en_US/development.md b/docsite/docs/developer/development.md similarity index 95% rename from docs/en_US/development.md rename to docsite/docs/developer/development.md index 5064c2167..397efab51 100644 --- a/docs/en_US/development.md +++ b/docsite/docs/developer/development.md @@ -57,8 +57,8 @@ kubectl get crds kubectl get pods -n oceanbase-system ``` you will get something like the following -![crd](../img/crd.jpg "crd") -![controller-manager](../img/controller-manager.jpg "controller-manager") +![crd](/img/crd.jpg "crd") +![controller-manager](/img/controller-manager.jpg "controller-manager") ## check logs After deploying the crds and controller-manager, ob-operator will handle OceanBase related objects lifecycle management, you may test your own business by create a cr and make some modifications, ob-operator will handle the certain event. To test everything works properly, you can use the following command to check log message. diff --git a/docsite/docs/manual/100.what-is-ob-operator.md b/docsite/docs/manual/100.what-is-ob-operator.md new file mode 100644 index 000000000..eb9678a5a --- /dev/null +++ b/docsite/docs/manual/100.what-is-ob-operator.md @@ -0,0 +1,19 @@ +--- +sidebar_position: 1 +--- + +# Overview + +## What is ob-operator? + +ob-operator is a tool built based on the Kubernetes Operator framework for managing OceanBase clusters on Kubernetes. It provides a simple and reliable way to implement containerized deployment of OceanBase clusters and simplifies the O&M of OceanBase clusters. ob-operator defines various resources of OceanBase Database and implements the corresponding coordination logic. It supports declarative management of OceanBase Database resources in the same way as you manage native Kubernetes resources. + +## Features of ob-operator + +ob-operator provides the following features: + +* [Management of OceanBase clusters](500.ob-operator-user-guide/100.cluster-management-of-ob-operator/100.cluster-management-intro.md): cluster bootstrap, cluster topology adjustment, configuration of Kubernetes topology, cluster scaling, cluster upgrade, and parameter management. + +* [Management of OceanBase Database tenants](500.ob-operator-user-guide/200.tenant-management-of-ob-operator/000.tenant-management-intro.md): tenant creation, tenant topology adjustment, resource unit management, and user password update. + +* [High availability of OceanBase Database](500.ob-operator-user-guide/300.high-availability/100.high-availability-intro.md): backup and restore, physical standby database, and fault recovery. \ No newline at end of file diff --git a/docsite/docs/manual/200.quick-start-of-ob-operator.md b/docsite/docs/manual/200.quick-start-of-ob-operator.md new file mode 100644 index 000000000..9e23c5f40 --- /dev/null +++ b/docsite/docs/manual/200.quick-start-of-ob-operator.md @@ -0,0 +1,97 @@ +--- +sidebar_position: 2 +--- + +# Quick start + +This topic describes how to deploy ob-operator and an OceanBase cluster and use ob-operator to manage OceanBase Database. + +## Prerequisites + +Before you start the deployment, make sure that the following conditions are met: + +- You have an available Kubernetes cluster, which has at least 2 CPU cores, 10 GB of memory, and 100 GB of storage space. +- You have installed cert-manager. For more information about how to install cert-manager, see the [installation document](https://cert-manager.io/docs/installation/). +- You have installed local-path-provisioner and confirmed that the specified destination has sufficient storage space. For more information about how to install local-path-provisioner, see the documentation on [GitHub](https://github.com/rancher/local-path-provisioner). + +## Deploy ob-operator + +Run the following command to deploy ob-operator in the Kubernetes cluster: + +- Deploy the stable version of ob-operator + + ```shell + kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.0_release/deploy/operator.yaml + ``` + +- Deploy the developing version of ob-operator + + ```shell + kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/master/deploy/operator.yaml + ``` + +Run the following command to verify that ob-operator is deployed: + +```shell +kubectl get pod -n oceanbase-system +``` + +The expected output is as follows: + +```shell +NAME READY STATUS RESTARTS AGE +oceanbase-controller-manager-86cfc8f7bf-4hfnj 2/2 Running 0 1m +``` + +## Deploy an OceanBase cluster + +Perform the following steps to deploy an OceanBase cluster in the Kubernetes cluster: + +1. Create secrets + Before you create an OceanBase cluster, you must create secrets required for specific users. Run the following commands to create secrets: + + ```shell + kubectl create secret generic root-password --from-literal=password='root_password' + kubectl create secret generic proxyro-password --from-literal=password='proxyro_password' + kubectl create secret generic monitor-password --from-literal=password='monitor_password' + kubectl create secret generic operator-password --from-literal=password='operator_password' + ``` + +2. Deploy an OceanBase cluster + Run the following command to deploy an OceanBase cluster in the Kubernetes cluster: + + ```shell + kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.0_release/example/quickstart/obcluster.yaml + ``` + + In general, it takes about 2 minutes to create a cluster. Run the following command to check the cluster status: + + ```shell + kubectl get obclusters.oceanbase.oceanbase.com test + ``` + + The expected output is as follows: + + ```shell + NAME STATUS AGE + test running 6m2s + ``` + +3. Connect to the OceanBase cluster + Perform the following steps to connect to the created OceanBase cluster: + + ```shell + # Run the following command to obtain the IP address and name of the pod for the server where the OceanBase cluster is deployed. + # The pod name is in the {cluster_name}-{cluster_id}-{zone}-uuid format. + kubectl get pods -o wide + # Run the following command to connect to the cluster. + mysql -h{POD_IP} -P2881 -uroot -p'root_password' oceanbase -A -c + ``` + +If you have any questions or need help, contact OceanBase Technical Support. + +## What to do next + +This topic describes how to deploy ob-operator and an OceanBase cluster. You can use the method to quickly set up the environment. For more information about the deployment and O&M of clusters in a production environment, see [Manage clusters](500.ob-operator-user-guide/100.cluster-management-of-ob-operator/100.cluster-management-intro.md). + +After you create a cluster, you need to create a business tenant. For more information about tenant management, see [Manage OceanBase Database tenants](500.ob-operator-user-guide/200.tenant-management-of-ob-operator/000.tenant-management-intro.md). diff --git a/docsite/docs/manual/300.deploy-ob-operator.md b/docsite/docs/manual/300.deploy-ob-operator.md new file mode 100644 index 000000000..6e3ec57e0 --- /dev/null +++ b/docsite/docs/manual/300.deploy-ob-operator.md @@ -0,0 +1,81 @@ +--- +sidebar_position: 3 +--- + + +# Deploy + +This topic describes how to deploy ob-operator. + +## Prerequisites + +ob-operator depends on cert-manager. Before you deploy ob-operator, make sure that you have installed cert-manager. For more information about how to install cert-manager, see the [installation document](https://cert-manager.io/docs/installation/). + +## Use Helm to deploy ob-operator + +You can deploy ob-operator by using Helm. For more information about how to install Helm, see the documentation on [GitHub](https://github.com/helm/helm). After you install Helm, run the following command to deploy ob-operator: + +```shell +helm repo add ob-operator https://oceanbase.github.io/ob-operator/ +helm install ob-operator ob-operator/ob-operator --namespace=oceanbase-system --create-namespace --version=2.1.0 +``` + +The parameters are described as follows: + +* namespace: the namespace for ob-operator. You can specify a custom namespace as needed. We recommend that you use `oceanbase-system`. + +* version: the version of ob-operator. We recommend that you use the latest version. + +## Use configuration files to deploy ob-operator + +You can deploy ob-operator by using the configuration file for the stable or developing version of ob-operator as needed. + +* Deploy the stable version of ob-operator + + ```shell + kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.0_release/deploy/operator.yaml + ``` + +* Deploy the developing version of ob-operator + + ```shell + kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/master/deploy/operator.yaml + ``` + +We recommend that you use the configuration file for the stable version of ob-operator. + +## View the deployment result + +After the deployment is completed, you can run the following command to view the custom resource definitions (CRDs): + +```shell +kubectl get crds +``` + +If the output is similar to the following example, the CRDs are deployed: + +```shell +NAME CREATED AT +obparameters.oceanbase.oceanbase.com 2023-11-12T08:06:58Z +observers.oceanbase.oceanbase.com 2023-11-12T08:06:58Z +obtenantbackups.oceanbase.oceanbase.com 2023-11-12T08:06:58Z +obtenantrestores.oceanbase.oceanbase.com 2023-11-12T08:06:58Z +obzones.oceanbase.oceanbase.com 2023-11-12T08:06:58Z +obtenants.oceanbase.oceanbase.com 2023-11-12T08:06:58Z +obtenantoperations.oceanbase.oceanbase.com 2023-11-12T08:06:58Z +obclusters.oceanbase.oceanbase.com 2023-11-12T08:06:58Z +obtenantbackuppolicies.oceanbase.oceanbase.com 2023-11-12T08:06:58Z +``` + +Run the following command to check whether ob-operator is deployed: + +```shell +kubectl get pods -n oceanbase-system +``` + +The following result is returned. If all the containers are ready and in the running state, ob-operator is deployed. + +```shell +NAME READY STATUS RESTARTS AGE +oceanbase-controller-manager-86cfc8f7bf-4hfnj 2/2 Running 0 1m +``` diff --git a/docsite/docs/manual/400.ob-operator-upgrade.md b/docsite/docs/manual/400.ob-operator-upgrade.md new file mode 100644 index 000000000..003060d5e --- /dev/null +++ b/docsite/docs/manual/400.ob-operator-upgrade.md @@ -0,0 +1,27 @@ +--- +sidebar_position: 4 +--- + +# Upgrade + +This topic describes how to upgrade ob-operator. + +## Upgrade ob-operator by using Helm + +For more information about the chart for upgrading ob-operator, visit [Helm chart upgrade](https://atlassian.github.io/data-center-helm-charts/userguide/upgrades/HELM_CHART_UPGRADE/). + +## Upgrade ob-operator by using configuration files + +If you upgrade ob-operator by using configuration files, you only need to reapply the configuration files of the new version of ob-operator. ob-operator is upgraded after it restarts. + +- Deploy the stable version of ob-operator + + ```shell + kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.0_release/deploy/operator.yaml + ``` + +- Deploy the developing version of ob-operator + + ```shell + kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/master/deploy/operator.yaml + ``` diff --git a/docsite/docs/manual/500.configuration-of-ob-operator.md b/docsite/docs/manual/500.configuration-of-ob-operator.md new file mode 100644 index 000000000..c3427da6f --- /dev/null +++ b/docsite/docs/manual/500.configuration-of-ob-operator.md @@ -0,0 +1,90 @@ +--- +sidebar_position: 5 +--- + +# Configure + +This topic describes the startup parameters and environment variables of ob-operator, and the methods for modifying them. You can change the behavior of ob-operator by modifying the startup parameters and environment variables. + +## Startup parameters + +| Parameter | Description | Default value | Deployment configuration | +| :----------------------- | :----------------------------------------------------------------- | :-------------- | :-------------- | +| namespace | The namespace listened to by ob-operator. If you do not specify this parameter, ob-operator listens to all namespaces. | Empty | Empty | +| manager-namespace | The namespace where ob-operator runs. | oceanbase-system | oceanbase-system | +| metrics-bind-address | The service port that ob-operator uses to provide metrics for Prometheus. | :8080 | 127.0.0.1:8080 | +| health-probe-bind-address | The service port that ob-operator uses to bind the process health probe. | :8081 | :8081 | +| leader-elect | Specifies whether to elect a leader if no leader exists when ob-operator starts. | false | true | +| log-verbosity | The scope of log output. `0` specifies to output key information, `1` specifies to output debugging information, and `2` specifies to output traceability information. | 0 | 0 | + +## Environment variables + +| Environment variable | Description | Deployment configuration | +| :------------------- | :-------------------------------- | :------------------------------- | +| TELEMETRY_REPORT_HOST | The data collection endpoint of telemetry. | https://openwebapi.oceanbase.com | +| TELEMETRY_DEBUG | Specifies whether to enable DEBUG mode of telemetry. If you set the value to `true`, DEBUG mode is enabled. | Empty | +| DISABLE_WEBHOOKS | Specifies whether to disable webhook verification. If you set the value to `true`, webhook verification is disabled. | Empty | +| DISABLE_TELEMETRY | Specifies whether to disable the telemetry module. If you set the value to `true`, the telemetry module is disabled. The telemetry module collects and desensitizes the cluster environment and event information, and then it sends the information to OceanBase Database. OceanBase Database uses the information to improve ob-operator. | Empty | + +## Modify the configuration + +Open the configuration file named `operator.yaml` in the `deploy/` directory and find the `Deployment` resource named `oceanbase-controller-manager`. Then, find the container named `manager` in the containers list, and modify the startup parameters and environment variables. The following sample code snippet is taken from the `operator.yaml` configuration file as an example. + +```yaml + # Original configuration + containers: + - args: + - --health-probe-bind-address=:8081 + - --metrics-bind-address=:8080 + - --leader-elect + - --manager-namespace=oceanbase-system + - --log-verbosity=0 + command: + - /manager + env: + - name: TELEMETRY_REPORT_HOST + value: https://openwebapi.oceanbase.com +``` + +### Example: Increase the log output + +To increase the log output of ob-operator, set the `log-verbosity` parameter to 1 or 2. The larger the value, the more logs are recorded. + +```yaml + # Modified configuration + containers: + - args: + - --health-probe-bind-address=:8081 + - --metrics-bind-address=:8080 + - --leader-elect + - --manager-namespace=oceanbase-system + - --log-verbosity=2 # Set the value of log output to 2. + command: + - /manager + env: + - name: TELEMETRY_REPORT_HOST + value: https://openwebapi.oceanbase.com +``` + +### Example: Specify a resource namespace + +```yaml + # Modified configuration + containers: + - args: + - --health-probe-bind-address=:8081 + - --metrics-bind-address=:8080 + - --leader-elect + - --manager-namespace=oceanbase-system + - --log-verbosity=0 + - --namespace=oceanbase # Specify that ob-operator listens only to resources in the oceanbase namespace. + command: + - /manager + env: + - name: TELEMETRY_REPORT_HOST + value: https://openwebapi.oceanbase.com +``` + +### Apply the modified configuration to the cluster + +After you modify the configuration file, you can run the `kubectl apply -f deploy/operator.yaml` command to apply the configuration file to the cluster. You can use the same method to configure environment variables. diff --git a/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/100.cluster-management-intro.md b/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/100.cluster-management-intro.md new file mode 100644 index 000000000..3572bb1a1 --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/100.cluster-management-intro.md @@ -0,0 +1,19 @@ +# Manage clusters + +ob-operator defines the following custom resource definitions (CRDs) based on the deployment mode of OceanBase clusters: + +* `obclusters.oceanbase.oceanbase.com` defines OceanBase clusters. You can define OceanBase clusters and perform cluster O&M tasks by modifying this resource definition. +* `obzones.oceanbase.oceanbase.com` defines a specific zone and is used for O&M of the zone. Generally, you do not need to modify this resource definition. ob-operator automatically maintains this resource definition. +* `observers.oceanbase.oceanbase.com` defines a specific OBServer node and is used for O&M of the OBServer node. Generally, you do not need to modify this resource definition. ob-operator automatically maintains this resource definition. +* `obparameters.oceanbase.oceanbase.com` defines parameters of OceanBase Database and is used for O&M of parameters. Generally, you do not need to modify this resource definition. ob-operator automatically maintains this resource definition. + +You can implement the O&M of OceanBase clusters by creating or modifying `obparameters.oceanbase.oceanbase.com`. For example, you can perform the following O&M tasks: + +* [Create a cluster](200.create-cluster.md) +* [Add zones to a cluster](./300.zone-management/100.add-zone.md) +* [Delete zones from a cluster](./300.zone-management/200.delete-zone.md) +* [Add OBServer nodes to zones](./400.server-management/100.add-server.md) +* [Delete OBServer nodes from zones](./400.server-management/200.delete-server.md) +* [Upgrade a cluster](500.upgrade-cluster-of-ob-operator.md) +* [Manage parameters](600.parameter-management.md) +* [Delete a cluster](700.delete-cluster.md) diff --git a/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/200.create-cluster.md b/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/200.create-cluster.md new file mode 100644 index 000000000..f82219c85 --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/200.create-cluster.md @@ -0,0 +1,185 @@ +# Create a cluster + +This topic describes how to create an OceanBase cluster by using ob-operator. + +## Preparations before deployment + +You must have deployed ob-operator in a Kubernetes cluster. For more information, see [Deploy ob-operator](../../300.deploy-ob-operator.md). Make sure that the Kubernetes cluster has an available storage class. We recommend that you use [local-path-provisioner](https://github.com/rancher/local-path-provisioner). + +## Deploy OceanBase Database + +### Create a namespace + +Run the following command to create a namespace for deploying an OceanBase cluster. + +```shell +kubectl create namespace oceanbase +``` + +### Create secrets for default users + +Run the following command to create secrets for specific users of the cluster. + +```shell +kubectl create secret -n oceanbase generic root-password --from-literal=password='root_password' +``` + +### Define the OceanBase cluster + +You can use the YAML configuration file to define the OceanBase cluster. Here is an example: + +```yaml +apiVersion: oceanbase.oceanbase.com/v1alpha1 +kind: OBCluster +metadata: + name: test + namespace: oceanbase + annotations: + "oceanbase.oceanbase.com/independent-pvc-lifecycle": "true" + # "oceanbase.oceanbase.com/mode": "standalone" or "service" + # "oceanbase.oceanbase.com/single-pvc": "true" +spec: + clusterName: obcluster + clusterId: 1 + serviceAccount: "default" + userSecrets: + root: root-password + topology: + - zone: zone1 + replica: 1 + # nodeSelector: + # k1: v1 + # affinity: + # nodeAffinity: + # podAffinity: + # podAntiAffinity: + # tolerations: + # - key: "obtopo" + # value: "zone" + # effect: "NoSchedule" + - zone: zone2 + replica: 1 + - zone: zone3 + replica: 1 + observer: + image: oceanbase/oceanbase-cloud-native:4.2.0.0-101000032023091319 + resource: + cpu: 2 + memory: 10Gi + storage: + dataStorage: + storageClass: local-path + size: 50Gi + redoLogStorage: + storageClass: local-path + size: 50Gi + logStorage: + storageClass: local-path + size: 20Gi + monitor: + image: oceanbase/obagent:4.2.0-100000062023080210 + resource: + cpu: 1 + memory: 1Gi + + # parameters: + # - name: system_memory + # value: 2G + # backupVolume: + # volume: + # name: backup + # nfs: + # server: 1.1.1.1 + # path: /opt/nfs + # readOnly: false + +``` + +#### Parameters + +The following table describes the parameters. + +| Parameter | Description | +| --- | --- | +| metadata.name | Required. The name of the cluster, which is the name of resources in the Kubernetes cluster. | +| metadata.namespace | Required. The namespace where the cluster resides. | +| spec.clusterName | Required. The name of the OceanBase cluster. | +| spec.clusterId | Required. The ID of the OceanBase cluster. | +| spec.serviceAccount | Optional. The service account that will be bound to OBServer pods. | +| spec.userSecrets | Required. The secrets of default users of the OceanBase cluster. | +| spec.userSecrets.root | Required. The secret of the root@sys user in the OceanBase cluster. The secret must contain the `password` keyword. | +| spec.userSecrets.proxyro | Optional. The secret of the proxyro@sys user in the OceanBase cluster. The secret must contain the `password` keyword. | +| spec.userSecrets.monitor | Optional. The secret of the monitor@sys user in the OceanBase cluster. The secret must contain the `password` keyword. | +| spec.userSecrets.operator | Optional. The secret of the operator@sys user in the OceanBase cluster. The secret must contain the `password` keyword. | +| spec.topology | Required. The definition of the topology of the OceanBase cluster, which contains the definition of each zone. | +| spec.topology[i].zone | Required. The name of the zone in the OceanBase cluster. | +| spec.topology[i].replica | Required. The number of OBServer nodes in the zone. | +| spec.topology[i].nodeSelector | Optional. Specifies the distribution of pods across the OBServer nodes in the zone. The value is in the mapping format. This parameter must be used with the labels of OBServer nodes. | +| spec.topology[i].affinity | Specifies the affinity among the OBServer nodes in the zone. For more information, visit [kubernetes.io](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity). | +| spec.topology[i].tolerations | Specifies the toleration of OBServer nodes in the zone. For more information, visit [kubernetes.io](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/). | +| spec.observer.image | Required. The OBServer image of the OceanBase cluster. | +| spec.observer.resource | Required. The resource specifications of OBServer nodes. | +| spec.observer.resource.cpu | Required. The number of CPU cores for OBServer nodes. | +| spec.observer.resource.memory | Required. The memory size for OBServer nodes. | +| spec.observer.storage | Required. The storage size for OBServer nodes. | +| spec.observer.storage.dataStorage | Required. The data storage size for OBServer nodes. | +| spec.observer.storage.redoLogStorage | Required. The clog storage size for OBServer nodes. | +| spec.observer.storage.logStorage | Required. The runtime log storage size for OBServer nodes. | +| spec.observer.storage.*.storageClass | Required. The storage class required for creating a PersistentVolumeClaim (PVC). This parameter takes effect on storage configurations. | +| spec.observer.storage.*.size | Required. The size of the created PVC. This parameter takes effect on storage configurations. | +| spec.monitor | Optional. The monitoring configuration. We recommend that you enable this parameter. ob-operator uses obagent to collect monitoring data. You can connect ob-operator to Prometheus to monitor the status of the OceanBase cluster. | +| spec.monitor.image | Required. The image used for monitoring. | +| spec.monitor.resource | Required. The resources allocated to the monitoring container. | +| spec.monitor.resource.cpu | Required. The number of CPU cores allocated to the monitoring container. | +| spec.monitor.resource.memory | Required. The memory size allocated to the monitoring container. | +| spec.parameters | The optional custom parameter of the OceanBase cluster. This parameter takes effect globally in the cluster. | +| spec.parameters[i].name | Required. The name of the parameter. | +| spec.parameters[i].value | Required. The value of the parameter. | +| spec.backupVolume | Optional. The backup storage for the OceanBase cluster. If you want to enable the backup feature and do not use Alibaba Cloud Object Storage Service (OSS) for backup storage, you need to specify this parameter. You can configure a Network File System (NFS) volume. | + + +#### Annotations + +The following table describes available annotations. For short, the annotation `annotation` implies there is an `oceanbase.oceanbase.com/` in front of it. + +| Annotation | Description | +| -- | -- | +| `independent-pvc-lifecycle` | `true`: PVCs won't be deleted even if the OBCluster is deleted. | +| `mode` | `standalone`: Bootstrap the single-node cluster with 127.0.0.1, which cannot contact other nodes any more.
`service`: Create a specific K8s service for each OBServer and use the service's `ClusterIP` as the OBServer's IP address. | +| `single-pvc` | `true`: Create and bind a single PVC to a OBServer pod (three PVCs by default). | + +### Create a cluster + +After you save the configuration file, run the following command to create an OceanBase cluster in the Kubernetes cluster: + +```shell +kubectl apply -f obcluster.yaml +``` + +In general, it takes about 2 minutes to create a cluster. Run the following command to query the cluster status. If the cluster status changes to `Running`, the cluster is created. + +```shell +kubectl get obclusters.oceanbase.oceanbase.com test -n oceanbase + +# desired output +NAME STATUS AGE +test running 6m2s +``` + +## Connect to the cluster + +Run the following command to obtain the IP address of the pod for the server where the cluster is deployed. The pod name is in the `{cluster_name}-{cluster_id}-{zone}-uuid` format. + +```shell +kubectl get pods -n oceanbase -o wide +``` + +Run the following command to connect to the pod: + +```shell +mysql -h{POD_IP} -P2881 -uroot -proot_password oceanbase -A -c +``` + +## What to do next + +After the cluster is created, you must create a tenant for your business. For more information, see [Manage tenants](../200.tenant-management-of-ob-operator/000.tenant-management-intro.md). diff --git a/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/300.zone-management/100.add-zone.md b/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/300.zone-management/100.add-zone.md new file mode 100644 index 000000000..18e23afe0 --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/300.zone-management/100.add-zone.md @@ -0,0 +1,71 @@ +# Add zones to a cluster + +This topic describes how to add zones to a cluster. + +## Prerequisites + +Before you add a zone to a cluster, make sure that the following conditions are met: + +* The server must have sufficient resources for the new zone. +* The OceanBase cluster is in the `Running` state. + +## Procedure + +Assume that the current cluster has three zones, `zone1`, `zone2`, and `zone3`, and each zone contains one OBServer node. You can perform the following steps to scale out the cluster to one that consists of five zones. + +1. Modify the `spec.topology` parameter in the `obcluster.yaml` configuration file to add `zone4` and `zone5`. For more information about the complete configuration file, see [Create a cluster](../200.create-cluster.md). + + ```yaml + # For example, assume that an OceanBase cluster has three zones. + topology: + - zone: zone1 + replica: 1 + - zone: zone2 + replica: 1 + - zone: zone3 + replica: 1 + + # Add zone4 and zone5 to the cluster. + topology: + - zone: zone1 + replica: 1 + - zone: zone2 + replica: 1 + - zone: zone3 + replica: 1 + - zone: zone4 + replica: 1 + - zone: zone5 + replica: 1 + ``` + +2. Run the following command for the modification to take effect: + + ```yaml + kubectl apply -f obcluster.yaml + ``` + +3. Query the status of custom resources in the OceanBase cluster to check whether the operation succeeds. + +Run the following command to query the status of custom resources in the OceanBase cluster. If the cluster and the five zones are in the `Running` state, the operation is successful. + +```shell +kubectl get obclusters.oceanbase.oceanbase.com test -n oceanbase -o yaml + +# desired output, only displays status here +status: + image: oceanbase/oceanbase-cloud-native:4.2.0.0-101000032023091319 + obzones: + - status: running + zone: obcluster-1-zone1 + - status: running + zone: obcluster-1-zone2 + - status: running + zone: obcluster-1-zone3 + - status: running + zone: obcluster-1-zone4 + - status: running + zone: obcluster-1-zone5 + parameters: [] + status: running +``` diff --git a/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/300.zone-management/200.delete-zone.md b/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/300.zone-management/200.delete-zone.md new file mode 100644 index 000000000..4660a1b25 --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/300.zone-management/200.delete-zone.md @@ -0,0 +1,68 @@ +# Delete zones from a cluster + +This topic describes how to delete zones from a cluster. + +## Prerequisites + +Before you delete a zone from a cluster, make sure that the following conditions are met: + +* The OceanBase cluster is in the `Running` state. +* After the zone is deleted, the available zones must be the majority. + +## Procedure + +Assume that the current cluster has five zones, `zone1`, `zone2`, `zone3`, `zone4`, and `zone5`, and each zone contains one OBServer node. You can perform the following steps to scale in the cluster to three zones. + +1. Modify the `spec.topology` parameter in the `obcluster.yaml` configuration file to delete zone4 and zone5. For more information about the complete configuration file, see [Create a cluster](../200.create-cluster.md). + + ```yaml + # For example, the OceanBase cluster has five zones. + topology: + - zone: zone1 + replica: 1 + - zone: zone2 + replica: 1 + - zone: zone3 + replica: 1 + - zone: zone4 + replica: 1 + - zone: zone5 + replica: 1 + + # Delete zone4 and zone5 from the cluster. + topology: + - zone: zone1 + replica: 1 + - zone: zone2 + replica: 1 + - zone: zone3 + replica: 1 + + ``` + +2. Run the following command for the modification to take effect: + + ```yaml + kubectl apply -f obcluster.yaml + ``` + +3. Query the status of custom resources in the OceanBase cluster to check whether the operation succeeds. + +Run the following command to query the status of custom resources in the OceanBase cluster. If the cluster and the three zones are in the `Running` state, the operation is successful. + +```shell +kubectl get obclusters.oceanbase.oceanbase.com test -n oceanbase -o yaml + +# desired output, only displays status here +status: + image: oceanbase/oceanbase-cloud-native:4.2.0.0-101000032023091319 + obzones: + - status: running + zone: obcluster-1-zone1 + - status: running + zone: obcluster-1-zone2 + - status: running + zone: obcluster-1-zone3 + parameters: [] + status: running +``` diff --git a/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/300.zone-management/_category_.yml b/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/300.zone-management/_category_.yml new file mode 100644 index 000000000..02a664adb --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/300.zone-management/_category_.yml @@ -0,0 +1,4 @@ +label: Zone management +position: 1 +link: + type: generated-index \ No newline at end of file diff --git a/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/400.server-management/100.add-server.md b/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/400.server-management/100.add-server.md new file mode 100644 index 000000000..066dea551 --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/400.server-management/100.add-server.md @@ -0,0 +1,77 @@ +# Add OBServer nodes to zones + +This topic describes how to scale out a cluster by adding OBServer nodes to zones in the cluster. + +## Prerequisites + +Before you add an OBServer node to a zone, make sure that the following conditions are met: + +* The server has sufficient resources for the new OBServer node. +* The OceanBase cluster is in the `Running` state. + +## Procedure + +Assume that the current cluster has three zones, `zone1`, `zone2`, and `zone3`, each zone contains one OBServer node, and you want to add one OBServer node to each zone so that each zone contains two OBServer nodes. Perform the following steps: + +1. Open the `obcluster.yaml` configuration file and change the value of the `replica` parameter of each zone from `1` to `2`. + + ```yaml + # For example, assume that an OceanBase cluster has three zones. + topology: + - zone: zone1 + replica: 1 + - zone: zone2 + replica: 1 + - zone: zone3 + replica: 1 + + # Add an OBServer node to each zone. + topology: + - zone: zone1 + replica: 2 + - zone: zone2 + replica: 2 + - zone: zone3 + replica: 2 + ``` + +2. Run the following command for the modification to take effect: + + ```shell + kubectl apply -f obcluster.yaml + ``` + +3. Query the status of custom resources in the OceanBase cluster to check whether the operation succeeds. + +Run the following command to query the status of custom resources in the OceanBase cluster. + +```shell +kubectl get obclusters.oceanbase.oceanbase.com test -n oceanbase -o yaml + +# obcluster desired output, only displays status here +status: + image: oceanbase/oceanbase-cloud-native:4.2.0.0-101000032023091319 + obzones: + - status: running + zone: obcluster-1-zone1 + - status: running + zone: obcluster-1-zone2 + - status: running + zone: obcluster-1-zone3 + parameters: [] + status: running +``` + +Run the following command to check whether the number of OBServer nodes is correct and whether they are all in the `Running` state: + +```shell +kubectl get observers.oceanbase.oceanbase.com -n oceanbase + +# observer desired output, only displays status here +oceanbase obcluster-1-zone1-7b0e9f7e7675 10.42.0.241 running 7h48m +oceanbase obcluster-1-zone2-67f3d1fe0b40 10.42.0.251 running 28m +oceanbase obcluster-1-zone3-914ef208ac46 10.42.0.252 running 28m +oceanbase obcluster-1-zone2-2336549ba883 10.42.0.19 running 3m15s +oceanbase obcluster-1-zone3-d7011a909e2b 10.42.0.26 running 3m10s +oceanbase obcluster-1-zone1-0f5d712adb19 10.42.0.27 running 3m10s +``` diff --git a/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/400.server-management/200.delete-server.md b/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/400.server-management/200.delete-server.md new file mode 100644 index 000000000..f66890e5c --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/400.server-management/200.delete-server.md @@ -0,0 +1,71 @@ +# Delete OBServer nodes from zones + +This topic describes how to scale in a cluster by removing OBServer nodes from zones in the cluster. + +## Prerequisites + +* The OceanBase cluster is in the `Running` state. +* After the OBServer nodes are deleted, the cluster has sufficient resources for the units of tenants. + +## Procedure + +Assume that the current cluster has three zones, `zone1`, `zone2`, and `zone3`, each zone contains two OBServer nodes, and you want to delete one OBServer node from each zone so that each zone contains one OBServer node. + +1. Open the `obcluster.yaml` configuration file and change the value of the `replica` parameter of each zone from `2` to `1`. + + ```yaml + # For example, assume that an OceanBase cluster has three zones. + topology: + - zone: zone1 + replica: 2 + - zone: zone2 + replica: 2 + - zone: zone3 + replica: 2 + + # Delete an OBServer node from each zone. + topology: + - zone: zone1 + replica: 1 + - zone: zone2 + replica: 1 + - zone: zone3 + replica: 1 + ``` + +2. Run the following command for the modification to take effect: + + ```yaml + kubectl apply -f obcluster.yaml + ``` + +3. Query the status of custom resources in the OceanBase cluster to check whether the operation succeeds. + Run the following command to query the status of the OceanBase cluster. + +```shell +kubectl get obclusters.oceanbase.oceanbase.com test -n oceanbase -o yaml + +# obcluster desired output, only displays status here +status: + image: oceanbase/oceanbase-cloud-native:4.2.0.0-101000032023091319 + obzones: + - status: running + zone: obcluster-1-zone1 + - status: running + zone: obcluster-1-zone2 + - status: running + zone: obcluster-1-zone3 + parameters: [] + status: running +``` + +Run the following command to check whether the number of OBServer nodes is correct and whether they are all in the `Running` state: + +``` +kubectl get observers.oceanbase.oceanbase.com -n oceanbase + +# observer desired output, only displays status here +oceanbase obcluster-1-zone1-7b0e9f7e7675 10.42.0.241 running 7h48m +oceanbase obcluster-1-zone2-67f3d1fe0b40 10.42.0.251 running 28m +oceanbase obcluster-1-zone3-914ef208ac46 10.42.0.252 running 28m +``` diff --git a/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/400.server-management/_category_.yml b/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/400.server-management/_category_.yml new file mode 100644 index 000000000..d958a99a9 --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/400.server-management/_category_.yml @@ -0,0 +1,4 @@ +label: Server management +position: 2 +link: + type: generated-index \ No newline at end of file diff --git a/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/500.upgrade-cluster-of-ob-operator.md b/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/500.upgrade-cluster-of-ob-operator.md new file mode 100644 index 000000000..ce0eb6890 --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/500.upgrade-cluster-of-ob-operator.md @@ -0,0 +1,51 @@ +# Upgrade a cluster + +This topic describes how to upgrade an OceanBase cluster that is deployed by using ob-operator. + +## Prerequisites + +Before you upgrade a cluster, make sure that the cluster is in the `Running` state. + +## Procedure + +### Modify the tag setting in `spec` + +1. Modify the configuration file of the OceanBase cluster. For more information about the complete configuration file, see [Create a cluster](200.create-cluster.md). Change the value of the `spec.observer.image` parameter to the target image. + + ```yaml + # Before modification + spec: + observer: + image: oceanbase/oceanbase-cloud-native:4.2.0.0-101000032023091319 + + # After modification + spec: + observer: + image: oceanbase/oceanbase-cloud-native:4.2.1.1-101000062023110109 + ``` + +2. Run the following command for the modification to take effect: + + ```yaml + kubectl apply -f obcluster.yaml + ``` + +3. Query the status of custom resources in the OceanBase cluster to check whether the operation succeeds. + Run the following command to query the status of custom resources in the OceanBase cluster. If the cluster is in the `Running` state and the value of the `image` parameter is the target image, the cluster is upgraded. + +```shell +kubectl get obclusters.oceanbase.oceanbase.com test -n oceanbase -o yaml + +# desired output, only displays status here +status: + image: oceanbase/oceanbase-cloud-native:4.2.1.1-101000062023110109 + obzones: + - status: running + zone: obcluster-1-zone1 + - status: running + zone: obcluster-1-zone2 + - status: running + zone: obcluster-1-zone3 + parameters: [] + status: running +``` diff --git a/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/600.parameter-management.md b/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/600.parameter-management.md new file mode 100644 index 000000000..667896400 --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/600.parameter-management.md @@ -0,0 +1,47 @@ +# Manage parameters + +This topic describes how to modify the parameters of an OceanBase cluster by using ob-operator. + +## Prerequisites + +Make sure that the OceanBase cluster is in the `Running` state. + +## Procedure + +### Modify the tag setting in `spec` + +1. Modify the configuration file of the OceanBase cluster. You need to specify the parameter that you want to modify in `spec.parameters`. For more information about the complete configuration file, see [Create a cluster](200.create-cluster.md). + + ```yaml + # Before modification + # parameters: + # - name: system_memory + # value: 2G + + # After modification + parameters: + - name: system_memory + value: 2G + ``` + +2. Run the following command for the modification to take effect: + + ```yaml + kubectl apply -f obcluster.yaml + ``` + +3. Query the status of custom resources in the OceanBase cluster to check whether the operation succeeds. + Run the following command to query the status of the OceanBase cluster. + + ```shell + kubectl get obclusters.oceanbase.oceanbase.com test -n oceanbase -o yaml + + # desired output, only displays status and one result here + status: + parameter: + - name: system_memory + server: 10.42.0.232:2882 + value: 2G + zone: zone1 + status: matched + ``` diff --git a/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/650.update-resources.md b/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/650.update-resources.md new file mode 100644 index 000000000..ec8ca7104 --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/650.update-resources.md @@ -0,0 +1,102 @@ +# Update resources + +After the cluster is created and running, we may need to adjust the resource configuration of the OBServer node, such as CPU, memory, and storage volumes. This article introduces the resource configuration that can be modified and the specific operations. + +## Scale up: Modify CPU and memory resources + +
+

Notes

+

Only the standalone mode cluster supports this operation.

+
+ +Assuming that we have created a single-node standalone cluster with a resource specification of 2C+10G. The configuration in YAML format is as follows: + +```yaml + observer: + # ... + resource: + cpu: 2 + memory: 10Gi + # ... +``` + +If you find that the resources are insufficient after running for a period of time and need to be expanded, you can directly modify this part of the configuration. For example, in the following YAML fragment, we have expanded the resource specification of the OBServer to 4C+16G. + +```yaml + observer: + # ... + resource: + cpu: 4 + memory: 16Gi + # ... +``` + +Upon modifying the YAML, apply it to the Kubernetes cluster. ob-operator will then perform the cluster's scale-up expansion. Once the OBCluster transitions back to a `running` state, the expansion is complete. + +```shell +kubectl apply -f obcluster.yaml +kubectl get obcluster -w + +NAME STATUS AGE +test scale up obzone xxx +test scale up obzone xxx +... +test running xxx +``` + +## Dynamically expand PVC + +
+

Notes

+

This operation requires that the storage class used by the cluster supports the AllowVolumeExpansion feature.

+
+ +Assuming that we have deployed an OBCluster, the storage configuration is shown in the following YAML fragment: + +```yaml + observer: + # ... + storage: + dataStorage: + storageClass: my-storage + size: 50Gi + redoLogStorage: + storageClass: my-storage + size: 50Gi + logStorage: + storageClass: my-storage + size: 20Gi + # ... +``` + +To expand the mounted volume, increase the `size` value in the YAML fragment and apply the changes via kubectl. ob-operator will handle the PVC expansion. Note that `size` can only be increased. + +After modification, the configuration is as follows: + +```yaml + observer: + # ... + storage: + dataStorage: + storageClass: my-storage + size: 60Gi + redoLogStorage: + storageClass: my-storage + size: 60Gi + logStorage: + storageClass: my-storage + size: 30Gi + # ... +``` + +```shell +kubectl apply -f obcluster.yaml +kubectl get obcluster -w + +NAME STATUS AGE +test expand pvc xxx +test expand pvc xxx +... +test running xxx +``` + diff --git a/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/700.delete-cluster.md b/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/700.delete-cluster.md new file mode 100644 index 000000000..63cb2073b --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/700.delete-cluster.md @@ -0,0 +1,43 @@ +# Delete a cluster + +This topic describes how to delete an OceanBase cluster by using ob-operator. + +## Procedure + +1. Run the following command to delete a specific OceanBase cluster: + + ```shell + kubectl delete obclusters.oceanbase.oceanbase.com test -n oceanbase + ``` + +2. Check whether the cluster and related resources are deleted. + +* If you run the following command to query the deleted OceanBase cluster, no information about the resource is returned: + + ```shell + kubectl get obclusters.oceanbase.oceanbase.com -n oceanbase + ``` + +* If you run the following command to query the deleted zone, no information about the resource is returned: + + ```shell + kubectl get obzones.oceanbase.oceanbase.com -n oceanbase + ``` + +* If you run the following command to query the deleted OBServer node, no information about the resource is returned: + + ```shell + kubectl get observers.oceanbase.oceanbase.com -n oceanbase + ``` + +* Check whether the pods are deleted: + + ```shell + kubectl get pods -n oceanbase + ``` + +* Check whether the PersistentVolumeClaim (PVC) is deleted: + + ```shell + kubectl get pvc -n oceanbase + ``` diff --git a/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/_category_.yml b/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/_category_.yml new file mode 100644 index 000000000..12a301e0a --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/_category_.yml @@ -0,0 +1,4 @@ +label: Cluster management +position: 1 +link: + type: generated-index \ No newline at end of file diff --git a/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/000.tenant-management-intro.md b/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/000.tenant-management-intro.md new file mode 100644 index 000000000..89aba6ecd --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/000.tenant-management-intro.md @@ -0,0 +1,15 @@ +# Manage tenants + +ob-operator defines the following resources for OceanBase Database tenants: + +* `obtenants.oceanbase.oceanbase.com`: defines OceanBase Database tenants. You can create or modify this resource for tenant O&M. +* `obtenantoperations.oceanbase.oceanbase.com`: defines O&M operations on OceanBase Database tenants, such as password change, switchover, and failover. + +You can create or modify custom resource definitions (CRDs) for the following tenant O&M operations: + +* [Create a tenant](100.create-tenant.md) +* [Change tenant resources](./200.modify-tenant-of-ob-operator/100.resource-management-of-ob-operator.md) +* [Modify the locality of a tenant](./200.modify-tenant-of-ob-operator/200.replica-management-of-ob-operator.md) +* [Modify configurations of a tenant](./200.modify-tenant-of-ob-operator/300.other-configuration-item-modifications-of-ob-operator.md) +* [Delete a tenant](300.delete-tenant-of-ob-operator.md) +* [Perform other tenant O&M operations](400.tenant-operation.md) diff --git a/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/100.create-tenant.md b/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/100.create-tenant.md new file mode 100644 index 000000000..74990adf6 --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/100.create-tenant.md @@ -0,0 +1,288 @@ +# Create a tenant + +This topic describes how to create a tenant by using ob-operator. + +## Prerequisites + +Before you create a tenant, make sure the following conditions are met: + +* You have deployed ob-operator V2.1.0 or later. + +* You have deployed an OceanBase cluster, which is running normally. + +## Create a tenant by using the configuration file + +You can create a tenant by using the configuration file of the tenant. For more information about the configuration file, visit [GitHub](https://github.com/oceanbase/ob-operator/blob/2.1.0_release/deploy/tenant.yaml). + +Run the following command to create a tenant. This command creates an OceanBase Database tenant with custom resources in the current Kubernetes cluster. + +```shell +kubectl apply -f tenant.yaml +``` + +## Example + +Create a MySQL tenant named `t1` with three replicas and allow all clients to connect to the tenant. + +During the creation of the tenant, ob-operator creates resource units and resource pools based on the zones in the pools specified in the `tenant.yaml` configuration file. ob-operator creates resource units based on the parameter settings in the `resource` section and creates resource pools based on the resource units. + +```yaml +apiVersion: oceanbase.oceanbase.com/v1alpha1 +kind: OBTenant +metadata: + name: t1 + namespace: oceanbase +spec: + obcluster: obcluster + tenantName: t1 + unitNum: 1 + charset: utf8mb4 + connectWhiteList: '%' + forceDelete: true + credentials: # optional + root: t1-ro # optional, empty root password if not given + standbyRo: t1-ro # optional, generate automatically if not given + pools: + - zone: zone1 + type: + name: Full + replica: 1 + isActive: true + resource: + maxCPU: 1 + minCPU: 1 + memorySize: 5Gi + maxIops: 1024 + minIops: 1024 + iopsWeight: 2 + logDiskSize: 12Gi + - zone: zone2 + type: + name: Full + replica: 1 + isActive: true + resource: + maxCPU: 1 + minCPU: 1 + memorySize: 5Gi + maxIops: 1024 + minIops: 1024 + iopsWeight: 2 + logDiskSize: 12Gi + - zone: zone3 + type: + name: Full + replica: 1 + isActive: true + priority: 3 + resource: + maxCPU: 1 + minCPU: 1 + memorySize: 5Gi + maxIops: 1024 + minIops: 1024 + iopsWeight: 2 + logDiskSize: 12Gi +``` + +The following table describes the parameters. + +| Parameter | Description | +| --- | --- | +| metadata.name | Required. The name of the tenant resource, which must be unique in the same namespace of the Kubernetes cluster. | +| metadata.namespace | Required. The namespace where the tenant resources are located. | +| obcluster | Required. The name of the OceanBase cluster in which the tenant is to be created. | +| tenantName | Required. The name of the tenant. Like a variable, a tenant name can contain up to 128 characters, which can be letters, digits, and underscores (`_`). The tenant name must start with a letter or an underscore (`_`) and cannot be a keyword of OceanBase Database. For more information about the keywords supported by OceanBase Database, see [Reserved keywords (MySQL mode)](https://en.oceanbase.com/docs/common-oceanbase-database-10000000001103417) or [Reserved keywords (Oracle mode)](https://en.oceanbase.com/docs/common-oceanbase-database-10000000001103416). | +| unitNum | Required. The number of resource units to be created for the zone. The value must be less than the number of OBServer nodes in the zone. | +| charset | Optional. The character set of the tenant. For more information about character sets, see [Character sets](https://en.oceanbase.com/docs/common-oceanbase-database-10000000001106482). This parameter is set to `utf8mb4` by default. | +| collate | Optional. The collation of the tenant. For more information about collations, see [Collations](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000222182). | +| connectWhiteList | Optional. The IP addresses of the clients that are allowed to connect to the tenant. `%` indicates that all client IP addresses are allowed to connect to the tenant. The default value is `%`. When you modify this parameter, the value must include the CIDR block of ob-operator; otherwise, ob-operator cannot connect to the tenant. | +| forceDelete | Optional. Specifies whether to forcibly delete the tenant. The default value is `false`. | +| credentials | Optional. The secret resources referenced for creating the user and changing the password when you create the tenant. You can specify the passwords of the root account and the standbyro account. If you do not specify this parameter, the password is not changed. | +| pools | The topology of the tenant, which defines the replica and resource distribution of the tenant in each zone. | +| type.name | Required. The type of replicas in the zone. The valid values are `full` and `readonly`. This parameter is case insensitive. | +| type.replica | Optional. The number of replicas in the zone. This parameter is set to `1` by default. | +| type.isActive | Specifies whether to enable the zone. | +| priority | Optional. The priority of the current zone. A larger number indicates a higher priority. This parameter is set to 0 by default. | +| resource | The resource information of the tenant in the zone. | +| maxCPU | Required. The maximum number of CPU cores provided by a resource unit in the zone for the tenant. The minimum value is `1`. | +| minCPU | Optional. The minimum number of CPU cores provided by a resource unit in the zone for the tenant. This parameter is equal to the value of the `maxCPU` parameter by default. | +| memorySize | Required. The size of memory provided by a resource unit in the zone for the tenant. The minimum value is `1GB`. Take note of the value of the cluster parameter `__min_full_resource_pool_memory` when you specify this parameter. | +| maxIops | Optional. The maximum I/O resources provided by a resource unit in the zone for the tenant. | +| minIops | Optional. The minimum I/O resources provided by a resource unit in the zone for the tenant. | +| iopsWeight | Optional. The weight of the tenant for using I/O resources provided by a resource unit in the zone. The default value is `1`. | +| logDiskSize | Optional. The size of log space provided by a resource unit in the zone for the tenant. The default value is three times the memory size. The minimum value is `2Gi`. | + +## Verify whether the tenant is created + +After the tenant creation process is completed, run the following command to check whether the current Kubernetes cluster contains the custom resources of the created tenant and whether the status of the custom resource is `Running`. The related configurations are displayed in the `status` section. + +```shell +kubectl describe obtenants.oceanbase.oceanbase.com -n oceanbase t1 +``` + +Here is a sample result: + +```shell +Name: t1 +Namespace: oceanbase +Labels: +Annotations: +API Version: oceanbase.oceanbase.com/v1alpha1 +Kind: OBTenant +Metadata: + Creation Timestamp: 2023-11-13T07:28:31Z + Finalizers: + finalizers.oceanbase.com.deleteobtenant + Generation: 2 + Resource Version: 940236 + UID: 34036a49-26bf-47cf-8201-444b3850aaa2 +Spec: + Charset: utf8mb4 + Connect White List: % + Credentials: + Root: t1-ro + Standby Ro: t1-ro + Force Delete: true + Obcluster: obcluster + Pools: + Priority: 1 + Resource: + Iops Weight: 2 + Log Disk Size: 12Gi + Max CPU: 1 + Max Iops: 1024 + Memory Size: 5Gi + Min CPU: 1 + Min Iops: 1024 + Type: + Is Active: true + Name: Full + Replica: 1 + Zone: zone1 + Priority: 1 + Resource: + Iops Weight: 2 + Log Disk Size: 12Gi + Max CPU: 1 + Max Iops: 1024 + Memory Size: 5Gi + Min CPU: 1 + Min Iops: 1024 + Type: + Is Active: true + Name: Full + Replica: 1 + Zone: zone2 + Priority: 3 + Resource: + Iops Weight: 2 + Log Disk Size: 12Gi + Max CPU: 1 + Max Iops: 1024 + Memory Size: 5Gi + Min CPU: 1 + Min Iops: 1024 + Type: + Is Active: true + Name: Full + Replica: 1 + Zone: zone3 + Tenant Name: t1 + Tenant Role: PRIMARY + Unit Num: 1 +Status: + Credentials: + Root: t1-ro + Standby Ro: t1-ro + Resource Pool: + Priority: 1 + Type: + Is Active: true + Name: FULL + Replica: 1 + Unit Config: + Iops Weight: 2 + Log Disk Size: 12884901888 + Max CPU: 1 + Max Iops: 1024 + Memory Size: 5368709120 + Min CPU: 1 + Min Iops: 1024 + Unit Num: 1 + Units: + Migrate: + Server IP: + Server Port: 0 + Server IP: 10.42.0.189 + Server Port: 2882 + Status: ACTIVE + Unit Id: 1006 + Zone List: zone1 + Priority: 1 + Type: + Is Active: true + Name: FULL + Replica: 1 + Unit Config: + Iops Weight: 2 + Log Disk Size: 12884901888 + Max CPU: 1 + Max Iops: 1024 + Memory Size: 5368709120 + Min CPU: 1 + Min Iops: 1024 + Unit Num: 1 + Units: + Migrate: + Server IP: + Server Port: 0 + Server IP: 10.42.1.118 + Server Port: 2882 + Status: ACTIVE + Unit Id: 1007 + Zone List: zone2 + Priority: 2 + Type: + Is Active: true + Name: FULL + Replica: 1 + Unit Config: + Iops Weight: 2 + Log Disk Size: 12884901888 + Max CPU: 1 + Max Iops: 1024 + Memory Size: 5368709120 + Min CPU: 1 + Min Iops: 1024 + Unit Num: 1 + Units: + Migrate: + Server IP: + Server Port: 0 + Server IP: 10.42.0.190 + Server Port: 2882 + Status: ACTIVE + Unit Id: 1008 + Zone List: zone3 + Status: running + Tenant Record Info: + Charset: utf8mb4 + Connect White List: % + Locality: FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 + Pool List: pool_t1_zone1,pool_t1_zone2,pool_t1_zone3 + Primary Zone: zone3;zone1,zone2 + Tenant ID: 1006 + Unit Num: 1 + Zone List: zone1,zone2,zone3 + Tenant Role: PRIMARY +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal 2m58s obtenant-controller start creating + Normal 115s obtenant-controller create OBTenant successfully +``` + +## What to do next + +After the tenant is created, the password of its administrator account is the value of `secret` specified in the `spec.credentials.root` field. If you have not specified the `secret` field, the password is empty. You can use the `obclient -h${podIP} -P2881 -uroot@tenantname -p -A` or `mysql -h${podIP} -P2881 -uroot@tenantname -p -A` statement to log on to the database. diff --git a/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/100.resource-management-of-ob-operator.md b/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/100.resource-management-of-ob-operator.md new file mode 100644 index 000000000..e1ba8e76a --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/100.resource-management-of-ob-operator.md @@ -0,0 +1,135 @@ +# Manage resources + +This topic describes how to change the resource specifications and pools of a tenant by using ob-operator. + +Tenant resources consist of tenant resource specifications and tenant resource pools. You can change tenant resource specifications and resource pools to scale in or out a tenant. + +## Change resource specifications + +You can increase or decrease the CPU, memory, and log disk capacities to change the resource specifications. + +For more information about how to change resource specifications, see [Change resource specifications](https://en.oceanbase.com/docs/common-oceanbase-database-10000000001106043). + +### Procedure + +To change the resource unit specifications of a zone, apply the parameters in the `resource` section of the zone in the tenant configuration file `tenant.yaml`. Perform the following steps: + +1. Modify the tenant configuration file `tenant.yaml`. + + ```yaml + # For example, the value of maxCPU is 1 before the modification. + resource: + maxCPU: 1 + memorySize: 1Gi + + # After the modification, the value of maxCPU is changed to 2. + resource: + maxCPU: 2 # Change the value from 1 to 2. + memorySize: 1Gi + ``` + +2. Run the following command for the modification to take effect: + + ```shell + kubectl apply -f tenant.yaml + ``` + +3. Run the following command to view the custom resources of the tenant in the current Kubernetes cluster to check whether the modification is successful: + + ```shell + kubectl get obtenants.oceanbase.oceanbase.com -n oceanbase -o yaml + ``` + +If the value of the corresponding parameter in the `status.pools.resource` section in the custom resources of the tenant is changed to the new value, the modification is successful. + +```yaml + status: + ... + resourcePool: + - priority: 1 + type: + isActive: true + name: FULL + replica: 1 + unitConfig: + iopsWeight: 2 + logDiskSize: "12884901888" + maxCPU: "2" # The value of maxCPU is changed to 2. + maxIops: 1024 + memorySize: "5368709120" + minCPU: "1" + minIops: 1024 + unitNum: 1 + units: + - migrate: + serverIP: "" + serverPort: 0 + serverIP: xxx.xxx.xxx.xxx + serverPort: 2882 + status: ACTIVE + unitId: 1006 + zoneList: zone1 +``` + +## Change the number of resource units for a resource pool + +Before you increase the resource units for a resource pool, make sure that the zone has sufficient OBServer nodes. For more information about how to add OBServer nodes to a zone, see [Add OBServer nodes to zones](https://en.oceanbase.com/docs/common-oceanbase-database-10000000001107536). + +### Procedure + +When you modify the number of resource units for a resource pool, apply the `unitNum` parameter of each zone in the `pools` section in the tenant configuration file `tenant.yaml`. Perform the following steps: + +1. Modify the tenant configuration file `tenant.yaml`. + + ```yaml + # For example, the number of resource units in each zone of the tenant is 1 before the modification. + spec: + unitNum: 1 + + # After the modification, the value of unitNum is 2. + spec: + unitNum: 2 + ``` + +2. Run the following command for the modification to take effect: + + ```shell + kubectl apply -f tenant.yaml + ``` + +3. Run the following command to view the custom resources of the tenant in the current Kubernetes cluster to check whether the modification is successful: + + ```shell + kubectl get obtenants.oceanbase.oceanbase.com -n oceanbase -o yaml + ``` + +If the value of the corresponding parameter in the `status.resourcePool.unitNum` section in the custom resources of the tenant is changed to the new value, the modification is successful. + +```yaml + status: + ... + resourcePool: + - priority: 1 + type: + isActive: true + name: FULL + replica: 1 + unitConfig: + iopsWeight: 2 + logDiskSize: "12884901888" + maxCPU: "1" + maxIops: 1024 + memorySize: "5368709120" + minCPU: "1" + minIops: 1024 + unitNum: 2 # The value of unitNum is changed to 2. + units: + - migrate: + serverIP: "" + serverPort: 0 + serverIP: 10.42.0.189 + serverPort: 2882 + status: ACTIVE + unitId: 1006 + zoneList: zone1 +``` diff --git a/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/200.replica-management-of-ob-operator.md b/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/200.replica-management-of-ob-operator.md new file mode 100644 index 000000000..251663ee0 --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/200.replica-management-of-ob-operator.md @@ -0,0 +1,277 @@ +# Manage replicas + +This topic describes how to manage tenant replicas by using ob-operator. + +## Modify the primary zone of a tenant + +You can modify the `priority` parameter of zones in the tenant configuration file to modify the primary zone of a tenant. A larger number indicates a higher priority. The minimum value is `1`. + +The primary zone describes the preferred location of the leader. The leader handles strong-consistency read traffic and write traffic of the business. Therefore, the primary zone determines the traffic distribution of OceanBase Database. You can modify the primary zone to switch business traffic from one IDC to another or from one city to another in disaster recovery and scaling scenarios. + +### Procedure + +1. Modify the tenant configuration file `tenant.yaml` to adjust the priority value for each zone. + + ```yaml + - zone: zone1 + priority: 1 + - zone: zone2 + priority: 1 + - zone: zone3 + priority: 3 + + # After modification + - zone: zone1 + priority: 3 + - zone: zone2 + @priority 2 + - zone: zone3 + priority: 1 + ``` + + The preceding configuration changes the primary zone of the tenant from `zone3;zone1,zone2` to `zone1;zone2;zone3`. + +2. Run the following command for the modification to take effect: + + ```shell + kubectl apply -f tenant.yaml + ``` + +3. Run the following command to view the custom resources of the tenant in the current Kubernetes cluster to check whether the modification is successful: + + ```shell + kubectl get obtenants.oceanbase.oceanbase.com -n oceanbase -o yaml + ``` + + If the value of the corresponding parameter in the `status.resourcePool.priority` section in the custom resources of the tenant is changed to the new value, the modification is successful. + + ```yaml + status: + ... + resourcePool: + - zone: zone1 + priority: 3 + - zone: zone2 + @priority 2 + - zone: zone3 + priority: 1 + ``` + + You can also run the following command to view the result. + + ```shell + kubectl get obtenants.oceanbase.oceanbase.com -n oceanbase -o wide + ``` + + The command output is as follows: + + ```shell + NAME STATUS TENANTNAME TENANTROLE CLUSTERNAME AGE LOCALITY PRIMARYZONE POOLLIST CHARSET + t1 running t1 PRIMARY obcluster 13m ... zone1;zone2;zone3 ... utf8mb4 + ``` + + The result shows that the value of the `PRIMARYZONE` field is modified to `zone1;zone2;zone3`, which matches the priority configuration. + +## Modify the locality of a tenant + +To modify the locality of a tenant, you can modify the parameters in the `type` section to specify the replica type and the number of replicas. The following replica types are supported: `full`, `logonly`, and `readonly`. + +For more information, see [Modify the primary zone of a tenant](# Modify the primary zone of a tenant). + +Modify the tenant configuration file `tenant.yaml`: + +```yaml + type: + name: Full # The Full and Readonly replica types are supported. + replica: 1 +``` + +## Add replicas + +### Prerequisites + +* You have added a zone to the cluster. For more information, see [Add zones to a cluster](../../100.cluster-management-of-ob-operator/300.zone-management/100.add-zone.md). + +### Procedure + +You can add zones to a tenant by modifying the tenant configuration file `tenant.yaml`. + +Assume that the current cluster has four zones, `zone1`, `zone2`, `zone3`, and `zone4`, the zones corresponding to the tenant are `zone1`, `zone2`, and `zone3`, and you want to scale out the tenant to four zones. + +1. Modify the configuration file `tenant.yaml` to add `zone4`. + + ```yaml + # For example, the tenant has three zones. + pools: + - zone: zone1 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + - zone: zone2 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + - zone: zone3 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + + # Add zone4 to the tenant. + pools: + - zone: zone1 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + - zone: zone2 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + - zone: zone3 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + - zone: zone4 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + ``` + +2. Run the following command for the modification to take effect: + + ```shell + kubectl apply -f tenant.yaml + ``` + +3. Run the following command to view the custom resources of the tenant in the current Kubernetes cluster: + + ```shell + kubectl get obtenants.oceanbase.oceanbase.com -n oceanbase -o wide + ``` + + The following command output shows that the value of the LOCALITY field is as expected: + + ```shell + NAME STATUS TENANTNAME TENANTROLE CLUSTERNAME AGE LOCALITY PRIMARYZONE POOLLIST CHARSET + t1 running t1 PRIMARY obcluster 19m FULL{1}@zone1,FULL{1}@zone2,FULL{1}@zone3,FULL{1}@zone4 ... ... utf8mb4 + ``` + +## Delete replicas + +### Procedure + +You can modify the tenant configuration file `tenant.yaml` to delete zones from a tenant. + +Assume that the current cluster has four zones, `zone1`, `zone2`, `zone3`, and `zone4`, the zones corresponding to the tenant are `zone1`, `zone2`, `zone3`, and `zone4`, and you want to scale in the tenant to `zone1`, `zone2`, and `zone3`. + +1. Modify the configuration file `tenant.yaml` to delete `zone4`. + + ```yaml + # For example, the tenant has four zones. + pools: + - zone: zone1 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + - zone: zone2 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + - zone: zone3 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + - zone: zone4 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + + # Delete zone4 from the tenant. + pools: + - zone: zone1 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + - zone: zone2 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + - zone: zone3 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + ``` + +2. Run the following command for the modification to take effect: + + ```shell + kubectl apply -f tenant.yaml + ``` + +3. Run the following command to view the custom resources of the tenant in the current Kubernetes cluster: + + ```shell + kubectl get obtenants.oceanbase.oceanbase.com -n oceanbase -o wide + ``` + + The following command output shows that the value of the LOCALITY field is as expected: + + ```shell + NAME STATUS TENANTNAME TENANTROLE CLUSTERNAME AGE LOCALITY PRIMARYZONE POOLLIST CHARSET + t1 running t1 PRIMARY obcluster 25m FULL{1}@zone1,FULL{1}@zone2,FULL{1}@zone3 ... ... utf8mb4 + ``` diff --git a/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/300.other-configuration-item-modifications-of-ob-operator.md b/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/300.other-configuration-item-modifications-of-ob-operator.md new file mode 100644 index 000000000..1847c6a42 --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/300.other-configuration-item-modifications-of-ob-operator.md @@ -0,0 +1,40 @@ +# Modify other parameters + +This topic describes how to modify parameters other than those related to tenant resources and tenant replicas. + +* For more information about how to modify parameters related to tenant resources, see [Manage resources](100.resource-management-of-ob-operator.md). + +* For more information about how to modify parameters related to tenant replicas, see [Manage replicas](200.replica-management-of-ob-operator.md). + +## Modify the connection whitelist for a tenant + +If you want to update the list of IP addresses allowed to connect to a tenant, you can modify the `connectWhiteList` parameter in the tenant configuration file. When you modify this parameter, the value must include the CIDR block of ob-operator; otherwise, ob-operator cannot connect to the tenant. + +1. Modify the value of `connectWhiteList` in the `spec` section in the tenant configuration file `tenant.yaml`. + + ```yaml + spec: + ... + connectWhiteList: '%' + ``` + +2. Run the following command for the modification to take effect: + + ```shell + kubectl apply -f tenant.yaml + ``` + +3. Run the following command to view the custom resources of the tenant in the current Kubernetes cluster to check whether the modification is successful: + + ```shell + kubectl get obtenants.oceanbase.oceanbase.com -n oceanbase -o yaml + ``` + + If the value of the corresponding parameter in the `spec:connectWhiteList` section in the custom resources of the tenant is changed to the new value, the modification is successful. + + ```yaml + spec: + obcluster: obcluster + connectWhiteList: '%' + pools: + ``` diff --git a/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/_category_.yml b/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/_category_.yml new file mode 100644 index 000000000..4fde4ceb3 --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/_category_.yml @@ -0,0 +1,4 @@ +label: Modify tenant +position: 2 +link: + type: generated-index \ No newline at end of file diff --git a/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/300.delete-tenant-of-ob-operator.md b/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/300.delete-tenant-of-ob-operator.md new file mode 100644 index 000000000..f60ede372 --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/300.delete-tenant-of-ob-operator.md @@ -0,0 +1,21 @@ +# Delete a tenant + +This topic describes how to use ob-operator to delete a tenant from a Kubernetes environment. + +## Procedure + +You can delete the specified tenant resources from the cluster by using the configuration file `tenant.yaml`. For more information about the configuration file, visit [GitHub](https://github.com/oceanbase/ob-operator/blob/2.1.0_release/deploy/tenant.yaml). + +Run the following command to delete a tenant. This command deletes an OceanBase Database tenant with custom resources in the current Kubernetes cluster. + +```shell +kubectl delete -f tenant.yaml +``` + +Run the following command to check whether the current Kubernetes cluster contains the custom resources of the deleted tenant: + +```shell +kubectl get obtenants.oceanbase.oceanbase.com -A -o yaml +``` + +If not, the tenant is deleted. diff --git a/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/400.tenant-operation.md b/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/400.tenant-operation.md new file mode 100644 index 000000000..64b52861d --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/400.tenant-operation.md @@ -0,0 +1,88 @@ +# Perform tenant O&M operations + +A tenant contains various resources. To prevent a tenant from becoming bloated and improve tenant O&M flexibility, ob-operator provides the tenant O&M resource `OBTenantOperation` for you to perform intra-tenant and inter-tenant O&M operations. ob-operator V2.1.0 supports three O&M operations: changing the password of the root user, activating a standby tenant, and executing a primary/standby tenant switchover. Standby tenant activation and primary/standby tenant switchover are related to the [physical standby database](../300.high-availability/600.standby-tenant-of-ob-operator.md) feature. Here are sample configurations of the three O&M operations: + +```yaml op-chg-pwd.yaml +# Change the password. +apiVersion: oceanbase.oceanbase.com/v1alpha1 +kind: OBTenantOperation +metadata: + name: op-chg-pwd + namespace: oceanbase +spec: + type: "CHANGE_PASSWORD" + changePwd: + tenant: "t1" + secretRef: "t1-credential-new" +``` + +```yaml op-failover.yaml +# Upgrade a standby tenant to the primary tenant. +apiVersion: oceanbase.oceanbase.com/v1alpha1 +kind: OBTenantOperation +metadata: + name: op-failover + namespace: oceanbase +spec: + type: "FAILOVER" + failover: + standbyTenant: "t1s" +``` + +```yaml op-switchover.yaml +# Perform a primary/standby tenant switchover. +apiVersion: oceanbase.oceanbase.com/v1alpha1 +kind: OBTenantOperation +metadata: + name: op-switchover + namespace: oceanbase +spec: + type: "SWITCHOVER" + switchover: + primaryTenant: "t1" + standbyTenant: "t1s" +``` + +## Examples + +### Create a standby tenant + +```shell +kubectl apply -f tenant_restore.yaml +``` + +### View the tenant status + +```shell +kubectl get obtenants.oceanbase.oceanbase.com -n oceanbase +``` + +The command output is as follows: + +```shell +NAME STATUS TENANTNAME TENANTROLE CLUSTERNAME AGE +t1 running t1 PRIMARY obcluster 3d4h +t1s running t1s STANDBY obcluster 3h30m +``` + +### Perform O&M operations on the tenant + +```shell +kubectl apply -f tenant_op_change_pwd.yaml +kubectl apply -f tenant_op_failover.yaml +``` + +### Query the information about the tenant O&M operations + +```shell +kubectl get obtenantoperations.oceanbase.oceanbase.com -n oceanbase +``` + +The command output is as follows: + +```shell +NAME TYPE STATUS AGE CLUSTER PRIMARYTENANT +op-failover FAILOVER SUCCESSFUL 8s obcluster t1s +``` + +Note that the value of the `PRIMARYTENANT` field in the output indicates the new primary tenant after the switchover. The value of the `SECONDARYTENANT` field in the output indicates the new standby tenant after the switchover. To save space, the `SECONDARYTENANT` field is not exported by default. You can run the `kubectl get obtenantoperations.oceanbase.oceanbase.com -o wide` command to view it. diff --git a/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/_category_.yml b/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/_category_.yml new file mode 100644 index 000000000..a2fe1148b --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/_category_.yml @@ -0,0 +1,4 @@ +label: Tenant management +position: 2 +link: + type: generated-index \ No newline at end of file diff --git a/docsite/docs/manual/500.ob-operator-user-guide/300.high-availability/100.high-availability-intro.md b/docsite/docs/manual/500.ob-operator-user-guide/300.high-availability/100.high-availability-intro.md new file mode 100644 index 000000000..46dc09128 --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/300.high-availability/100.high-availability-intro.md @@ -0,0 +1,7 @@ +# High availability + +ob-operator ensures the high availability of data by using the following features of OceanBase Database. + +* Node fault recovery. The distributed architecture of OceanBase Database allows you to restore the service when a minority of nodes fail. By relying on certain network plugins, you can even restore the service from majority nodes failure. For more information, see [Restore service from faults](300.disaster-recovery-of-ob-operator.md). +* Backup and restore of tenant data. The backup and restore feature of OceanBase Database allows you to back up tenant data to different storage media to ensure data safety. For more information, see [Back up a tenant](400.tenant-backup-of-ob-operator.md). +* Primary and standby tenants. OceanBase Database allows you to create a standby tenant for the primary tenant. When a fault occurs to the primary tenant, you can quickly switch your business to the standby tenant to reduce the business interruption. For more information, see [Physical standby database](600.standby-tenant-of-ob-operator.md). diff --git a/docsite/docs/manual/500.ob-operator-user-guide/300.high-availability/300.disaster-recovery-of-ob-operator.md b/docsite/docs/manual/500.ob-operator-user-guide/300.high-availability/300.disaster-recovery-of-ob-operator.md new file mode 100644 index 000000000..ca05499bf --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/300.high-availability/300.disaster-recovery-of-ob-operator.md @@ -0,0 +1,40 @@ +# Restore service from node failure + +This topic describes how to handle the faults of OBServer nodes by using ob-operator. + +## Prerequisites + +* You must deploy an OceanBase cluster with at least 3 OBServer nodes and a tenant with 3 replicas or above. +* To use the static IP address feature, you must install `Calico` as the network plugin for the Kubernetes cluster. + +## Restore policy + +When a minority of OBServer nodes fail, the multi-replica mechanism of OceanBase Database ensures the availability of the cluster, and ob-operator detects a pod exception. Then, ob-operator creates an OBServer node, adds it to the cluster, and deletes the abnormal OBServer node. +OceanBase Database replicates the data of replicas on the abnormal OBServer node to the new node. + +If you have installed Calico for the Kubernetes cluster, this process can be easier. ob-operator can start a new observer process by using the IP address of the abnormal OBServer node. This way, the data on the abnormal OBServer node, if the data still exists, can be directly used without the replication step. Moreover, if a majority of OBServer nodes fail, this method can also restore the service after all new OBServer nodes are started. + +## Verification + +You can verify the restore result of ob-operator by performing the following steps. + +Delete the pod + +```shell +kubectl delete pod obcluster-1-zone1-074bda77c272 -n oceanbase +``` + +View the restore result. The output shows that the pod of zone1 has been created and is ready. + +```shell +kubectl get pods -n oceanbase + +NAME READY STATUS RESTARTS AGE +obcluster-1-zone3-074bda77c272 2/2 Running 0 12d +obcluster-1-zone2-7ecbd89f84de 2/2 Running 0 12d +obcluster-1-zone1-94ecf05cb290 2/2 Running 0 1m +``` + +## Deployment suggestions + +To deploy a production cluster with high availability, we recommend that you deploy an OceanBase cluster of at least three OBServer nodes, create tenants that each has at least three replicas, distribute nodes of each zone on different servers, and use the network plug-in Calico. This minimizes the risk of an unrecoverable cluster disaster. ob-operator also provides high-availability solutions based on the backup and restore of tenant data and the primary and standby tenants. For more information, see [Restore data from a backup](500.data-recovery-of-ob-operator.md) and [Back up a tenant](400.tenant-backup-of-ob-operator.md). diff --git a/docsite/docs/manual/500.ob-operator-user-guide/300.high-availability/400.tenant-backup-of-ob-operator.md b/docsite/docs/manual/500.ob-operator-user-guide/300.high-availability/400.tenant-backup-of-ob-operator.md new file mode 100644 index 000000000..59d953336 --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/300.high-availability/400.tenant-backup-of-ob-operator.md @@ -0,0 +1,291 @@ +# Back up a tenant + +This topic describes how to back up the data of a tenant. OBTenantBackupPolicy and OBTenantBackup resources are key to tenant data backup. You can use OBTenantBackupPolicy to define backup policies and OBTenantBackup to define backup jobs. A backup policy specifies the interval of log archiving and data backup parameters for a tenant in an OceanBase cluster. When a backup policy takes effect, a backup job is created to execute specific operations. The backup destination can be a Network File System (NFS) volume or an Alibaba Cloud Object Storage Service (OSS) bucket. + +## Prerequisites + +To back up data to an NFS volume, make sure that backup volume has been configured when the OceanBase cluster is deployed and can be accessed, and that you have the read and write permissions on the NFS volume. + +## Configure backup policies + +### Sample configurations + +You can use the configuration file to specify a backup policy for a specific tenant. Here is an example: + +```yaml +apiVersion: oceanbase.oceanbase.com/v1alpha1 +kind: OBTenantBackupPolicy +metadata: + name: backup-policy-example + namespace: oceanbase +spec: + obClusterName: "test" + tenantName: "t1" + tenantSecret: "t1-credential" + tenantCRName: "tenant-cr" + jobKeepWindow: "1d" + suspend: false + dataClean: + recoveryWindow: "8d" + logArchive: + destination: + type: "OSS" + path: "oss://bucket/archive?host=oss-cn-hangzhou.aliyuncs.com" + ossAccessSecret: "oss-access" + # type: "NFS" + # path: "t1/logArchive" + switchPieceInterval: "1d" + binding: Optional + dataBackup: + destination: + type: "OSS" + path: "oss://bucket/backup?host=oss-cn-hangzhou.aliyuncs.com" + ossAccessSecret: "oss-access" + # type: "NFS" + # path: "t1/dataBackup" + fullCrontab: "30 0 * * 6" + incrementalCrontab: "30 1 * * *" + encryptionSecret: t1-encryption +``` + +### Configuration description + +The parameters are described as follows: + +* obClusterName: the name of the OceanBase cluster in the same namespace. +* tenantName: the tenant name in the OceanBase cluster. +* tenantSecret: the name of the secret resource that contains the password of the root user of the specified tenant, whose name is the value of the `tenantName` parameter. +* tenantCRName: the name of the custom resources of the OceanBase Database tenant. If you specify this parameter, you do not need to specify the `tenantName` or `tenantSecret` parameter. +* jobKeepWindow: the time window for which the resources for a backup job are retained. +* suspend: specifies whether the backup job can be suspended. The default value is `false`. +* dataClean: the configuration for the cleanup of expired backup data. + * recoveryWindow: the time window for data recovery. +* logArchive: the configuration for log archiving. + * destination: the destination of the backup data. + * switchPieceInterval: the switching interval of pieces of archived logs. The value range is `[1d,7d]`. The default value is `1d`. + * binding: the mode for prioritizing archiving and business. `Optional` and `Mandatory` modes are supported. By default, `Optional` mode is used. +* dataBackup: the configuration for data backup. + * destination: the destination of the backup data. + * fullCrontab: the scheduled timestamp, in the cron expression format, when a full data backup job is triggered. For more information, visit [https://crontab.guru/](https://crontab.guru/). + * incrementalCrontab: the scheduled timestamp, in the cron expression format, when an incremental data backup job is triggered. For more information, visit [https://crontab.guru/](https://crontab.guru/). + * encryptionSecret: the name of the secret resource for data backup encryption. + +The parameters are described as follows: + +destination: + +* type: the type of the destination. Valid values are `NFS` and `OSS`. +* path: the path of the backup destination. If you use an OSS backup destination, the path must start with `oss://`. If you use an NFS backup destination, you must specify a relative path, which must not start with `/`. +* ossAccessSecret: the name of the secret resource that stores the OSS access credential. If you use an OSS backup destination, you must specify this parameter. + +Here is the configuration of a sample tenantSecret resource: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: tenant-root + namespace: oceanbase +data: + # base64 encoded + password: ****** +``` + +Here is the configuration of a sample encryptionSecret resource: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: tenant-backup-encryption + namespace: oceanbase +data: + # base64 encoded + password: ****** +``` + +Here is the configuration of a sample ossAccessSecret resource: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: oss-access + namespace: obcluster +data: + # base64 encoded + accessId: ****** + accessKey: ****** +``` + +## Common operations + +### Initiate a backup job + +Specify the name of the related secret resource as needed and run the following command to create the secret resource: + +```shell +kubectl apply -f tenant-secret.yaml +kubectl apply -f backup-encryption.yaml +kubectl apply -f oss-access.yaml +``` + +Run the following command to create a tenant backup policy: + +```shell +kubectl apply -f backup-policy.yaml +``` + +### View the status of the backup policy + +Run the following command to view the status of the backup policy: + +```shell +kubectl get obtenantbackuppolicies.oceanbase.oceanbase.com -n oceanbase +``` + +The command output is as follows: + +```shell +NAME STATUS AGE TENANTNAME NEXTFULL NEXTINCREMENTAL FULLCRONTAB INCREMENTALCRONTAB +backup-policy-example RUNNING 2m46s t1 2023-11-10 11:07:58 */60 * * * * */25 * * * * +``` + +### View the status of the backup job + +When a backup policy takes effect, a backup job is created to execute specific operations. You can run the following command to view the status of a backup job: + +```shell +kubectl get obtenantbackups.oceanbase.oceanbase.com -n oceanbase +``` + +The command output is as follows: + +```shell +NAME TYPE STATUS TENANTNAME STARTEDAT ENDEDAT +backup-policy-example-clean-20231110110746 CLEAN RUNNING t1 +backup-policy-example-full-20231110110756 FULL SUCCESSFUL t1 2023-11-10 11:08:06.952711 2023-11-10 11:13:31.079246 +backup-policy-example-archive-20231110110746 ARCHIVE RUNNING t1 2023-11-10 11:07:50.139978 2023-11-10 11:13:50.128627 +``` + +### View details of the backup policy + +You can view details of the backup policy by running the following two commands. + +* Run the `kubectl get -o yaml` command: + +```shell +kubectl get -n oceanbase obtenantbackuppolicies.oceanbase.oceanbase.com backup-policy-example -o yaml +``` + +The command output is as follows: + +```yaml +apiVersion: oceanbase.oceanbase.com/v1alpha1 +kind: OBTenantBackupPolicy +metadata: + creationTimestamp: "2023-11-10T03:07:39Z" + finalizers: + - obtenantbackuppolicy.finalizers.oceanbase.com + generation: 1 + name: backup-policy-example + namespace: oceanbase + resourceVersion: "775461" + uid: 7ab40200-f849-434d-b1a5-6aad888cf42e +spec: + dataBackup: + destination: + ossAccessSecret: oss-access + path: oss://bucket/backup?host=oss-cn-hangzhou.aliyuncs.com + type: OSS + fullCrontab: '*/60 * * * *' + incrementalCrontab: '*/25 * * * *' + encryptionSecret: t1-encryption + dataClean: + recoveryWindow: 8d + jobKeepWindow: 1d + logArchive: + destination: + ossAccessSecret: oss-access + path: oss://bucket/archive?host=oss-cn-hangzhou.aliyuncs.com + type: OSS + switchPieceInterval: 1d + obClusterName: test + tenantName: t1 + tenantSecret: t1-credential +status: + latestArchiveLogJob: + fields: values... + latestFullBackupJob: + fields: values... + nextFull: "2023-11-10 12:00:00" + nextIncremental: "2023-11-10 11:25:00" + observedGeneration: 1 + status: RUNNING + tenantCR: + fields: values... + tenantInfo: + fields: values... +``` + +* Run the `kubectl describe` command: + +```shell +kubectl describe -n oceanbase obtenantbackuppolicies.oceanbase.oceanbase.com backup-policy-example +``` + +The command output is as follows: + +```text +Name: backup-policy-example +Namespace: oceanbase +Labels: +Annotations: +API Version: oceanbase.oceanbase.com/v1alpha1 +Kind: OBTenantBackupPolicy +Metadata: + Creation Timestamp: 2023-11-10T03:07:39Z + Finalizers: + obtenantbackuppolicy.finalizers.oceanbase.com + Generation: 1 + Resource Version: 775477 + UID: 7ab40200-f849-434d-b1a5-6aad888cf42e +Spec: + Data Backup: + Destination: + Oss Access Secret: oss-access + Path: oss://bucket/backup?host=oss-cn-hangzhou.aliyuncs.com + Type: OSS + Full Crontab: */60 * * * * + Incremental Crontab: */25 * * * * + Encryption Secret: t1-encryption + Data Clean: + Recovery Window: 8d + Job Keep Window: 1d + Log Archive: + Destination: + Oss Access Secret: oss-access + Path: oss://bucket/archive?host=oss-cn-hangzhou.aliyuncs.com + Type: OSS + Switch Piece Interval: 1d + Ob Cluster Name: test + Tenant Name: t1 + Tenant Secret: t1-credential +Status: + Latest Archive Log Job: + fields: values... + Latest Full Backup Job: + fields: values... + Next Full: 2023-11-10 12:00:00 + Next Incremental: 2023-11-10 11:25:00 + Observed Generation: 1 + Status: RUNNING + Tenant CR: + fields: values... + Tenant Info: + fields: values... +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal 12m obtenantbackuppolicy-controller init status +``` diff --git a/docsite/docs/manual/500.ob-operator-user-guide/300.high-availability/500.data-recovery-of-ob-operator.md b/docsite/docs/manual/500.ob-operator-user-guide/300.high-availability/500.data-recovery-of-ob-operator.md new file mode 100644 index 000000000..f52da7613 --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/300.high-availability/500.data-recovery-of-ob-operator.md @@ -0,0 +1,190 @@ +# Restore data from a backup + +This topic describes how to restore data from a backup. OBTenant and OBTenantRestore resources are important to data restore from a backup. You must use parameters in the `spec.source` section in the configuration file of the OBTenant resource to specify the tenant restore source. When the specified parameters take effect, ob-operator creates the OBTenantRestore resources required to execute restore jobs. + +## Prerequisites + +* Data has been backed up and can be restored. + +* The cluster is running properly and the available resources are sufficient to create a recovery tenant. + +* If the restore source is a Network File System (NFS) volume, make sure that the volume mounted to the OceanBase cluster can be accessed. + +## Configuration file for restoring data + +You can use the configuration file to define tenant resources required for restoring data: + +```yaml tenant_restore.yaml +apiVersion: oceanbase.oceanbase.com/v1alpha1 +kind: OBTenant +metadata: + name: t1s + # namespace: oceanbase +spec: + obcluster: obcluster + tenantName: t1s + unitNum: 1 + tenantRole: STANDBY + source: + restore: + bakDataSource: + # type: "NFS" + # path: "t1/dataBackup" + type: "OSS" + path: "oss://bucket/backup?host=oss-cn-hangzhou.aliyuncs.com" + ossAccessSecret: "oss-access" + archiveSource: + # type: "NFS" + # path: "t1/logArchive" + type: "OSS" + path: "oss://bucket/archive?host=oss-cn-hangzhou.aliyuncs.com" + ossAccessSecret: "oss-access" + until: + unlimited: true + replayLogUntil: + unlimited: true + tenant: t1 + fields: values +``` + +The parameters are described as follows: + +* tenantRole: the role of the tenant to be created. Valid values are `PRIMARY` and `STANDBY`, which represent the primary and standby tenants, respectively. The default value is `PRIMARY`. For more information about standby tenants and physical standby databases, see [Physical standby database](./600.standby-tenant-of-ob-operator.md). +* source: the source of tenant data. + * restore: the source of the backup data for restore. + * bakDataSource: the path to the source of the backup data for restore. The data restore source is the same as the data backup destination. + * archiveSource: the path to the source of archived logs for restore. The log restore source is the same as the log archiving destination. + * until: the checkpoint to which the data is to be restored. + * unlimited: specifies whether to restore data to the latest checkpoint. + * timestamp: the timestamp, in the `YYYY-MM-DD HH:mm:ss` format, to which you want to restore data. For example, `2023-11-10 09:00:00`. + * scn: the system change number (SCN) to which the data is restored. + * replayLogUntil: the checkpoint to which the logs of the primary tenant are replayed after data restore. This parameter takes effect only if the standby tenant is restored and the `unlimited` parameter is not specified. You can specify this parameter as a supplement to the `until` parameter by using the same configuration method. + * tenant: the name of the primary tenant. This parameter takes effect only if the standby tenant is restored. +* The configuration of other parameters is the same as that of a normal tenant. + +## Example + +### Initiate a data restore job + +Run the following command to restore data to a tenant. + +```shell +kubectl apply -f tenant_restore.yaml +``` + +### View the data restore status + +* Run the following command to view the status of the tenant to be restored. + +```shell +kubectl get obtenants.oceanbase.oceanbase.com -n oceanbase +``` + +The command output is as follows: + +```shell +NAME STATUS TENANTNAME TENANTROLE CLUSTERNAME AGE +t1s restoring t1s STANDBY obcluster 27s +``` + +* Run the following command to view the created tenant restore job. + +```shell +kubectl get obtenantrestores.oceanbase.oceanbase.com -n oceanbase +``` + +The command output is as follows: + +```shell +NAME STATUS AGE TARGETTENANT TARGETCLUSTER RESTOREROLE STATUSINDB +t1s-restore RUNNING 113s t1s obcluster STANDBY WAIT_TENANT_RESTORE_FINISH +``` + +* Run the following command to view details of the tenant restore job: + +```shell +kubectl describe obtenantrestores.oceanbase.oceanbase.com -n oceanbase +``` + +The command output is as follows: + +```shell +Name: t1s-restore +Namespace: oceanbase +Labels: oceanbase.oceanbase.com/tenant-name=t1s + ref-obcluster=obcluster + ref-uid=b9317541-6566-4ac0-84fb-9a4c6fca03ba +Annotations: +API Version: oceanbase.oceanbase.com/v1alpha1 +Kind: OBTenantRestore +Metadata: +Creation Timestamp: 2023-11-13T03:13:26Z +Generation: 1 +Owner References: + API Version: oceanbase.oceanbase.com/v1alpha1 + Block Owner Deletion: true + Kind: OBTenant + Name: t1s + UID: b9317541-6566-4ac0-84fb-9a4c6fca03ba +Resource Version: 927784 +UID: e439a060-9758-4074-a170-661d3e23a836 +Spec: +Primary Tenant: t1 +Restore Option: pool_list=pool_t1s_zone1&primary_zone=zone1;&locality=FULL{1}@zone1 +Restore Role: STANDBY +Source: + Archive Source: + Oss Access Secret: oss-access + Path: oss://bucket/archive?host=oss-cn-hangzhou.aliyuncs.com + Type: OSS + Bak Data Source: + Oss Access Secret: oss-access + Path: oss://bucket/backup?host=oss-cn-hangzhou.aliyuncs.com + Type: OSS + Replay Log Until: + Unlimited: true + Until: + Unlimited: true +Target Cluster: obcluster +Target Tenant: t1s +Status: +Restore Progress: + backup_cluster_name: obcluster + backup_cluster_version: + backup_dest: oss://bucket/backup?host=oss-cn-hangzhou.aliyuncs.com&access_id=xxx&access_key=yyy,oss://bucket/archive?host=oss-cn-hangzhou.aliyuncs.com&access_id=xxx&access_key=yyy + backup_piece_list: oss://bucket/archive/piece_d1005r10p10?host=oss-cn-hangzhou.aliyuncs.com&access_id=xxx&access_key=yyy + backup_set_list: oss://bucket/backup/backup_set_25_full?host=oss-cn-hangzhou.aliyuncs.com&access_id=xxx&access_key=yyy,oss://bucket/backup/backup_set_26_inc?host=oss-cn-hangzhou.aliyuncs.com&access_id=xxx&access_key=yyy + backup_tenant_id: 1016 + backup_tenant_name: t1 + Description: + finish_ls_count: 0 + finish_tablet_count: 0 + finish_timestamp: + job_id: 5 + ls_count: 0 + restore_option: pool_list=pool_t1s_zone1&primary_zone=zone1;&locality=FULL{1}@zone1 + restore_scn: 1697098764718466986 + restore_scn_display: 2023-10-12 16:19:24.718466 + restore_tenant_id: 1004 + restore_tenant_name: t1s + start_timestamp: 2023-11-13 11:13:46.220513 + Status: WAIT_TENANT_RESTORE_FINISH + tablet_count: 0 + tenant_id: 1 +Status: RUNNING +Events: +``` + +## Check whether the tenant is restored + +* Connect to the sys tenant. + +```shell +mysql -h$(kubectl get pods -l ref-obcluster=test -o jsonpath='{.items[0].status.podIP}') -P2881 -uroot oceanbase -A -c +``` + +* Check whether the target tenant is restored. + +```sql +select * from DBA_OB_TENANTS; +``` diff --git a/docsite/docs/manual/500.ob-operator-user-guide/300.high-availability/600.standby-tenant-of-ob-operator.md b/docsite/docs/manual/500.ob-operator-user-guide/300.high-availability/600.standby-tenant-of-ob-operator.md new file mode 100644 index 000000000..71c7ead77 --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/300.high-availability/600.standby-tenant-of-ob-operator.md @@ -0,0 +1,60 @@ +# Physical standby tenant + +This topic describes the physical standby tenant feature. This feature is available in OceanBase Database V4.x and provides your key applications with important capabilities such as high availability, data protection, and disaster recovery. It requires OBTenant and OBTenantOperation resources. You can use OBTenant resources to define tenants and OBTenantOperation resources to define tenant O&M operations. You can create a physical standby tenant from backup data or by creating an empty tenant. The physical standby tenant feature is closely related to the data restore feature. + +## Modify the configuration file + +Parameters of a physical standby tenant are also contained in the OBTenant resource. For more information, see [Restore data from a backup](500.data-recovery-of-ob-operator.md). + +```yaml tenant_standby.yaml +apiVersion: oceanbase.oceanbase.com/v1alpha1 +kind: OBTenant +metadata: + name: t1s + # namespace: oceanbase +spec: + obcluster: obcluster + tenantName: t1s + unitNum: 1 + tenantRole: STANDBY + source: + restore: + bakDataSource: + # type: "NFS" + # path: "t1/dataBackup" + type: "OSS" + path: "oss://bucket/backup?host=oss-cn-hangzhou.aliyuncs.com" + ossAccessSecret: "oss-access" + archiveSource: + # type: "NFS" + # path: "t1/logArchive" + type: "OSS" + path: "oss://bucket/archive?host=oss-cn-hangzhou.aliyuncs.com" + ossAccessSecret: "oss-access" + until: + unlimited: true + replayLogUntil: + unlimited: true + tenant: t1 + fields: values +``` + +The parameters are described as follows: + +* tenantRole: the role of the tenant. If you want to use the tenant as a standby tenant, set this parameter to `STANDBY`. The default value is `PRIMARY`. +* source: the source of tenant data. + * restore: the source of the backup data for restore. + * tenant: the name of the primary tenant whose data will be synchronized to the created tenant. + +## Combined use of parameters + +In the `spec.source` section of the configuration file of the OBTenant resource, the `restore` parameter specifies the information of the data restore source and the `tenant` parameter specifies the name of the primary tenant. The behavior of ob-operator varies based on the configuration of the two parameters. + +* If you specify both the `restore` and `tenant` parameters, ob-operator restores the standby tenant based on the configuration of the `restore` parameter, sets the log restore source of the standby tenant to the primary tenant, and replay the logs based on the values of the `until` and `replayLogUntil` parameters. +* If you specify only the `restore` parameter, ob-operator restores the tenant based on the configuration of the `restore` parameter, and sets the tenant role as specified by the `tenantRole` parameter. +* If you specify only the `tenant` parameter, ob-operator checks the existence of the specified tenant and the integrity of the log streams. If the check is passed, ob-operator creates an empty standby tenant and synchronizes the data from the specified primary tenant to the standby tenant. +* If you specify neither the `restore` nor `tenant` parameter, the configuration file cannot be verified and cannot be applied to the cluster. + +## Tenant upgrade and switchover + +For more information, see [Perform tenant O&M operations](../200.tenant-management-of-ob-operator/400.tenant-operation.md). diff --git a/docsite/docs/manual/500.ob-operator-user-guide/300.high-availability/_category_.yml b/docsite/docs/manual/500.ob-operator-user-guide/300.high-availability/_category_.yml new file mode 100644 index 000000000..3bcae5d64 --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/300.high-availability/_category_.yml @@ -0,0 +1,4 @@ +label: High availability +position: 3 +link: + type: generated-index \ No newline at end of file diff --git a/docsite/docs/manual/500.ob-operator-user-guide/_category_.yml b/docsite/docs/manual/500.ob-operator-user-guide/_category_.yml new file mode 100644 index 000000000..149e95e90 --- /dev/null +++ b/docsite/docs/manual/500.ob-operator-user-guide/_category_.yml @@ -0,0 +1,4 @@ +label: Manage resources +position: 6 +link: + type: generated-index \ No newline at end of file diff --git a/docsite/docs/manual/900.appendix/100.example.md b/docsite/docs/manual/900.appendix/100.example.md new file mode 100644 index 000000000..dd7cf6028 --- /dev/null +++ b/docsite/docs/manual/900.appendix/100.example.md @@ -0,0 +1,288 @@ +--- +sidebar_position: 1 +title: A real-world example +--- + +# Deploy OceanBase Database and applications in a Kubernetes cluster + +This topic describes how to deploy OceanBase Database, related components, and applications in a Kubernetes cluster by using a real-world example. + +## Prerequisites + +Before you start the deployment, make sure that you have deployed [cert-manager](https://cert-manager.io/docs/), [local-path-provisioner](https://github.com/rancher/local-path-provisioner), and [ob-operator](https://github.com/oceanbase/ob-operator) in your Kubernetes cluster. + +In this example, the following components are deployed: + +* [OceanBase Database](https://github.com/oceanbase/oceanbase). +* [ob-configserver](https://github.com/oceanbase/oceanbase/tree/master/tools/ob-configserver), which is used to register the IP address of the RootService server for OceanBase Database. +* [OceanBase Database Proxy (ODP)](https://github.com/oceanbase/obproxy), the proxy of OceanBase Database. +* [OceanBase Cloud Platform (OCP)](https://hub.docker.com/r/oceanbase/ocp-ce). OCP is taken as an example to describe how to deploy web applications in the Kubernetes cluster. +* [Prometheus](https://prometheus.io/), the monitoring and alerting system that collects and calculates the monitoring metrics of OceanBase Database. +* [Grafana](https://grafana.com/), the data visualization system. You can connect Grafana to Prometheus to display the monitoring data of OceanBase Database. + +## Deploy OceanBase Database and related components + +### Preparations before deployment + +Create a namespace: + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.0_release/example/webapp/namespace.yaml +``` + +View the created namespace: + +```shell +kubectl get namespace oceanbase +``` + +The following output indicates that the namespace is created: + +```shell +NAME STATUS AGE +oceanbase Active 98s +``` + +Create secrets for the cluster and tenants: + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.0_release/example/webapp/secret.yaml +``` + +View the created secrets: + +```shell +kubectl get secret -n oceanbase +``` + +The following output indicates that the secrets are created: + +```shell +NAME TYPE DATA AGE +sc-metatenant-root Opaque 1 11s +sc-metatenant-standbyro Opaque 1 11s +sc-sys-monitor Opaque 1 11s +sc-sys-operator Opaque 1 11s +sc-sys-proxyro Opaque 1 11s +sc-sys-root Opaque 1 11s +``` + +### Deploy ob-configserver + +ob-configserver allows you to register, store, and query metadata of the RootService server for OceanBase Database. The supported metadata storage types are `sqlite3` and `mysql`. In this example, `sqlite3` is used. +Run the following command to deploy ob-configserver and create the corresponding service: + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.0_release/example/webapp/configserver.yaml +``` + +Check the pod status: + +```shell +kubectl get pods -n oceanbase | grep ob-configserver + +# desired output +ob-configserver-856bf5d865-dlwxr 1/1 Running 0 16s +``` + +Check the svc status: + +```shell +kubectl get svc svc-ob-configserver -n oceanbase + +# desired output +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +svc-ob-configserver NodePort 10.96.3.39 8080:30080/TCP 98s +``` + +### Deploy an OceanBase cluster + +When you deploy an OceanBase cluster, add environment variables and set the system parameter `obconfig_url` to the IP address of ob-configserver service. OceanBase Database will register the information of RootService with ob-configserver. +Deploy the OceanBase cluster: + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.0_release/example/webapp/obcluster.yaml +``` + +Run the following command to query the status of the OceanBase cluster until the status becomes `running`: + +```shell +kubectl get obclusters.oceanbase.oceanbase.com metadb -n oceanbase + +# desired output +NAME STATUS AGE +metadb running 3m21s +``` + +### Deploy ODP + +You can start ODP by using ob-configserver or specifying the RS list. To maximize the performance of ODP, we recommend that you connect ODP to the cluster by using ob-configserver. + +Run the following command to deploy ODP and create the ODP service: + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.0_release/example/webapp/obproxy.yaml +``` + +When you query the pod status of ODP, you can see two ODP pods. + +```shell +kubectl get pod -A | grep obproxy + +# desired output +oceanbase obproxy-5cb8f4d975-pmr59 1/1 Running 0 21s +oceanbase obproxy-5cb8f4d975-xlvjp 1/1 Running 0 21s +``` + +View information about the ODP service: + +```shell +kubectl get svc svc-obproxy -n oceanbase + +# desired output +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +svc-obproxy ClusterIP 10.96.2.46 2883/TCP,2884/TCP 2m26s +``` + +Connect to the OceanBase cluster by using the IP address of the ODP service: + +```shell +mysql -h${obproxy-service-address} -P2883 -uroot@sys#metadb -p +``` + +If the OceanBase cluster is connected, the ODP service is normal. + +![connection](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/observer/V4.2.0/ob-operator-1.png) + +If the `cluster not exist` message is returned, it indicates that the OceanBase cluster has not registered the cluster metadata with ob-configserver. Try again later. You can view the registration result by using the `curl "http://127.0.0.1:30080/services?Action=ObRootServiceInfo&ObCluster=metadb"` statement. If the RsList parameter is not empty in the response, the cluster metadata is registered. + +## Deploy applications + +### Create a tenant + +You can create a dedicated tenant for each type of business for better resource isolation. In this example, one tenant is created. + +Run the following command to create a tenant: + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.0_release/example/webapp/tenant.yaml +``` + +Run the following command to query the status of the tenant until the status becomes `running`: + +```shell +kubectl get obtenants.oceanbase.oceanbase.com metatenant -n oceanbase +NAME STATUS TENANTNAME TENANTROLE CLUSTERNAME AGE +metatenant running metatenant PRIMARY metadb 106s +``` + +Run the following command to verify that the tenant can be connected: + +```shell +mysql -h${obproxy-service-address} -P2883 -uroot@metatenant#metadb -p +``` + +If the tenant is connected, you can use it. + +### Deploy an application + +OCP is taken as an example to describe how to deploy a web application. +Create databases +Run the following command to create databases: + +```shell +# connect tenant +mysql -h${obproxy-service-address} -P2883 -uroot@metatenant#metadb -p + +# create meta database +create database ocp_metadb; + +# create monitor database +create database ocp_monitordb; +``` + +Run the following command to deploy the application: + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.0_release/example/webapp/ocp.yaml +``` + +After the deployment process is completed, run the following command to view the application status: + +```shell +# check pod +kubectl get pods -n oceanbase | grep ocp +ocp-6bb784f89f-q6cbs 1/1 Running 0 12m + +# check service +kubectl get svc svc-ocp -n oceanbase +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +svc-ocp NodePort 10.43.39.231 8080:32080/TCP 12m +``` + +An application provides service a while after it is deployed. You can access the application by using the service address. + +```shell +# check by query time api +curl -L 'http://${service_ip}:${server_port}/api/v2/time' +"2023-11-27T00:00:13.687+08:00" +``` + +## Deploy the monitoring system + +### Deploy Prometheus + +When you deploy the OceanBase cluster, an OBAgent sidecar container is created in each pod to provide monitoring data over the Prometheus protocol. A service is also created to automatically identify the IP address of OBAgent to collect data with the service discovery feature enabled. + +Run the following command to deploy Prometheus: + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.0_release/example/webapp/prometheus.yaml +``` + +Run the following command to view the deployment status: + +```shell +# check pod status +kubectl get pods -n oceanbase | grep prometheus +prometheus-576d7757b9-jsvfh 1/1 Running 0 3m17s + +# check service status +kubectl get svc svc-prometheus -n oceanbase +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +svc-prometheus NodePort 10.96.1.212 9090:30090/TCP 3m45s +``` + +### Deploy Grafana + +Grafana displays the metrics of OceanBase Database by using Prometheus as a data source. +Run the following command to deploy Grafana: + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.0_release/example/webapp/grafana.yaml +``` + +Run the following command to view the deployment status: + +```shell +# check pod status +kubectl get pods -n oceanbase | grep grafana +grafana-b7c6c6ccb-dkv57 1/1 Running 0 2m + +# check service status +kubectl get svc svc-grafana -n oceanbase +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +svc-grafana NodePort 10.96.2.145 3000:30030/TCP 2m +``` + +Open a browser and visit the service address to view the monitoring metrics of OceanBase Database. + +![Grafana](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/observer/V4.2.0/ob-operator-2.png) + +## Summary + +This topic describes how to deploy OceanBase Database and related components such as ODP and ob-configserver, applications, and the monitoring system. You can deploy other applications based on the example. + +## Note + +You can find all configuration files used in this topic in the [webapp](https://github.com/oceanbase/ob-operator/tree/2.1.0_release/example/webapp) directory. diff --git a/docsite/docs/manual/900.appendix/200.FAQ.md b/docsite/docs/manual/900.appendix/200.FAQ.md new file mode 100644 index 000000000..fac52e64e --- /dev/null +++ b/docsite/docs/manual/900.appendix/200.FAQ.md @@ -0,0 +1,147 @@ +--- +sidebar_position: 2 +--- + +# FAQ + +## 1. How do I make sure that a resource is ready? + +Assume that you want to view the resource status of a cluster. Run the following command: + +```shell +kubectl get obclusters.oceanbase.oceanbase.com test -n oceanbase +``` + +If the status is `running` in the response, the resource is ready. + +```shell +# desired output +NAME STATUS AGE +test running 6m2s +``` + +## 2. How do I view the O&M status of a resource? + +Assume that you want to view the resource status of a cluster. Run the following command: + +```shell +kubectl get obclusters.oceanbase.oceanbase.com test -n oceanbase -o yaml +``` + +You can check the status and progress of O&M tasks based on values of parameters in the `operationContext` section in the response. + +```shell +status: + image: oceanbase/oceanbase-cloud-native:4.2.0.0-101000032023091319 + obzones: + - status: delete observer + zone: obcluster-1-zone1 + - status: delete observer + zone: obcluster-1-zone2 + - status: delete observer + zone: obcluster-1-zone3 + operationContext: + failureRule: + failureStatus: running + failureStrategy: retry over + retryCount: 0 + idx: 2 + name: modify obzone replica + targetStatus: running + task: wait obzone topology match + taskId: c04aeb28-01e7-4f85-b390-8d855b9f30e3 + taskStatus: running + tasks: + - modify obzone replica + - wait obzone topology match + - wait obzone running + parameters: [] + status: modify obzone replica +``` + +## 3. How do I do troubleshooting for ob-operator and OceanBase? + +* Generally, you need to first analyze the logs of ob-operator to locate an error. Run the following command to view the logs of ob-operator: + +```shell +kubectl logs oceanbase-controller-manager-86cfc8f7bf-js95z -n oceanbase-system -c manager | less +``` + +* View the logs of the OBServer node + +```shell +# Log on to the container of the OBServer node. +kubectl exec -it obcluster-1-zone1-8ab645f4d0f9 -n oceanbase -c observer -- bash + +# The directory where the log files are located. +cd /home/admin/oceanbase/log +``` + +## 4. How do I fix a "stuck" resource in ob-operator? + +As ob-operator uses a state machine and task flow to manage custom resources (CRs) and their O&M operations, there may be situations where CRs are in an unexpected state. This could include continuously retrying a task flow that is bound to fail, failing to delete a resource, or mistakenly deleting a resource that needs to be recovered. In cases where a CR cannot be restored to normal through regular operations, you can use the `OBResourceRescue` resource to rescue the problematic CR. The `OBResourceRescue` resource includes four types of operations: `reset`, `delete`, `retry`, and `skip`. + +A typical `OBResourceRescue` CR configuration is as follows: + +```yaml +apiVersion: oceanbase.oceanbase.com/v1alpha1 +kind: OBResourceRescue +metadata: + generateName: rescue-reset- # generateName needs to be used with kubectl create -f +spec: + type: reset + targetKind: OBCluster + targetResName: test + targetStatus: running # The target status needs to be filled in when the type is reset +``` + +The key configurations are explained in the following table: + +| Configuration item | Optional values | Description | +| -- | -- | -- | +| type | `reset`, `delete`, `retry`, `skip` | The type of the resource rescue action | +| targetKind | `OBCluster`, `OBZone`, `OBTenant`, and other CRD kind managed by ob-operator | The kind of the resource to be rescued | +| targetResName | / | The name of the resource to be rescued | +| targetStatus | / | This field needs to be filled in when the type is reset, indicating the status of the resource after the reset | + + +### Reset + +The configuration example of the typical CR above is a reset type of resource rescue. After creating this resource in the K8s cluster using the `kubectl create -f` command, ob-operator sets the `status.status` of the resource whose kind is `OBCluster` and name is `test` to `running` (the `targetStatus` set in the configuration file), and sets the `status.operationContext` of the resource to empty. + +### Delete + +The configuration example of the delete type of rescue action is as follows. After creating this resource in the cluster, ob-operator clears the `finalizers` field of the target resource and sets the `deletionTimestamp` of the resource to the current time. + +```yaml +# ... +spec: + type: delete + targetKind: OBCluster + targetResName: test +``` + +### Retry + +The configuration example of the retry type of rescue action is as follows. After creating this resource in the cluster, ob-operator sets the `status.operationContext.retryCount` of the target resource to 0 and sets the `status.operationContext.taskStatus` to `pending`. Resources in this state will retry the current task. + +```yaml +# ... +spec: + type: retry + targetKind: OBCluster + targetResName: test +``` + +### Skip + +The configuration example of the skip type of rescue action is as follows. After creating this resource in the cluster, ob-operator directly sets the `status.operationContext.taskStatus` of the target resource to `successful`. After receiving this message, the task manager will execute the next task in the `tasks` field. + +```yaml +# ... +spec: + type: skip + targetKind: OBCluster + targetResName: test +``` + diff --git a/docsite/docs/manual/900.appendix/_category_.yml b/docsite/docs/manual/900.appendix/_category_.yml new file mode 100644 index 000000000..71e84db0f --- /dev/null +++ b/docsite/docs/manual/900.appendix/_category_.yml @@ -0,0 +1,4 @@ +label: Appendix +position: 7 +link: + type: generated-index \ No newline at end of file diff --git a/docsite/docusaurus.config.ts b/docsite/docusaurus.config.ts new file mode 100644 index 000000000..cf909df06 --- /dev/null +++ b/docsite/docusaurus.config.ts @@ -0,0 +1,161 @@ +import { themes as prismThemes } from 'prism-react-renderer' +import type { Config } from '@docusaurus/types' +import type * as Preset from '@docusaurus/preset-classic' + +const config: Config = { + title: 'ob-operator', + tagline: 'ob-operator is a Kubernetes operator for OceanBase', + favicon: 'img/favicon.ico', + + // Set the production url of your site here + url: 'https://oceanbase.github.io', + // Set the // pathname under which your site is served + // For GitHub pages deployment, it is often '//' + baseUrl: '/ob-operator', + + // GitHub pages deployment config. + // If you aren't using GitHub pages, you don't need these. + organizationName: 'oceanbase', // Usually your GitHub org/user name. + projectName: 'ob-operator', // Usually your repo name. + + onBrokenLinks: 'throw', + onBrokenMarkdownLinks: 'warn', + + // Even if you don't use internationalization, you can use this field to set + // useful metadata like html lang. For example, if your site is Chinese, you + // may want to replace "en" with "zh-Hans". + i18n: { + defaultLocale: 'en', + locales: ['en', 'zh-Hans'], + }, + + presets: [ + [ + 'classic', + { + docs: { + sidebarPath: './sidebars.ts', + // Please change this to your repo. + // Remove this to remove the "edit this page" links. + editUrl: + 'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/', + }, + blog: { + showReadingTime: true, + // Please change this to your repo. + // Remove this to remove the "edit this page" links. + editUrl: + 'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/', + }, + theme: { + customCss: './src/css/custom.css', + }, + } satisfies Preset.Options, + ], + ], + + trailingSlash: false, + themeConfig: { + // TODO: Replace with oceanbase docs index + algolia: { + appId: 'QK0JZ42KY7', + apiKey: '36bae2ea61a954b3c70a3ae5ef68dea7', + indexName: 'powerfooiio', + contextualSearch: true, + }, + image: 'img/logo.png', + navbar: { + title: 'ob-operator', + logo: { + alt: 'OceanBase Logo', + src: 'img/logo.png', + }, + items: [ + { + type: 'docSidebar', + sidebarId: 'manualSidebar', + label: 'Manual', + position: 'left', + }, + { + type: 'docSidebar', + sidebarId: 'developerSidebar', + label: 'Developer', + position: 'left', + }, + { + label: 'Change log', + to: 'changelog', + }, + { + type: 'localeDropdown', + position: 'right', + }, + { + href: 'https://github.com/oceanbase', + label: 'GitHub', + position: 'right', + }, + ], + }, + footer: { + style: 'dark', + links: [ + { + title: 'Docs', + items: [ + { + label: 'Manual', + to: '/docs/manual/what-is-ob-operator', + }, + { + label: 'Architecture', + to: '/docs/developer/arch', + }, + { + label: 'Development', + to: '/docs/developer/develop-locally', + } + ], + }, + { + title: 'Repos', + items: [ + { + label: 'ob-operator', + href: 'https://github.com/oceanbase/ob-operator', + }, + { + label: 'OceanBase CE', + href: 'https://github.com/oceanbase/oceanbase', + }, + ], + }, + { + title: 'Community', + items: [ + { + label: 'Forum (in Chinese)', + href: 'https://ask.oceanbase.com/', + }, + { + label: 'Slack', + href: 'https://oceanbase.slack.com/', + }, + { + label: 'Stack Overflow', + href: 'https://stackoverflow.com/questions/tagged/oceanbase', + }, + ], + }, + ], + copyright: `Copyright © ${new Date().getFullYear()} OceanBase, Inc. Built with Docusaurus.`, + }, + prism: { + theme: prismThemes.github, + darkTheme: prismThemes.dracula, + }, + } satisfies Preset.ThemeConfig, +} + +export default config diff --git a/docsite/i18n/zh-Hans/code.json b/docsite/i18n/zh-Hans/code.json new file mode 100644 index 000000000..9e8c92b5b --- /dev/null +++ b/docsite/i18n/zh-Hans/code.json @@ -0,0 +1,444 @@ +{ + "Learn about": { + "message": "了解" + }, + "Docusaurus was designed from the ground up to be easily installed and used to get your website up and running quickly.": { + "message": "Docusaurus 从一开始就被设计成易于安装和使用,以快速搭建和运行你的网站。" + }, + "Docusaurus lets you focus on your docs, and we'll do the chores. Go ahead and move your docs into the `docs` directory.": { + "message": "Docusaurus 让你专注于文档编写,而我们来处理琐碎的事务。你可以将你的文档移动到 `docs` 目录中。" + }, + "Extend or customize your website layout by reusing React. Docusaurus can be extended while reusing the same header and footer.": { + "message": "通过重用 React,可以扩展或自定义你的网站布局。Docusaurus 可以在重用相同的页眉和页脚的同时进行扩展。" + }, + "theme.ErrorPageContent.title": { + "message": "页面已崩溃。", + "description": "The title of the fallback page when the page crashed" + }, + "theme.BackToTopButton.buttonAriaLabel": { + "message": "回到顶部", + "description": "The ARIA label for the back to top button" + }, + "theme.blog.archive.title": { + "message": "历史博文", + "description": "The page & hero title of the blog archive page" + }, + "theme.blog.archive.description": { + "message": "历史博文", + "description": "The page & hero description of the blog archive page" + }, + "theme.blog.paginator.navAriaLabel": { + "message": "博文列表分页导航", + "description": "The ARIA label for the blog pagination" + }, + "theme.blog.paginator.newerEntries": { + "message": "较新的博文", + "description": "The label used to navigate to the newer blog posts page (previous page)" + }, + "theme.blog.paginator.olderEntries": { + "message": "较旧的博文", + "description": "The label used to navigate to the older blog posts page (next page)" + }, + "theme.blog.post.paginator.navAriaLabel": { + "message": "博文分页导航", + "description": "The ARIA label for the blog posts pagination" + }, + "theme.blog.post.paginator.newerPost": { + "message": "较新一篇", + "description": "The blog post button label to navigate to the newer/previous post" + }, + "theme.blog.post.paginator.olderPost": { + "message": "较旧一篇", + "description": "The blog post button label to navigate to the older/next post" + }, + "theme.blog.post.plurals": { + "message": "{count} 篇博文", + "description": "Pluralized label for \"{count} posts\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)" + }, + "theme.blog.tagTitle": { + "message": "{nPosts} 含有标签「{tagName}」", + "description": "The title of the page for a blog tag" + }, + "theme.tags.tagsPageLink": { + "message": "查看所有标签", + "description": "The label of the link targeting the tag list page" + }, + "theme.colorToggle.ariaLabel": { + "message": "切换浅色/暗黑模式(当前为{mode})", + "description": "The ARIA label for the navbar color mode toggle" + }, + "theme.colorToggle.ariaLabel.mode.dark": { + "message": "暗黑模式", + "description": "The name for the dark color mode" + }, + "theme.colorToggle.ariaLabel.mode.light": { + "message": "浅色模式", + "description": "The name for the light color mode" + }, + "theme.docs.breadcrumbs.navAriaLabel": { + "message": "页面路径", + "description": "The ARIA label for the breadcrumbs" + }, + "theme.docs.DocCard.categoryDescription": { + "message": "{count} 个项目", + "description": "The default description for a category card in the generated index about how many items this category includes" + }, + "theme.docs.paginator.navAriaLabel": { + "message": "文件选项卡", + "description": "The ARIA label for the docs pagination" + }, + "theme.docs.paginator.previous": { + "message": "上一页", + "description": "The label used to navigate to the previous doc" + }, + "theme.docs.paginator.next": { + "message": "下一页", + "description": "The label used to navigate to the next doc" + }, + "theme.docs.tagDocListPageTitle.nDocsTagged": { + "message": "{count} 篇文档带有标签", + "description": "Pluralized label for \"{count} docs tagged\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)" + }, + "theme.docs.tagDocListPageTitle": { + "message": "{nDocsTagged}「{tagName}」", + "description": "The title of the page for a docs tag" + }, + "theme.docs.versionBadge.label": { + "message": "版本:{versionLabel}" + }, + "theme.docs.versions.unreleasedVersionLabel": { + "message": "此为 {siteTitle} {versionLabel} 版尚未发行的文档。", + "description": "The label used to tell the user that he's browsing an unreleased doc version" + }, + "theme.docs.versions.unmaintainedVersionLabel": { + "message": "此为 {siteTitle} {versionLabel} 版的文档,现已不再积极维护。", + "description": "The label used to tell the user that he's browsing an unmaintained doc version" + }, + "theme.docs.versions.latestVersionSuggestionLabel": { + "message": "最新的文档请参阅 {latestVersionLink} ({versionLabel})。", + "description": "The label used to tell the user to check the latest version" + }, + "theme.docs.versions.latestVersionLinkLabel": { + "message": "最新版本", + "description": "The label used for the latest version suggestion link label" + }, + "theme.common.editThisPage": { + "message": "编辑此页", + "description": "The link label to edit the current page" + }, + "theme.common.headingLinkTitle": { + "message": "{heading}的直接链接", + "description": "Title for link to heading" + }, + "theme.lastUpdated.atDate": { + "message": "于 {date} ", + "description": "The words used to describe on which date a page has been last updated" + }, + "theme.lastUpdated.byUser": { + "message": "由 {user} ", + "description": "The words used to describe by who the page has been last updated" + }, + "theme.lastUpdated.lastUpdatedAtBy": { + "message": "最后{byUser}{atDate}更新", + "description": "The sentence used to display when a page has been last updated, and by who" + }, + "theme.navbar.mobileVersionsDropdown.label": { + "message": "选择版本", + "description": "The label for the navbar versions dropdown on mobile view" + }, + "theme.NotFound.title": { + "message": "找不到页面", + "description": "The title of the 404 page" + }, + "theme.tags.tagsListLabel": { + "message": "标签:", + "description": "The label alongside a tag list" + }, + "theme.admonition.caution": { + "message": "警告", + "description": "The default label used for the Caution admonition (:::caution)" + }, + "theme.admonition.danger": { + "message": "危险", + "description": "The default label used for the Danger admonition (:::danger)" + }, + "theme.admonition.info": { + "message": "信息", + "description": "The default label used for the Info admonition (:::info)" + }, + "theme.admonition.note": { + "message": "备注", + "description": "The default label used for the Note admonition (:::note)" + }, + "theme.admonition.tip": { + "message": "提示", + "description": "The default label used for the Tip admonition (:::tip)" + }, + "theme.admonition.warning": { + "message": "注意", + "description": "The default label used for the Warning admonition (:::warning)" + }, + "theme.AnnouncementBar.closeButtonAriaLabel": { + "message": "关闭", + "description": "The ARIA label for close button of announcement bar" + }, + "theme.blog.sidebar.navAriaLabel": { + "message": "最近博文导航", + "description": "The ARIA label for recent posts in the blog sidebar" + }, + "theme.CodeBlock.copied": { + "message": "复制成功", + "description": "The copied button label on code blocks" + }, + "theme.CodeBlock.copyButtonAriaLabel": { + "message": "复制代码到剪贴板", + "description": "The ARIA label for copy code blocks button" + }, + "theme.CodeBlock.copy": { + "message": "复制", + "description": "The copy button label on code blocks" + }, + "theme.CodeBlock.wordWrapToggle": { + "message": "切换自动换行", + "description": "The title attribute for toggle word wrapping button of code block lines" + }, + "theme.DocSidebarItem.expandCategoryAriaLabel": { + "message": "展开侧边栏分类 '{label}'", + "description": "The ARIA label to expand the sidebar category" + }, + "theme.DocSidebarItem.collapseCategoryAriaLabel": { + "message": "折叠侧边栏分类 '{label}'", + "description": "The ARIA label to collapse the sidebar category" + }, + "theme.NavBar.navAriaLabel": { + "message": "主导航", + "description": "The ARIA label for the main navigation" + }, + "theme.TOCCollapsible.toggleButtonLabel": { + "message": "本页总览", + "description": "The label used by the button on the collapsible TOC component" + }, + "theme.NotFound.p1": { + "message": "我们找不到您要找的页面。", + "description": "The first paragraph of the 404 page" + }, + "theme.NotFound.p2": { + "message": "请联系原始链接来源网站的所有者,并告知他们链接已损坏。", + "description": "The 2nd paragraph of the 404 page" + }, + "theme.navbar.mobileLanguageDropdown.label": { + "message": "选择语言", + "description": "The label for the mobile language switcher dropdown" + }, + "theme.blog.post.readMore": { + "message": "阅读更多", + "description": "The label used in blog post item excerpts to link to full blog posts" + }, + "theme.blog.post.readMoreLabel": { + "message": "阅读 {title} 的全文", + "description": "The ARIA label for the link to full blog posts from excerpts" + }, + "theme.blog.post.readingTime.plurals": { + "message": "阅读需 {readingTime} 分钟", + "description": "Pluralized label for \"{readingTime} min read\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)" + }, + "theme.docs.breadcrumbs.home": { + "message": "主页面", + "description": "The ARIA label for the home page in the breadcrumbs" + }, + "theme.docs.sidebar.collapseButtonTitle": { + "message": "收起侧边栏", + "description": "The title attribute for collapse button of doc sidebar" + }, + "theme.docs.sidebar.collapseButtonAriaLabel": { + "message": "收起侧边栏", + "description": "The title attribute for collapse button of doc sidebar" + }, + "theme.docs.sidebar.navAriaLabel": { + "message": "文档侧边栏", + "description": "The ARIA label for the sidebar navigation" + }, + "theme.docs.sidebar.closeSidebarButtonAriaLabel": { + "message": "关闭导航栏", + "description": "The ARIA label for close button of mobile sidebar" + }, + "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": { + "message": "← 回到主菜单", + "description": "The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)" + }, + "theme.docs.sidebar.toggleSidebarButtonAriaLabel": { + "message": "切换导航栏", + "description": "The ARIA label for hamburger menu button of mobile navigation" + }, + "theme.docs.sidebar.expandButtonTitle": { + "message": "展开侧边栏", + "description": "The ARIA label and title attribute for expand button of doc sidebar" + }, + "theme.docs.sidebar.expandButtonAriaLabel": { + "message": "展开侧边栏", + "description": "The ARIA label and title attribute for expand button of doc sidebar" + }, + "theme.ErrorPageContent.tryAgain": { + "message": "重试", + "description": "The label of the button to try again rendering when the React error boundary captures an error" + }, + "theme.common.skipToMainContent": { + "message": "跳到主要内容", + "description": "The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation" + }, + "theme.tags.tagsPageTitle": { + "message": "标签", + "description": "The title of the tag list page" + }, + "theme.unlistedContent.title": { + "message": "未列出页", + "description": "The unlisted content banner title" + }, + "theme.unlistedContent.message": { + "message": "此页面未列出。搜索引擎不会对其索引,只有拥有直接链接的用户才能访问。", + "description": "The unlisted content banner message" + }, + "Easy to Use": { + "message": "简单易用" + }, + "Focus on What Matters": { + "message": "关注焦点" + }, + "Powered by React": { + "message": "React 赋能" + }, + "OceanBase is an enterprise distributed relational database developed by Ant Group.": { + "message": "OceanBase 是由蚂蚁集团完全自主研发的企业级分布式关系型数据库" + }, + "theme.SearchPage.documentsFound.plurals": { + "message": "找到 {count} 份文件", + "description": "Pluralized label for \"{count} documents found\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)" + }, + "theme.SearchPage.existingResultsTitle": { + "message": "「{query}」的搜索结果", + "description": "The search page title for non-empty query" + }, + "theme.SearchPage.emptyResultsTitle": { + "message": "在文档中搜索", + "description": "The search page title for empty query" + }, + "theme.SearchPage.inputPlaceholder": { + "message": "在此输入搜索字词", + "description": "The placeholder for search page input" + }, + "theme.SearchPage.inputLabel": { + "message": "搜索", + "description": "The ARIA label for search page input" + }, + "theme.SearchPage.algoliaLabel": { + "message": "通过 Algolia 搜索", + "description": "The ARIA label for Algolia mention" + }, + "theme.SearchPage.noResultsText": { + "message": "未找到任何结果", + "description": "The paragraph for empty search result" + }, + "theme.SearchPage.fetchingNewResults": { + "message": "正在获取新的搜索结果...", + "description": "The paragraph for fetching new search results" + }, + "theme.SearchBar.label": { + "message": "搜索", + "description": "The ARIA label and placeholder for search button" + }, + "theme.SearchModal.searchBox.resetButtonTitle": { + "message": "清除查询", + "description": "The label and ARIA label for search box reset button" + }, + "theme.SearchModal.searchBox.cancelButtonText": { + "message": "取消", + "description": "The label and ARIA label for search box cancel button" + }, + "theme.SearchModal.startScreen.recentSearchesTitle": { + "message": "最近搜索", + "description": "The title for recent searches" + }, + "theme.SearchModal.startScreen.noRecentSearchesText": { + "message": "没有最近搜索", + "description": "The text when no recent searches" + }, + "theme.SearchModal.startScreen.saveRecentSearchButtonTitle": { + "message": "保存这个搜索", + "description": "The label for save recent search button" + }, + "theme.SearchModal.startScreen.removeRecentSearchButtonTitle": { + "message": "从历史记录中删除这个搜索", + "description": "The label for remove recent search button" + }, + "theme.SearchModal.startScreen.favoriteSearchesTitle": { + "message": "收藏", + "description": "The title for favorite searches" + }, + "theme.SearchModal.startScreen.removeFavoriteSearchButtonTitle": { + "message": "从收藏列表中删除这个搜索", + "description": "The label for remove favorite search button" + }, + "theme.SearchModal.errorScreen.titleText": { + "message": "无法获取结果", + "description": "The title for error screen of search modal" + }, + "theme.SearchModal.errorScreen.helpText": { + "message": "你可能需要检查网络连接。", + "description": "The help text for error screen of search modal" + }, + "theme.SearchModal.footer.selectText": { + "message": "选中", + "description": "The explanatory text of the action for the enter key" + }, + "theme.SearchModal.footer.selectKeyAriaLabel": { + "message": "Enter 键", + "description": "The ARIA label for the Enter key button that makes the selection" + }, + "theme.SearchModal.footer.navigateText": { + "message": "导航", + "description": "The explanatory text of the action for the Arrow up and Arrow down key" + }, + "theme.SearchModal.footer.navigateUpKeyAriaLabel": { + "message": "向上键", + "description": "The ARIA label for the Arrow up key button that makes the navigation" + }, + "theme.SearchModal.footer.navigateDownKeyAriaLabel": { + "message": "向下键", + "description": "The ARIA label for the Arrow down key button that makes the navigation" + }, + "theme.SearchModal.footer.closeText": { + "message": "关闭", + "description": "The explanatory text of the action for Escape key" + }, + "theme.SearchModal.footer.closeKeyAriaLabel": { + "message": "Esc 键", + "description": "The ARIA label for the Escape key button that close the modal" + }, + "theme.SearchModal.footer.searchByText": { + "message": "搜索提供", + "description": "The text explain that the search is making by Algolia" + }, + "theme.SearchModal.noResultsScreen.noResultsText": { + "message": "没有结果:", + "description": "The text explains that there are no results for the following search" + }, + "theme.SearchModal.noResultsScreen.suggestedQueryText": { + "message": "试试搜索", + "description": "The text for the suggested query when no results are found for the following search" + }, + "theme.SearchModal.noResultsScreen.reportMissingResultsText": { + "message": "认为这个查询应该有结果?", + "description": "The text for the question where the user thinks there are missing results" + }, + "theme.SearchModal.noResultsScreen.reportMissingResultsLinkText": { + "message": "请告知我们。", + "description": "The text for the link to report missing results" + }, + "theme.SearchModal.placeholder": { + "message": "搜索文档", + "description": "The placeholder of the input of the DocSearch pop-up modal" + }, + "theme.SearchBar.seeAll": { + "message": "查看全部 {count} 个结果" + } +} diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-blog/options.json b/docsite/i18n/zh-Hans/docusaurus-plugin-content-blog/options.json new file mode 100644 index 000000000..7d94382c5 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-blog/options.json @@ -0,0 +1,14 @@ +{ + "title": { + "message": "博客", + "description": "The title for the blog used in SEO" + }, + "description": { + "message": "博客", + "description": "The description for the blog used in SEO" + }, + "sidebar.title": { + "message": "近期发布", + "description": "The label for the left sidebar" + } +} diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current.json b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current.json new file mode 100644 index 000000000..01b262df9 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current.json @@ -0,0 +1,82 @@ +{ + "version.label": { + "message": "下一篇", + "description": "The label for version current" + }, + "sidebar.oboperatorSidebar.category.ob-operator-user-guide": { + "message": " ob-operator 用户手册", + "description": "The label for category ob-operator-user-guide in sidebar oboperatorSidebar" + }, + "sidebar.oboperatorSidebar.category.cluster-management-of-ob-operator": { + "message": "集群管理", + "description": "The label for category cluster-management-of-ob-operator in sidebar oboperatorSidebar" + }, + "sidebar.oboperatorSidebar.category.zone-management": { + "message": "Zone 管理", + "description": "The label for category zone-management in sidebar oboperatorSidebar" + }, + "sidebar.oboperatorSidebar.category.server-management": { + "message": "Server 管理", + "description": "The label for category server-management in sidebar oboperatorSidebar" + }, + "sidebar.oboperatorSidebar.category.tenant-management-of-ob-operator": { + "message": "租户管理", + "description": "The label for category tenant-management-of-ob-operator in sidebar oboperatorSidebar" + }, + "sidebar.oboperatorSidebar.category.modify-tenant-of-ob-operator": { + "message": "修改租户", + "description": "The label for category modify-tenant-of-ob-operator in sidebar oboperatorSidebar" + }, + "sidebar.oboperatorSidebar.category.high-availability": { + "message": "高可用", + "description": "The label for category high-availability in sidebar oboperatorSidebar" + }, + "sidebar.oboperatorSidebar.category.appendix": { + "message": "附录", + "description": "The label for category appendix in sidebar oboperatorSidebar" + }, + "sidebar.obdSidebar.category.user-guide": { + "message": "用户手册", + "description": "The label for category user-guide in sidebar obdSidebar" + }, + "sidebar.obdSidebar.category.obd-command": { + "message": "obd 命令", + "description": "The label for category obd-command in sidebar obdSidebar" + }, + "sidebar.obdSidebar.category.faq": { + "message": "FAQ", + "description": "The label for category faq in sidebar obdSidebar" + }, + "sidebar.manualSidebar.category.Manage resources": { + "message": "资源运维", + "description": "The label for category Manage resources in sidebar manualSidebar" + }, + "sidebar.manualSidebar.category.Cluster management": { + "message": "集群管理", + "description": "The label for category Cluster management in sidebar manualSidebar" + }, + "sidebar.manualSidebar.category.Zone management": { + "message": "Zone 管理", + "description": "The label for category Zone management in sidebar manualSidebar" + }, + "sidebar.manualSidebar.category.Server management": { + "message": "Server 管理", + "description": "The label for category Server management in sidebar manualSidebar" + }, + "sidebar.manualSidebar.category.Tenant management": { + "message": "租户管理", + "description": "The label for category Tenant management in sidebar manualSidebar" + }, + "sidebar.manualSidebar.category.Modify tenant": { + "message": "修改租户配置", + "description": "The label for category Modify tenant in sidebar manualSidebar" + }, + "sidebar.manualSidebar.category.High availability": { + "message": "高可用", + "description": "The label for category High availability in sidebar manualSidebar" + }, + "sidebar.manualSidebar.category.Appendix": { + "message": "附录", + "description": "The label for category Appendix in sidebar manualSidebar" + } +} diff --git a/docs/zh_CN/arch.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer/arch.md similarity index 76% rename from docs/zh_CN/arch.md rename to docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer/arch.md index 038b09353..fe46fc377 100644 --- a/docs/zh_CN/arch.md +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer/arch.md @@ -1,7 +1,5 @@ # 架构设计 -[English version](../en_US/arch.md) is available. - 本文不涉及 OceanBase 数据库本身的架构和数据库管理说明,如需了解请参见[官网文档](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000217922)。 ob-operator 遵循 Kubernetes 的 [Operator 拓展范式](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/),聚焦于自定义资源及其控制逻辑。ob-operator 使用 Operator 开发框架 [kubebuilder@v3](https://book.kubebuilder.io/introduction) 为基础进行开发,所以底层架构与 [kubebuilder 的架构](https://book.kubebuilder.io/architecture)相近。通过向上在 Kubernetes 控制平面全局注册 Controller Manager,向下管理若干控制器和 Webhook,来对自定义的资源进行控制。 @@ -67,43 +65,4 @@ Kubernetes 在内部采用控制循环和消息队列的方式来实现事件的 控制循环、资源管理器、任务管理器的关系如下图所示。 -![控制循环、资源管理器、任务管理器的关系](../img/ob-operator-arch.png) - -## 资源与任务管理器的交互 - -任务流中的任务由资源管理器 `ResourceManager` 提交给全局的任务管理器 `TaskManager` 来执行,资源、资源管理器和任务管理器的大致关系和相互作用流程如下面的时序图所示: - -
-
-sequenceDiagram
-	participant r as Resource
-	participant c as Controller (ResourceManager)
-	participant t as TaskManager
-	autonumber
-	r->>c: Resource changes
-	c->>t: Get task flow according to recourse status
-	t->>t: Create goroutine to execute specific task
-	t->>c: Return task ID to controller
-	c->>r: Stores task ID and other task context in resource
-	loop Watch task progress
-		r->>c: Requeue and requeue
-		c->>t: Checks the task status
-		alt If task is still pending
-			t->>c: Empty result
-			c->>c: Continues loop and requeues resource with a shorter interval
-		else If task is finished
-			t->>c: Task results
-			alt if no other tasks in flow
-				c->>r: Updates status of resource
-			else if there are other tasks in flow
-				c->>r: Updates task context of resource
-				c->>t: Watches progress of new task, back to [6] loop
-			end
-		end
-	end
-	t->>t: Clean maps
-  
- -
\ No newline at end of file +![控制循环、资源管理器、任务管理器的关系](/img/ob-operator-arch.png) diff --git a/docs/en_US/contributor-guidance.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer/contributor-guidance.md similarity index 85% rename from docs/en_US/contributor-guidance.md rename to docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer/contributor-guidance.md index ff6556af3..c3fbfdbae 100644 --- a/docs/en_US/contributor-guidance.md +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer/contributor-guidance.md @@ -12,11 +12,11 @@ Before you start contributing, we strongly encourage you to review our [Code of ## Getting Started with Development -To get started with developing for our project, please refer to our [Development Guidelines](./develop-locally.md). This document provides the necessary steps to set up the development environment on your laptop. +To get started with developing for our project, please refer to our [Development Guidelines](develop-locally.md). This document provides the necessary steps to set up the development environment on your laptop. ## Deploying Changes -If you are working on changes that require deployment, look at our [Deployment Guide](./develop-locally.md) for detailed instructions on how to deploy and test your changes in a production-like environment. This ensures that all changes are vetted for stability and compatibility before being integrated. +If you are working on changes that require deployment, look at our [Deployment Guide](develop-locally.md) for detailed instructions on how to deploy and test your changes in a production-like environment. This ensures that all changes are vetted for stability and compatibility before being integrated. ## How to Contribute @@ -44,6 +44,6 @@ Here is a brief overview of how you can contribute to our project: ## Need Help? -If you have any questions or need further assistance, don't hesitate to reach out to our community via [issues](https://github.com/oceanbase/ob-operator/issues), [slack workspace](https://oceanbase.slack.com) or [dingtalk](../img/dingtalk-operator-users.png). Our maintainers and community members are here to help you and make your contributing experience enjoyable. +If you have any questions or need further assistance, don't hesitate to reach out to our community via [issues](https://github.com/oceanbase/ob-operator/issues), [slack workspace](https://oceanbase.slack.com) or [dingtalk](/img/dingtalk-operator-users.png). Our maintainers and community members are here to help you and make your contributing experience enjoyable. Once again, thank you for your interest in contributing to our project. Your efforts will help us build a better and stronger project for everyone. We look forward to your contributions and are thrilled to have you as part of our community! diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer/deploy-locally.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer/deploy-locally.md new file mode 100644 index 000000000..c00be9f81 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer/deploy-locally.md @@ -0,0 +1,207 @@ +# Deploy ob-operator locally + +## Hardware requirements + +* CPU: 4 Core available +* Memory: 10 GB available (A Single-node OceanBase cluster takes 8 ~ 9 GB memory) +* Disk space: 120 GB available + +## Software requirements + +You need to install the following softwares before getting started. Installation instructions can be found on their websites. You can get minkube by brew install minikube if you develop on macOS. +* [kubernetes/minikube](https://github.com/kubernetes/minikube): Run kubernetes locally +* [Docker desktop](https://www.docker.com/products/docker-desktop/): Manage container development locally +* [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl): Kubernetes CLI (optional if you prefer minikube kubectl) + +## Setup steps + +### 1. Configure Docker Resources + +Open Docker desktop - Settings - Resources, set `CPU limit`, `Memory limit` and `Virtual disk limit` to match the hardware requirements. + +![Docker Limits](/img/docker-limit.png) + +### 2. Start minikube cluster + +In order to make sure that the hardware limit are enforced to VM in minikube, we set configurations of minikube again by: + +```shell +minikube config set cpus 4 +minikube config set disk-size 120GB +minikube config set memory 10GB +``` + +Here we go! Just type `minikube start` and enter, we can see it starts fetching necessary images. After it says initialization is finished, we can type `kubectl get pods -A` (or `minikube kubectl -- get pods -A`) to see all pods in minikube cluster. + +Tips: Perform `minikube dashboard` to open kubernetes dashboard, everything in the cluster could be more clear. + +### 3. Install cert-manager + +ob-operator depends on `cert-manager` to enable TLS functionalities, so we should install it first. + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.1_release/deploy/cert-manager.yaml +``` + +### 4. Install ob-operator + +For robustness, default memory limit of ob-operator container is set to `1Gi` which is too large for us developing locally. We recommend fetching the manifests to local and configure it. wget tool could be useful here, while opening the URL and copying the contents to local file is more straight. + +https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.1_release/deploy/operator.yaml + +Search the pattern `/manager`, find the target container, configure the memory limit to `400Mi` and cpu limit to `400m`. + +OK, now we apply the manifest with `kubectl`. + +```shell +kubectl apply -f operator.yaml +``` + +And check whether the pod gets running successfully, + +```shell +kubectl get pods -n oceanbase-system +``` + +### 5. Deploy OceanBase cluster + +Apply the following yaml file to the cluster, + +```shell quick-cluster.yaml +apiVersion: v1 +kind: Secret +metadata: + name: demo-password + namespace: default +stringData: + password: "AAaa__321" +--- +apiVersion: oceanbase.oceanbase.com/v1alpha1 +kind: OBCluster +metadata: + name: test + namespace: default +spec: + clusterName: obcluster + clusterId: 1 + userSecrets: + root: demo-password + proxyro: demo-password + monitor: demo-password + operator: demo-password + topology: + - zone: zone1 + replica: 1 + observer: + image: oceanbase/oceanbase-cloud-native:4.2.1.1-101010012023111012 + resource: + cpu: 2 + memory: 9Gi + storage: + dataStorage: + storageClass: standard + size: 40Gi + redoLogStorage: + storageClass: standard + size: 40Gi + logStorage: + storageClass: standard + size: 10Gi + parameters: + - name: system_memory + value: 1G + - name: "__min_full_resource_pool_memory" + value: "2147483648" # 2G +``` + +You will see outputs like: + +```shell +secret/demo-password created +obcluster.oceanbase.oceanbase.com/test created +``` + +It will take 2~3 minutes for OceanBase cluster to bootstrap. We should wait for it to get ready before we try to connect it. Use `kubectl wait` to do this, + +```shell +kubectl wait obcluster test --for jsonpath='{.status.status}'=running --timeout=10m + +# After the cluster bootstraps successfully, the terminal outputs: +# obcluster.oceanbase.oceanbase.com/test condition met +``` + +Connect to the sys tenant of the cluster, + +```shell +PODNAME=$(kubectl get pods -l ref-obcluster=test -o jsonpath='{.items[*].metadata.name}') +PASSWORD=$(kubectl get secret demo-password -o jsonpath='{.data.password}' | base64 --decode) +kubectl exec pods/$PODNAME -- yum install -y mysql +kubectl exec -it pods/$PODNAME -- mysql -h127.0.0.1 -P2881 -uroot -p$PASSWORD +``` + +And you will enter the REPL of mysql, + +```shell +Welcome to the MySQL monitor. Commands end with ; or \g. +Your MySQL connection id is 3221488229 +Server version: 5.7.25 OceanBase_CE 4.2.1.1 (r101010012023111012-2f6924cd5a576f09d6e7f212fac83f1a15ff531a) (Built Nov 10 2023 12:13:37) + +Copyright (c) 2000, 2023, Oracle and/or its affiliates. + +Oracle is a registered trademark of Oracle Corporation and/or its +affiliates. Other names may be trademarks of their respective +owners. + +Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. + +mysql> +``` + +### 6. Create tenant in deployed OceanBase cluster + +Apply the following yaml manifest, + +```shell quick-tennat.yaml +apiVersion: oceanbase.oceanbase.com/v1alpha1 +kind: OBTenant +metadata: + name: t1 + namespace: default +spec: + obcluster: test + tenantName: t1 + unitNum: 1 + charset: utf8mb4 + connectWhiteList: "%" + forceDelete: true + credentials: + root: demo-password + standbyRo: demo-password + pools: + - zone: zone1 + type: + name: Full + replica: 1 + isActive: true + resource: + maxCPU: 1 + memorySize: 2Gi + minCPU: 1 + maxIops: 1024 + minIops: 1024 + iopsWeight: 2 + logDiskSize: 4Gi +``` + +Wait for the tenant to be initialized, + +```shell +kubectl wait obtenant t1 --for jsonpath='{.status.status}'=running --timeout=10m +``` + +Connect to the tenant, + +```shell +PODNAME=$(kubectl get pods -l ref-obcluster=test -o jsonpath='{.items[*].metadata.name}') +kubectl exec -it pods/$PODNAME -- mysql -h127.0.0.1 -P2881 -uroot@t1 +``` \ No newline at end of file diff --git a/docs/zh_CN/deploy.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer/deploy.md similarity index 93% rename from docs/zh_CN/deploy.md rename to docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer/deploy.md index 52d7b9684..67afffefa 100644 --- a/docs/zh_CN/deploy.md +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer/deploy.md @@ -1,7 +1,5 @@ # ob-operator 部署 -[English version](../en_US/deploy.md) is available. - 本文介绍 ob-operator 的部署方式。 ## 1. 部署依赖 @@ -12,20 +10,20 @@ ob-operator 支持通过 Helm 进行部署,在使用 Helm 命令部署 ob-oper ```shell helm repo add ob-operator https://oceanbase.github.io/ob-operator/ -helm install ob-operator ob-operator/ob-operator --namespace=oceanbase-system --create-namespace --version=2.1.2 +helm install ob-operator ob-operator/ob-operator --namespace=oceanbase-system --create-namespace --version=2.2.0 ``` 参数说明: * namespace:命名空间,可自定义,一般建议使用 oceanbase-system。 -* version:ob-operator 版本号,建议使用最新的版本 `2.1.2`。 +* version:ob-operator 版本号,建议使用最新的版本 `2.2.0`。 ## 2.2 使用配置文件部署 * Stable ```shell -kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.2_release/deploy/operator.yaml +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.2.0_release/deploy/operator.yaml ``` * Development ```shell diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer/develop-locally.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer/develop-locally.md new file mode 100644 index 000000000..ab39f6d76 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer/develop-locally.md @@ -0,0 +1,165 @@ +# Develop ob-operator locally + +Tips: In this tutorial, we'll disable webhook validation and run manager controller on our laptop. The controller manager will communicate with kubernetes cluster by local .kube/config configuration file. + +## Background + +ob-operator depends on [kubebuilder](https://kubebuilder.io/introduction), an operator framework maintained by kubernetes SIGS. It offers convenient utilities to bootstrap an operator and manage API types in it. Like other operator frameworks, kubebuilder depends on kubernetes [controller runtime](https://github.com/kubernetes-sigs/controller-runtime) either, which is an excellent reference to know how kubernetes dispatch events and reconcile resources. + +## Disable Webhook and CertManager + +There are many configuration items that marked by `[CERTMANAGER]` and `[WEBHOOK]` in the two files `config/crd/kustomization.yaml` and `config/default/kustomization.yaml`. They are used to enable and configure webhooks in real kubernetes deployment. Because we want to run controller manager locally, we need to disable them. + +You could just apply the latest `deploy/operator.yaml` manifest and delete the following resources to deploy CRDs and make controller manager uninstalled. + +```shell +kubectl delete validatingwebhookconfigurations.admissionregistration.k8s.io oceanbase-validating-webhook-configuration +kubectl delete mutatingwebhookconfigurations.admissionregistration.k8s.io oceanbase-mutating-webhook-configuration +kubectl delete -n oceanbase-system svc oceanbase-webhook-service +kubectl delete -n oceanbase-system deployments.apps oceanbase-controller-manager +``` + +## Self-signed Certificate + +It's necessary for node hosting controller manager to have a TLS certificate. In the real kubernetes cluster, the cert-manager will inject the sign into the controller manager pod. On our laptop, we need self-sign one: + +```shell +mkdir -p /tmp/k8s-webhook-server/serving-certs +openssl genrsa -out /tmp/k8s-webhook-server/serving-certs/tls.key 2048 +openssl req -new -key /tmp/k8s-webhook-server/serving-certs/tls.key -out /tmp/k8s-webhook-server/serving-certs/tls.csr +openssl x509 -req -days 365 -in /tmp/k8s-webhook-server/serving-certs/tls.csr -signkey /tmp/k8s-webhook-server/serving-certs/tls.key -out /tmp/k8s-webhook-server/serving-certs/tls.crt +``` + +## Run locally + +There are some useful commands in `Makefile` and `make/*.mk`, we could type `make run-local` to start controller manager locally. Or redirect the output to a log file for better analytic experience, + +```shell +# print log to stdout +make run-local +# or redirect output to a file +make run-local &> bin/run.log +``` + +## Debug locally + +Though print debugging is enough for most cases, there are quite some cases that are not obvious from printed information. We could debug with go debugging tool [delve](https://github.com/go-delve/delve). + +`install-delve` command is declared in `make/debug.mk`, we can type `make install-delve` to get it. The help message of it can be glanced, + +```shell dlv help +Delve is a source level debugger for Go programs. + +Delve enables you to interact with your program by controlling the execution of the process, +evaluating variables, and providing information of thread / goroutine state, CPU register state and more. + +The goal of this tool is to provide a simple yet powerful interface for debugging Go programs. + +Pass flags to the program you are debugging using `--`, for example: + +`dlv exec ./hello -- server --config conf/config.toml` + +Usage: + dlv [command] + +Available Commands: + attach Attach to running process and begin debugging. + completion Generate the autocompletion script for the specified shell + connect Connect to a headless debug server with a terminal client. + core Examine a core dump. + dap Starts a headless TCP server communicating via Debug Adaptor Protocol (DAP). + debug Compile and begin debugging main package in current directory, or the package specified. + exec Execute a precompiled binary, and begin a debug session. + help Help about any command + test Compile test binary and begin debugging program. + trace Compile and begin tracing program. + version Prints version. + +Additional help topics: + dlv backend Help about the --backend flag. + dlv log Help about logging flags. + dlv redirect Help about file redirection. +``` + +## Start debugging + +Run `make run-delve` to start debugging server. + +### Debug in terminal + +If you prefer to debug in terminal, with `dlv connect 127.0.0.1:2345` command you can connect to the debugging server. After connecting, you enter a REPL environment of delve, available commands are showed below, + +```shell +(dlv) help +The following commands are available: + +Running the program: + call ------------------------ Resumes process, injecting a function call (EXPERIMENTAL!!!) + continue (alias: c) --------- Run until breakpoint or program termination. + next (alias: n) ------------- Step over to next source line. + rebuild --------------------- Rebuild the target executable and restarts it. It does not work if the executable was not built by delve. + restart (alias: r) ---------- Restart process. + step (alias: s) ------------- Single step through program. + step-instruction (alias: si) Single step a single cpu instruction. + stepout (alias: so) --------- Step out of the current function. + +Manipulating breakpoints: + break (alias: b) ------- Sets a breakpoint. + breakpoints (alias: bp) Print out info for active breakpoints. + clear ------------------ Deletes breakpoint. + clearall --------------- Deletes multiple breakpoints. + condition (alias: cond) Set breakpoint condition. + on --------------------- Executes a command when a breakpoint is hit. + toggle ----------------- Toggles on or off a breakpoint. + trace (alias: t) ------- Set tracepoint. + watch ------------------ Set watchpoint. + +Viewing program variables and memory: + args ----------------- Print function arguments. + display -------------- Print value of an expression every time the program stops. + examinemem (alias: x) Examine raw memory at the given address. + locals --------------- Print local variables. + print (alias: p) ----- Evaluate an expression. + regs ----------------- Print contents of CPU registers. + set ------------------ Changes the value of a variable. + vars ----------------- Print package variables. + whatis --------------- Prints type of an expression. + +Listing and switching between threads and goroutines: + goroutine (alias: gr) -- Shows or changes current goroutine + goroutines (alias: grs) List program goroutines. + thread (alias: tr) ----- Switch to the specified thread. + threads ---------------- Print out info for every traced thread. + +Viewing the call stack and selecting frames: + deferred --------- Executes command in the context of a deferred call. + down ------------- Move the current frame down. + frame ------------ Set the current frame, or execute command on a different frame. + stack (alias: bt) Print stack trace. + up --------------- Move the current frame up. + +Other commands: + config --------------------- Changes configuration parameters. + disassemble (alias: disass) Disassembler. + dump ----------------------- Creates a core dump from the current process state + edit (alias: ed) ----------- Open where you are in $DELVE_EDITOR or $EDITOR + exit (alias: quit | q) ----- Exit the debugger. + funcs ---------------------- Print list of functions. + help (alias: h) ------------ Prints the help message. + libraries ------------------ List loaded dynamic libraries + list (alias: ls | l) ------- Show source code. + packages ------------------- Print list of packages. + source --------------------- Executes a file containing a list of delve commands + sources -------------------- Print list of source files. + target --------------------- Manages child process debugging. + transcript ----------------- Appends command output to a file. + types ---------------------- Print list of types + +Type help followed by a command for full documentation. +``` + +### In VSCode + +If you are first to debugging in VSCode, enter `Cmd+Shift+P` to open commands panel. Then, type `Debug: Add Configuration...` and create debugging task for Go. After creating task successfully, open commands panel and type `Debug: Start Debugging`/`Debug: Select and Start Debugging` to start debugging. + +![Debug in VSCode](/img/debug-in-vscode.png) \ No newline at end of file diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer/development.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer/development.md new file mode 100644 index 000000000..397efab51 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer/development.md @@ -0,0 +1,70 @@ +# Developing ob-operator + +## environment-setup +1. go +ob-operator requires [go 1.20 or above](https://go.dev/doc/install) to build, you can refer to the official document to setup go environment. + +2. make +ob-operator uses [make](https://www.gnu.org/software/make/) for a variety of build and test actions, it's need to be installed before you go. + +3. kubebuilder +ob-operator uses kubebuilder as operator framework, before you dive into the code, it's highly recommended to read [kubebuilder books](https://book.kubebuilder.io). + +## build ob-operator + +1. build docker image +use the following command to build docker image +``` +make docker-build +``` + +2. push docker image to repository +use the following command to push docker image +``` +make docker-push +``` + +## deploy + +1. install crd to K8s cluster +use the following command to generate crd and install to K8s cluster +``` +make install +``` +if you wish to save the crd as yaml format config file, you can run the following command +``` +make export-crd +``` +the generated file will be placed under deploy directory and named crd.yaml + +2. deploy controller-manager to K8s cluster +use the following command to generate controller-manager config and deploy to K8s cluster +``` +make deploy +``` +if you wish to save the controller-manager deployment config as yaml format config file, you can run the following command +``` +make export-operator +``` +the generated file will be placed under deploy directory and named operator.yaml + +After the above steps, CRDs and controller-manager are deployed to K8s cluster, to check the deployments are successful, you can check with the following command +``` +# check crds +kubectl get crds + +# check controller-manager +kubectl get pods -n oceanbase-system +``` +you will get something like the following +![crd](/img/crd.jpg "crd") +![controller-manager](/img/controller-manager.jpg "controller-manager") + +## check logs +After deploying the crds and controller-manager, ob-operator will handle OceanBase related objects lifecycle management, you may test your own business by create a cr and make some modifications, ob-operator will handle the certain event. To test everything works properly, you can use the following command to check log message. +``` +kubectl logs oceanbase-controller-manager-xxx -c manager -n oceanbase-system +``` + +`oceanbase-controller-manager-xxx` should be replaced by the real pod name + diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/100.what-is-ob-operator.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/100.what-is-ob-operator.md new file mode 100644 index 000000000..a7cf4207e --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/100.what-is-ob-operator.md @@ -0,0 +1,13 @@ +# ob-operator 概述 + +## 什么是 ob-operator + +ob-operator 是一款基于 Kubernetes Operator 框架构建的工具,用于在 Kubernetes 中管理 OceanBase 集群。它提供了一种简单可靠的方式来实现 OceanBase 集群的容器化部署,可以简化 OceanBase 的运维。ob-operator 定义了 OceanBase 相关的各种资源并且实现相应的调协逻辑,因此您可以像管理 Kubernetes 的原生资源一样,通过声明式的方式管理 OceanBase。 + +## ob-operator 功能特点 + +ob-operator 具有以下功能特点,ob-operator 提供了以下功能,覆盖了日常对于 OceanBase 运维所需的全部功能: + +* [OceanBase 集群管理](500.ob-operator-user-guide/100.cluster-management-of-ob-operator/100.cluster-management-intro.md):集群自举、调整集群拓扑、支持 K8s 拓扑配置、扩缩容、集群升级、修改参数 +* [OceanBase 租户管理](500.ob-operator-user-guide/200.tenant-management-of-ob-operator/000.tenant-management-intro.md):创建租户、调整租户拓扑、管理资源单元、修改用户密码 +* [OceanBase 高可用](500.ob-operator-user-guide/300.high-availability/100.high-availability-intro.md):备份恢复、物理备库、故障恢复 diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/200.quick-start-of-ob-operator.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/200.quick-start-of-ob-operator.md new file mode 100644 index 000000000..8d9493887 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/200.quick-start-of-ob-operator.md @@ -0,0 +1,93 @@ +# 快速上手 + +本文将以部署 ob-operator 以及部署 OceanBase 集群为例,指导您如何快速使用 ob-operator 进行 OceanBase 的管理。 + +## 前提条件 + +在开始之前,请确保您已满足以下条件: + +- 您有可用的 Kubernetes 集群且至少有2 个 CPU,10GB 内存和 100GB 存储空间。 +- 您已安装 cert-manager。cert-manager 的安装方法请参考对应的 [安装文档](https://cert-manager.io/docs/installation/)。 +- 您已安装 local-path-provisioner 并确认其配置的目标地点有足够的存储空间。local-path-provisioner 的安装方法请参考对应的 [安装文档](https://github.com/rancher/local-path-provisioner)。 + +## 部署 ob-operator + +使用以下命令在 Kubernetes 集群中部署 ob-operator: + +- 稳定版本 + + ```shell + kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.0_release/deploy/operator.yaml + ``` + +- 开发版本 + + ```shell + kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/master/deploy/operator.yaml + ``` + +使用以下命令验证 ob-operator 是否成功部署: + +```shell +kubectl get pod -n oceanbase-system +``` + +预期输出: + +```shell +NAME READY STATUS RESTARTS AGE +oceanbase-controller-manager-86cfc8f7bf-4hfnj 2/2 Running 0 1m +``` + +## 部署 OceanBase 集群 + +按照以下步骤在 Kubernetes 集群上部署 OceanBase 集群: + +1. 创建 Secrets + 在创建 OceanBase 集群之前,您必须创建特定用户所需的 secrets。使用以下命令创建 secrets: + + ```shell + kubectl create secret generic root-password --from-literal=password='root_password' + kubectl create secret generic proxyro-password --from-literal=password='proxyro_password' + kubectl create secret generic monitor-password --from-literal=password='monitor_password' + kubectl create secret generic operator-password --from-literal=password='operator_password' + ``` + +2. 部署 OceanBase 集群 + 使用以下命令在 Kubernetes 集群上部署 OceanBase 集群: + + ```shell + kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.0_release/example/quickstart/obcluster.yaml + ``` + + 集群创建通常需要约 2 分钟。执行以下命令检查集群状态: + + ```shell + kubectl get obclusters.oceanbase.oceanbase.com test + ``` + + 预期输出: + + ```shell + NAME STATUS AGE + test running 6m2s + ``` + +3. 连接 OceanBase 集群 + 按照以下步骤连接新创建的 OceanBase 集群: + + ```shell + # 使用以下命令查找 observer 的 POD IP 和 POD 名称 + # POD 名的规则为 {cluster_name}-{cluster_id}-{zone}-uuid + kubectl get pods -o wide + # 使用以下命令连接集群 + mysql -h{POD_IP} -P2881 -uroot -p'root_password' oceanbase -A -c + ``` + +如果您有任何问题或需要进一步帮助,请随时咨询。 + +## 后续操作 + +本文介绍了快速部署 ob-operator 和 OceanBase 集群,适用于快速搭建环境。在生产环境中的集群部署和运维,参考 [OceanBase 集群管理](500.ob-operator-user-guide/100.cluster-management-of-ob-operator/100.cluster-management-intro.md)。 + +在成功创建集群后,在运行业务之前,您需要创建业务租户。有关租户管理的内容,参考 [OceanBase 租户管理](500.ob-operator-user-guide/200.tenant-management-of-ob-operator/000.tenant-management-intro.md)。 diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/300.deploy-ob-operator.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/300.deploy-ob-operator.md new file mode 100644 index 000000000..6a82a62cd --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/300.deploy-ob-operator.md @@ -0,0 +1,76 @@ +# ob-operator 部署 + +本文介绍如何部署 ob-operator。 + +## 前提条件 + +ob-operator 依赖 cert-manager。在部署 ob-operator 之前,确保您已安装 cert-manager。cert-manager 的安装方法请参考对应的 [安装文档](https://cert-manager.io/docs/installation/)。 + +## 使用 Helm 部署 + +ob-operator 支持使用 Helm 部署。在使用 Helm 命令部署 ob-operator 之前,确保您已安装 [Helm](https://github.com/helm/helm)。Helm 安装完成后,使用以下命令部署 ob-operator: + +```shell +helm repo add ob-operator https://oceanbase.github.io/ob-operator/ +helm install ob-operator ob-operator/ob-operator --namespace=oceanbase-system --create-namespace --version=2.1.0 +``` + +参数说明: + +* namespace:命名空间,可根据需要自定义,建议使用 `oceanbase-system`。 + +* version:ob-operator 版本号,建议使用最新的版本。 + +## 使用配置文件部署 + +您可以直接使用配置文件部署 ob-operator。根据您的需求选择稳定版本或开发版本的配置文件。 + +* 稳定版本 + + ```shell + kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.0_release/deploy/operator.yaml + ``` + +* 开发版本 + + ```shell + kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/master/deploy/operator.yaml + ``` + +一般建议使用稳定版本的配置文件,如果您想使用开发中的版本,可以选择使用开发的配置文件。 + +## 查看部署结果 + +部署成功后,您可以通过以下命令查看 CRD 的定义,以确认部署是否成功: + +```shell +kubectl get crds +``` + +如果输出与以下示例相似,则表示部署成功: + +```shell +NAME CREATED AT +obparameters.oceanbase.oceanbase.com 2023-11-12T08:06:58Z +observers.oceanbase.oceanbase.com 2023-11-12T08:06:58Z +obtenantbackups.oceanbase.oceanbase.com 2023-11-12T08:06:58Z +obtenantrestores.oceanbase.oceanbase.com 2023-11-12T08:06:58Z +obzones.oceanbase.oceanbase.com 2023-11-12T08:06:58Z +obtenants.oceanbase.oceanbase.com 2023-11-12T08:06:58Z +obtenantoperations.oceanbase.oceanbase.com 2023-11-12T08:06:58Z +obclusters.oceanbase.oceanbase.com 2023-11-12T08:06:58Z +obtenantbackuppolicies.oceanbase.oceanbase.com 2023-11-12T08:06:58Z +``` + +通过如下命令确认 ob-operator 部署成功。 + +```shell +kubectl get pods -n oceanbase-system +``` + +返回结果如下,当看到所有容器都 ready 时并且 status 为 Running, 则表示部署成功。 + +```shell +NAME READY STATUS RESTARTS AGE +oceanbase-controller-manager-86cfc8f7bf-4hfnj 2/2 Running 0 1m +``` diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/400.ob-operator-upgrade.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/400.ob-operator-upgrade.md new file mode 100644 index 000000000..1902423dd --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/400.ob-operator-upgrade.md @@ -0,0 +1,23 @@ +# ob-operator 升级 + +本文介绍 ob-operator 的升级方式。 + +## 使用 helm 升级 ob-operator Chart + +升级 ob-operator 的 chart 可以参考 [helm chart upgrade](https://atlassian.github.io/data-center-helm-charts/userguide/upgrades/HELM_CHART_UPGRADE/)。 + +## 通过配置文件升级 + +要通过配置文件升级,您只需要重新应用新版本的 ob-operator 的配置文件,等待 ob-operator 重启完成即完成升级。 + +- 稳定版本 + + ```shell + kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.0_release/deploy/operator.yaml + ``` + +- 开发版本 + + ```shell + kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/master/deploy/operator.yaml + ``` diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.configuration-of-ob-operator.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.configuration-of-ob-operator.md new file mode 100644 index 000000000..8490d0718 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.configuration-of-ob-operator.md @@ -0,0 +1,86 @@ +# 配置 ob-operator + +本文介绍 ob-operator 的启动参数和使用到的环境变量以及修改方法。用户可通过改变启动参数和环境变量影响 ob-operator 的行为。 + +## 启动参数 + +| 参数名 | 含义 | 默认值 | deploy 配置 | +| :----------------------- | :----------------------------------------------------------------- | :-------------- | :-------------- | +| namespace | 监听的命名空间,留空表示监听所有命名空间 | 空 | 空 | +| manager-namespace | ob-operator 运行的命名空间 | oceanbase-system | oceanbase-system | +| metrics-bind-address | ob-operator 提供 Prometheus 指标的服务端口 | :8080 | 127.0.0.1:8080 | +| health-probe-bind-address | ob-operator 进程健康探针绑定端口 | :8081 | :8081 | +| leader-elect | 启动 ob-operator 时是否采用选主流程 | false | true | +| log-verbosity | 日志输出量,为 0 输出关键信息,为 1 输出调试信息,为 2 输出溯源信息 | 0 | 0 | + +## 环境变量 + +| 环境变量名 | 含义 | deploy 配置 | +| :------------------- | :-------------------------------- | :------------------------------- | +| TELEMETRY_REPORT_HOST | 遥测采集数据收集端 | https://openwebapi.oceanbase.com | +| TELEMETRY_DEBUG | 设置为 true 可开启遥测采集调试模式 | 空 | +| DISABLE_WEBHOOKS | 设置为 true 可禁用 webhooks 校验 | 空 | +| DISABLE_TELEMETRY | 设置为 true 可禁用遥测采集模块,遥测采集模块会采集集群环境和事件信息脱敏后发送给 OceanBase,期望通过这些数据帮助改善 ob-operator | 空 | + +## 修改方法 + +使用 `deploy/operator.yaml` 中的配置文件,找到名为 `oceanbase-controller-manager` 的 `Deployment` 资源,在其容器列表中修改名为 `manager` 容器的启动参数和环境变量,下面截取 `deploy/operator.yaml` 中该部分为例。 + +```yaml + # 原本的配置 + containers: + - args: + - --health-probe-bind-address=:8081 + - --metrics-bind-address=:8080 + - --leader-elect + - --manager-namespace=oceanbase-system + - --log-verbosity=0 + command: + - /manager + env: + - name: TELEMETRY_REPORT_HOST + value: https://openwebapi.oceanbase.com +``` + +### 示例:增大日志输出量 + +如果用户希望增加 ob-operator 的日志输出量,可增大 `log-verbosity` 参数到 1 或者 2,值越大输出的日志越多。 + +```yaml + # 修改后的配置 + containers: + - args: + - --health-probe-bind-address=:8081 + - --metrics-bind-address=:8080 + - --leader-elect + - --manager-namespace=oceanbase-system + - --log-verbosity=2 # 日志输出量增大到 2 + command: + - /manager + env: + - name: TELEMETRY_REPORT_HOST + value: https://openwebapi.oceanbase.com +``` + +### 示例:指定资源命名空间 + +```yaml + # 修改后的配置 + containers: + - args: + - --health-probe-bind-address=:8081 + - --metrics-bind-address=:8080 + - --leader-elect + - --manager-namespace=oceanbase-system + - --log-verbosity=0 + - --namespace=oceanbase # 限定 ob-operator 只监听命名空间为 oceanbase 内的资源 + command: + - /manager + env: + - name: TELEMETRY_REPORT_HOST + value: https://openwebapi.oceanbase.com +``` + +### 应用到集群中 + +修改完成后通过 `kubectl apply -f deploy/operator.yaml` 将配置文件应用到集群中即可生效。环境变量的配置方法与启动参数相同,本文不再赘述。 diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/100.cluster-management-intro.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/100.cluster-management-intro.md new file mode 100644 index 000000000..d4b4f85cc --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/100.cluster-management-intro.md @@ -0,0 +1,19 @@ +# 集群管理 + +ob-operator 根据 OceanBase 集群的部署模式定义了以下资源: + +* `obclusters.oceanbase.oceanbase.com`,定义了 OceanBase 集群,您可以修改此资源定义和运维集群。 +* `obzones.oceanbase.oceanbase.com`,定义了某一个 obzone,用于 obzone 的维护,一般不需要用户来修改,由 ob-operator 自动维护。 +* `observers.oceanbase.oceanbase.com`,定义了某一个 observer,用于 observer 的维护,一般不需要用户来修改,由 ob-operator 自动维护。 +* `obparameters.oceanbase.oceanbase.com`,定义了 OceanBase 参数,用于参数的维护,一般不需要用户来修改,由 ob-operator 自动维护。 + +您可以通过创建或者修改自定义资源(CRD) `obparameters.oceanbase.oceanbase.com` 运维 OceanBase 集群,包括: + +* [创建集群](200.create-cluster.md) +* [增加 OBZone](./300.zone-management/100.add-zone.md) +* [减少 OBZone](./300.zone-management/200.delete-zone.md) +* [增加 OBServer](./400.server-management/100.add-server.md) +* [减少 OBServer](./400.server-management/200.delete-server.md) +* [升级集群](500.upgrade-cluster-of-ob-operator.md) +* [修改集群参数](600.parameter-management.md) +* [删除集群](700.delete-cluster.md) diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/200.create-cluster.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/200.create-cluster.md new file mode 100644 index 000000000..56dad5750 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/200.create-cluster.md @@ -0,0 +1,184 @@ +# 集群创建 + +本文介绍通过 ob-operator 创建 OceanBase 集群。 + +## 部署前准备 + +部署之前,您需要在 K8s 集群中部署好 ob-operator,请参考 [部署 ob-operator](../../300.deploy-ob-operator.md), 并确保 K8s 集群有可用的 storage-class,推荐使用 [local-path-provisioner](https://github.com/rancher/local-path-provisioner) + +## 部署 OceanBase 数据库 + +### 创建 Namespace + +创建部署 OceanBase 集群使用的 namespace。 + +```shell +kubectl create namespace oceanbase +``` + +### 创建默认用户的 Secret + +创建 OceanBase 集群之前,您需要先创建好若干 secret 来存储 OceanBase 中的特定用户 + +```shell +kubectl create secret -n oceanbase generic root-password --from-literal=password='root_password' +``` + +### 定义 OceanBase 集群 + +OceanBase 集群可以通过 yaml 配置文件进行定义,您可参考如下配置文件作为基础按照实际进行需求进行修改。 + +```yaml +apiVersion: oceanbase.oceanbase.com/v1alpha1 +kind: OBCluster +metadata: + name: test + namespace: oceanbase + annotations: + "oceanbase.oceanbase.com/independent-pvc-lifecycle": "true" + # "oceanbase.oceanbase.com/mode": "standalone" 或 "service" + # "oceanbase.oceanbase.com/single-pvc": "true" +spec: + clusterName: obcluster + clusterId: 1 + userSecrets: + root: root-password + topology: + - zone: zone1 + replica: 1 + # nodeSelector: + # k1: v1 + # affinity: + # nodeAffinity: + # podAffinity: + # podAntiAffinity: + # tolerations: + # - key: "obtopo" + # value: "zone" + # effect: "NoSchedule" + - zone: zone2 + replica: 1 + - zone: zone3 + replica: 1 + observer: + image: oceanbase/oceanbase-cloud-native:4.2.0.0-101000032023091319 + resource: + cpu: 2 + memory: 10Gi + storage: + dataStorage: + storageClass: local-path + size: 50Gi + redoLogStorage: + storageClass: local-path + size: 50Gi + logStorage: + storageClass: local-path + size: 20Gi + monitor: + image: oceanbase/obagent:4.2.0-100000062023080210 + resource: + cpu: 1 + memory: 1Gi + + # parameters: + # - name: system_memory + # value: 2G + # backupVolume: + # volume: + # name: backup + # nfs: + # server: 1.1.1.1 + # path: /opt/nfs + # readOnly: false + +``` + +#### 配置项 + +配置项说明如下: + +| 配置项 | 说明 | +| --- | --- | +| metadata.name | 集群名。K8s 中资源的名字;必填。 | +| metadata.namespace | 集群所在的命名空间;必填。 | +| spec.clusterName | OceanBase 集群名;必填。 | +| spec.clusterId | OceanBase 集群 ID;必填。 | +| spec.serviceAccount | 绑定到 OBServer Pod 上的 ServiceAccount;可选,默认为 `default`。 | +| spec.userSecrets | OceanBase 集群默认用户的 Secret;必填。 | +| spec.userSecrets.root | OceanBase 集群 root@sys 用户的 Secret 名称, Secret 中需要包含 password 字段;必填。 | +| spec.userSecrets.proxyro | OceanBase 集群 proxyro@sys 用户的 Secret 名称, Secret 中需要包含 password 字段;可选。 | +| spec.userSecrets.monitor | OceanBase 集群 monitor@sys 用户的 Secret 名称, Secret 中需要包含 password 字段;可选。 | +| spec.userSecrets.operator | OceanBase 集群 operator@sys 用户的 Secret 名称, Secret 中需要包含 password 字段;可选。 | +| spec.topology | OceanBase 集群部署 topo 的定义,包含对各个 zone 的定义;必填。 | +| spec.topology[i].zone | OceanBase Zone 的名字;必填。 | +| spec.topology[i].replica | OceanBase Zone 的 observer 数;必填。 | +| spec.topology[i].nodeSelector | 用于指定 OceanBase Zone 中的 observer 分布节点的选择,map 形式,需要配合节点的 label 使用;选填。 | +| spec.topology[i].affinity | 用于指定 OceanBase Zone 中的 observer 的节点亲和性, 节点亲和性可以参考 [K8s 文档](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity);选填。 | +| spec.topology[i].tolerations | 用于指定 OceanBase Zone 中的 observer 的容忍度,节点容忍度可以参考 [K8s 文档](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/); 选填。 | +| spec.observer.image | OceanBase 中的 observer 的镜像; 必填。 | +| spec.observer.resource | OceanBase 中的 observer 的资源配置; 必填。 | +| spec.observer.resource.cpu | OceanBase 中的 observer 的 cpu 资源配置; 必填。 | +| spec.observer.resource.memory | OceanBase 中的 observer 的 memory 资源配置; 必填。 | +| spec.observer.storage | OceanBase 中的 observer 的存储配置; 必填。 | +| spec.observer.storage.dataStorage | OceanBase 中的 observer 的数据存储配置; 必填。 | +| spec.observer.storage.redoLogStorage | OceanBase 中的 observer 的 clog 存储配置; 必填。 | +| spec.observer.storage.logStorage | OceanBase 中的 observer 的运行日志存储配置; 必填。 | +| spec.observer.storage.*.storageClass | 对于存储配置生效,用于定义创建 pvc 使用的 storageClass; 必填。 | +| spec.observer.storage.*.size | 对于存储配置生效,用于定义创建 pvc 的容量; 必填。 | +| spec.monitor | 监控配置, 建议开启,ob-operator 会使用 obagent 来做监控数据采集,通过对接 prometheus 可以实现对 OceanBase 的状态监控; 选填。 | +| spec.monitor.image | 监控所使用的镜像; 必填。 | +| spec.monitor.resource | 监控容器使用的资源; 必填。 | +| spec.monitor.resource.cpu | 监控容器使用的 cpu 资源; 必填。 | +| spec.monitor.resource.memory | 监控容器使用的 memory 资源; 必填。 | +| spec.parameters | OceanBase 的自定义参数配置,对于集群全局生效; 选填。 | +| spec.parameters[i].name | 参数名; 必填。 | +| spec.parameters[i].value | 参数值; 必填。 | +| spec.backupVolume | OceanBase 备份使用的存储,如需开启备份功能,并且不是使用 OSS 进行备份的话,需要配置,一般配置 NFS Volume; 选填。 | + +#### 注解 + +下面的表格展示了可选的注解,为书写简单,注解 `annotations` 表示其前面有个 `oceanbase.oceanbase.com/` 的前缀。 + +| 注解 | 说明 | +| -- | -- | +| `independent-pvc-lifecycle` | `true`: 可在删除集群后保留 PVC | +| `mode` | `standalone`: 使用 127.0.0.1 初始化单节点集群,无法与其他节点通信
`service`: 为每个 OBServer 创建单独的 K8s Service,用 Service 的 `ClusterIP` 作为 OBServer 的通讯 IP | +| `single-pvc` | `true`: 为每个 OBServer 的 Pod 创建并绑定一个整体的 PVC(默认创建三个) | + + +### 创建集群 + +配置文件保存好之后,使用如下命令在 K8s 中创建集群: + +```shell +kubectl apply -f obcluster.yaml +``` + +一般创建集群需要 2 分钟左右,执行以下命令,查询集群状态,当集群状态变成 `running` 之后表示集群创建成功。 + +```shell +kubectl get obclusters.oceanbase.oceanbase.com test -n oceanbase + +# desired output +NAME STATUS AGE +test running 6m2s +``` + +## 连接集群 + +通过以下命令查找 observer 的 POD IP, POD 名的规则为 `{cluster_name}-{cluster_id}-{zone}-uuid`。 + +```shell +kubectl get pods -n oceanbase -o wide +``` + +通过以下命令连接: + +```shell +mysql -h{POD_IP} -P2881 -uroot -proot_password oceanbase -A -c +``` + +## 后续操作 + +集群创建成功后,还需要创建租户才可以给业务使用,请参考[租户管理](../200.tenant-management-of-ob-operator/000.tenant-management-intro.md)。 diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/300.zone-management/100.add-zone.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/300.zone-management/100.add-zone.md new file mode 100644 index 000000000..48408d3d4 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/300.zone-management/100.add-zone.md @@ -0,0 +1,71 @@ +# 在集群中增加 Zone + +本节介绍如何在集群中增加 Zone。 + +## 前提条件 + +在为集群增加 Zone 之前,您需要确保: + +* 服务器要有足够的资源,能够支持新增 Zone 所需资源。 +* OceanBase 集群目前处于 running 状态。 + +## 操作步骤 + +假设当前集群中共包含 3 个可用区 zone1、zone2 和 zone3,每个 Zone 内包含 1 个 OBServer 节点。现在希望将 3 个可用区扩容成为 5 个可用区。 + +1. 修改配置文件 `obcluster.yaml`,完整配置文件请参考 [创建 OceanBase 集群](../200.create-cluster.md),在 spec.topology 内增加 zone4 和 zone5。 + + ```yaml + # 示例: OB 集群中有 3 个 zone + topology: + - zone: zone1 + replica: 1 + - zone: zone2 + replica: 1 + - zone: zone3 + replica: 1 + + # 在集群中增加 zone(zone4, zone5) + topology: + - zone: zone1 + replica: 1 + - zone: zone2 + replica: 1 + - zone: zone3 + replica: 1 + - zone: zone4 + replica: 1 + - zone: zone5 + replica: 1 + ``` + +2. 配置文件修改后,需运行如下命令使改动生效。 + + ```yaml + kubectl apply -f obcluster.yaml + ``` + +3. 观察 OceanBase 集群 CR 的状态,等待操作成功。 + +您可以通过以下命令,获取 OceanBase 集群资源的状态。当集群状态和 5 个 zone 的状态均为 running 时,则扩容成功。 + +```shell +kubectl get obclusters.oceanbase.oceanbase.com test -n oceanbase -o yaml + +# desired output, only displays status here +status: + image: oceanbase/oceanbase-cloud-native:4.2.0.0-101000032023091319 + obzones: + - status: running + zone: obcluster-1-zone1 + - status: running + zone: obcluster-1-zone2 + - status: running + zone: obcluster-1-zone3 + - status: running + zone: obcluster-1-zone4 + - status: running + zone: obcluster-1-zone5 + parameters: [] + status: running +``` diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/300.zone-management/200.delete-zone.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/300.zone-management/200.delete-zone.md new file mode 100644 index 000000000..5c510b2e9 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/300.zone-management/200.delete-zone.md @@ -0,0 +1,68 @@ +# 在集群中减少 Zone + +本节主要介绍如何在集群中减少 Zone。 + +## 前提条件 + +在为集群减少 Zone 之前,您需要确保: + +* OceanBase 集群目前处于 running 状态。 +* 减少 zone 后仍需要满足多数派。 + +## 操作步骤 + +假设当前集群中共包含 5 个可用区 zone1、zone2、zone3、zone4 和 zone5。每个 Zone 内包含 1 个 OBServer 节点。现在希望将 5 个可用区减少为 3 个可用区。 + +1. 修改配置文件 `obcluster.yaml`。完整配置文件请参考 [创建 OceanBase 集群](../200.create-cluster.md),在 spec.topology 内减少 zone4 和 zone5。 + + ```yaml + # 示例: OB 集群中有 5 个 zone + topology: + - zone: zone1 + replica: 1 + - zone: zone2 + replica: 1 + - zone: zone3 + replica: 1 + - zone: zone4 + replica: 1 + - zone: zone5 + replica: 1 + + # 在集群中减小 zone(zone4, zone5), 仅剩 3 个 zone + topology: + - zone: zone1 + replica: 1 + - zone: zone2 + replica: 1 + - zone: zone3 + replica: 1 + + ``` + +2. 配置文件修改后,需运行如下命令使改动生效。 + + ```yaml + kubectl apply -f obcluster.yaml + ``` + +3. 观察 OceanBase 集群 CR 的状态等待操作成功。 + +通过以下命令,可以获取 OceanBase 集群资源的状态,当集群状态和 3 个 zone 的状态均为 running 时,则操作成功。 + +```shell +kubectl get obclusters.oceanbase.oceanbase.com test -n oceanbase -o yaml + +# desired output, only displays status here +status: + image: oceanbase/oceanbase-cloud-native:4.2.0.0-101000032023091319 + obzones: + - status: running + zone: obcluster-1-zone1 + - status: running + zone: obcluster-1-zone2 + - status: running + zone: obcluster-1-zone3 + parameters: [] + status: running +``` diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/400.server-management/100.add-server.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/400.server-management/100.add-server.md new file mode 100644 index 000000000..8bfce5a8c --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/400.server-management/100.add-server.md @@ -0,0 +1,77 @@ +# 向 Zone 内添加 OBServer 节点 + +本节主要介绍如何通过向 Zone 内添加 OBServer 节点的方式进行集群的扩容。 + +## 前提条件 + +在向 Zone 内添加 OBServer 节点,您需要确保: + +* 服务器要有足够的资源,能够支持添加 OBServer 节点所需资源。 +* OceanBase 集群目前处于 running 状态。 + +## 操作步骤 + +假设当前集群中共包含 3 个可用区 zone1、zone2、zone3,每个 Zone 内包含 1 个 OBServer 节点。现在希望向每个 Zone 添加 1 台 OBServer 节点来扩容。扩容后,3 个 Zone 内均包含 2 台 OBServer 节点。按照以下步骤添加 OBServer 节点: + +1. 修改配置文件 `obcluster.yaml`,每个 zone 对应的 replicas 由 1 修改为 2。 + + ```yaml + # 示例: OB 集群中有 3 个 zone + topology: + - zone: zone1 + replica: 1 + - zone: zone2 + replica: 1 + - zone: zone3 + replica: 1 + + # 向每个 zone 内添加 1 个 observer + topology: + - zone: zone1 + replica: 2 + - zone: zone2 + replica: 2 + - zone: zone3 + replica: 2 + ``` + +2. 配置文件修改后,需运行如下命令使改动生效。 + + ```shell + kubectl apply -f obcluster.yaml + ``` + +3. 观察 CR 的状态等待操作成功。 + +通过以下命令,可以获取 OceanBase 集群资源的状态。 + +```shell +kubectl get obclusters.oceanbase.oceanbase.com test -n oceanbase -o yaml + +# obcluster desired output, only displays status here +status: + image: oceanbase/oceanbase-cloud-native:4.2.0.0-101000032023091319 + obzones: + - status: running + zone: obcluster-1-zone1 + - status: running + zone: obcluster-1-zone2 + - status: running + zone: obcluster-1-zone3 + parameters: [] + status: running +``` + +通过以下命令,可以获取 observer 的状态, 可以观察 observer 数量匹配,并且都是 running 状态。 + +```shell +kubectl get observers.oceanbase.oceanbase.com -n oceanbase + +# observer desired output, only displays status here +oceanbase obcluster-1-zone1-7b0e9f7e7675 10.42.0.241 running 7h48m +oceanbase obcluster-1-zone2-67f3d1fe0b40 10.42.0.251 running 28m +oceanbase obcluster-1-zone3-914ef208ac46 10.42.0.252 running 28m +oceanbase obcluster-1-zone2-2336549ba883 10.42.0.19 running 3m15s +oceanbase obcluster-1-zone3-d7011a909e2b 10.42.0.26 running 3m10s +oceanbase obcluster-1-zone1-0f5d712adb19 10.42.0.27 running 3m10s +``` diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/400.server-management/200.delete-server.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/400.server-management/200.delete-server.md new file mode 100644 index 000000000..5f5bfdd8c --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/400.server-management/200.delete-server.md @@ -0,0 +1,71 @@ +# 从 Zone 中减少 OBServer 节点 + +本节主要介绍如何通过从 Zone 内减少 OBServer 节点的方式进行集群的缩容。 + +## 前提条件 + +* OceanBase 集群目前处于 running 状态。 +* observer 删除之后仍有足够的资源负载租户的 unit。 + +## 操作步骤 + +假设当前集群中共包含 3 个可用区 zone1、zone2 和 zone3,每个 Zone 内包含 2 个 OBServer 节点。现在希望从每个 Zone 减少 1 台 OBServer 节点来缩容,缩容后,3 个 Zone 内均包含 1 台 OBServer 节点。 + +1. 修改配置文件 `obcluster.yaml`,每个 zone 对应的 replicas 由 2 修改为 1。 + + ```yaml + # 示例: OB 集群中有 3 个 zone + topology: + - zone: zone1 + replica: 2 + - zone: zone2 + replica: 2 + - zone: zone3 + replica: 2 + + # 从每个 zone 内减少 1 个 observer + topology: + - zone: zone1 + replica: 1 + - zone: zone2 + replica: 1 + - zone: zone3 + replica: 1 + ``` + +2. 配置文件修改后,需运行如下命令使改动生效。 + + ```yaml + kubectl apply -f obcluster.yaml + ``` + +3. 观察 CR 的状态等待操作成功。 +通过以下命令,可以获取 OceanBase 集群资源的状态 + +```shell +kubectl get obclusters.oceanbase.oceanbase.com test -n oceanbase -o yaml + +# obcluster desired output, only displays status here +status: + image: oceanbase/oceanbase-cloud-native:4.2.0.0-101000032023091319 + obzones: + - status: running + zone: obcluster-1-zone1 + - status: running + zone: obcluster-1-zone2 + - status: running + zone: obcluster-1-zone3 + parameters: [] + status: running +``` + +通过以下命令,可以获取 observer 的状态, 可以观察 observer 数量匹配,并且都是 running 状态 + +``` +kubectl get observers.oceanbase.oceanbase.com -n oceanbase + +# observer desired output, only displays status here +oceanbase obcluster-1-zone1-7b0e9f7e7675 10.42.0.241 running 7h48m +oceanbase obcluster-1-zone2-67f3d1fe0b40 10.42.0.251 running 28m +oceanbase obcluster-1-zone3-914ef208ac46 10.42.0.252 running 28m +``` diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/500.upgrade-cluster-of-ob-operator.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/500.upgrade-cluster-of-ob-operator.md new file mode 100644 index 000000000..a6cc25459 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/500.upgrade-cluster-of-ob-operator.md @@ -0,0 +1,51 @@ +# 集群升级 + +本文介绍升级使用 ob-operator 部署的 OceanBase 集群。 + +## 前提条件 + +在集群升级前,您要确保待升级的集群是 running 状态。 + +## 操作步骤 + +### 修改 spec 中的 tag 配置 + +1. 修改 obcluster 的配置文件。完整配置文件请参考 [创建 OceanBase 集群](200.create-cluster.md)。 将 `spec.observer.image` 修改为目标镜像。 + + ```yaml + # 修改前 + spec: + observer: + image: oceanbase/oceanbase-cloud-native:4.2.0.0-101000032023091319 + + # 修改后 + spec: + observer: + image: oceanbase/oceanbase-cloud-native:4.2.1.1-101000062023110109 + ``` + +2. 配置文件修改后,需运行如下命令使改动生效。 + + ```yaml + kubectl apply -f obcluster.yaml + ``` + +3. 观察 OceanBase 集群 CR 的状态等待操作成功。 +通过以下命令,可以获取 OceanBase 集群资源的状态,当集群状态变为 running,image 变为目标镜像时,则升级成功。 + +```shell +kubectl get obclusters.oceanbase.oceanbase.com test -n oceanbase -o yaml + +# desired output, only displays status here +status: + image: oceanbase/oceanbase-cloud-native:4.2.1.1-101000062023110109 + obzones: + - status: running + zone: obcluster-1-zone1 + - status: running + zone: obcluster-1-zone2 + - status: running + zone: obcluster-1-zone3 + parameters: [] + status: running +``` diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/600.parameter-management.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/600.parameter-management.md new file mode 100644 index 000000000..beb419715 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/600.parameter-management.md @@ -0,0 +1,47 @@ +# 参数管理 + +本文介绍升级使用 ob-operator 更改 OceanBase 集群参数。 + +## 前提条件 + +确保您的 OceanBase 集群是 running 状态。 + +## 升级步骤 + +### 修改 spec 中的 tag 配置 + +1. 修改 obcluster 的配置文件。完整配置文件请参考 [创建 OceanBase 集群](200.create-cluster.md),将需要修改的参数写在 spec.parameters 中。 + + ```yaml + # 修改前 + # parameters: + # - name: system_memory + # value: 2G + + # 修改后 + parameters: + - name: system_memory + value: 2G + ``` + +2. 配置文件修改后,需运行如下命令使改动生效。 + + ```yaml + kubectl apply -f obcluster.yaml + ``` + +3. 观察 obparameter CR 的状态等待操作成功。 +通过以下命令进行查看。 + + ```shell + kubectl get obclusters.oceanbase.oceanbase.com test -n oceanbase -o yaml + + # desired output, only displays status and one result here + status: + parameter: + - name: system_memory + server: 10.42.0.232:2882 + value: 2G + zone: zone1 + status: matched + ``` diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/650.update-resources.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/650.update-resources.md new file mode 100644 index 000000000..2a60015f6 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/650.update-resources.md @@ -0,0 +1,103 @@ +# 修改集群资源配置 + +集群创建完成并处在运行状态后,有时我们仍然需要调节 OBServer 节点的资源配置,例如 CPU、内存、存储卷等。在此篇文章中介绍了可以进行修改的资源配置以及具体操作,可参考使用。 + +## 垂直拓展:修改 CPU 和内存资源 + +
+

注意

+

仅有 standalone 模式的集群支持本操作

+
+ +假设我们目前已经创建了一个单节点 Standalone 集群,节点资源规格为 2C+10G,该配置在 YAML 配置中应该如下片段所示。 + +```yaml + observer: + # ... + resource: + cpu: 2 + memory: 10Gi + # ... +``` + +若运行一段时间发现资源不足需要扩充,可以直接修改这部分配置,如下面 YAML 片段中我们将 OBServer 的资源规格扩充到了 4C+16G。 + +```yaml + observer: + # ... + resource: + cpu: 4 + memory: 16Gi + # ... +``` + +修改完成之后将新的 YAML(文件名 obcluster.yaml 为示例,以实际为准)应用到 K8s 集群中,ob-operator 会执行该集群的垂直拓展流程,待 OBCluster 从垂直扩展状态恢复到 `running` 状态后,表示垂直拓展完成。 + +```shell +kubectl apply -f obcluster.yaml +kubectl get obcluster -w + +NAME STATUS AGE +test scale up obzone xxx +test scale up obzone xxx +... +test running xxx +``` + +## 动态扩容 PVC + +
+

注意

+

该操作要求集群存储使用的存储类支持 AllowVolumeExpansion 特性

+
+ +假设我们目前已经部署了一个 OB 集群,其存储配置如下 YAML 片段所示: + +```yaml + observer: + # ... + storage: + dataStorage: + storageClass: my-storage-class + size: 50Gi + redoLogStorage: + storageClass: my-storage-class + size: 50Gi + logStorage: + storageClass: my-storage-class + size: 20Gi + # ... +``` + +如果现在我们希望将挂载的存储卷进行一定的扩容,可直接修改这个片段当中的 `size` 数值,并且通过 kubectl 应用到 K8s 集群当中,ob-operator 会执行该集群的 PVC 扩容流程。需要注意的是 PVC 只能扩容不能缩容,所以 `size` 只能增大不能减小。 + +修改后如下面片段所示: + +```yaml + observer: + # ... + storage: + dataStorage: + storageClass: my-storage-class + size: 60Gi + redoLogStorage: + storageClass: my-storage-class + size: 60Gi + logStorage: + storageClass: my-storage-class + size: 30Gi + # ... +``` + +执行 kubectl apply 将新的配置应用到集群中,再监听集群的状态变化,预期效果是 PVC 扩容完成后集群状态恢复到 `running` 状态。 + +```shell +kubectl apply -f obcluster.yaml +kubectl get obcluster -w + +NAME STATUS AGE +test expand pvc xxx +test expand pvc xxx +... +test running xxx +``` \ No newline at end of file diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/700.delete-cluster.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/700.delete-cluster.md new file mode 100644 index 000000000..3752027b2 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/100.cluster-management-of-ob-operator/700.delete-cluster.md @@ -0,0 +1,43 @@ +# 删除集群 + +本文介绍删除使用 ob-operator 部署的 OceanBase 集群。 + +## 操作步骤 + +1. 删除特定 OceanBase 集群,命令如下。 + + ```shell + kubectl delete obclusters.oceanbase.oceanbase.com test -n oceanbase + ``` + +2. 查看集群及相关资源被删除。 + +* 查看 obcluster 资源被成功删除, 通过以下命令查询不出资源。 + + ```shell + kubectl get obclusters.oceanbase.oceanbase.com -n oceanbase + ``` + +* 查看 obzone 资源被成功删除, 通过以下命令查询不出资源。 + + ```shell + kubectl get obzones.oceanbase.oceanbase.com -n oceanbase + ``` + +* 查看 observer 被成功删除,通过以下命令查询不出资源。 + + ```shell + kubectl get observers.oceanbase.oceanbase.com -n oceanbase + ``` + +* 查看 pod 被成功删除。 + + ```shell + kubectl get pods -n oceanbase + ``` + +* 查看 pvc 被成功删除。 + + ```shell + kubectl get pvc -n oceanbase + ``` diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/000.tenant-management-intro.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/000.tenant-management-intro.md new file mode 100644 index 000000000..7999bb222 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/000.tenant-management-intro.md @@ -0,0 +1,13 @@ +# 租户管理 + +ob-operator 根据 OceanBase 租户定义了以下资源: +* `obtenants.oceanbase.oceanbase.com`, 定义了 OceanBase 租户, 您可以通过创建或者修改此资源实现对租户的运维。 +* `obtenantoperations.oceanbase.oceanbase.com`, 定义了 OceanBase 租户的一些运维操作,目前支持`修改密码`, `switch over`,`fail over`。 + +您可以通过创建或修改自定义资源(CRD) 来进行租户的运维, 包括: +* [租户创建](100.create-tenant.md) +* [租户资源变更](./200.modify-tenant-of-ob-operator/100.resource-management-of-ob-operator.md) +* [租户副本变更](./200.modify-tenant-of-ob-operator/200.replica-management-of-ob-operator.md) +* [租户配置变更](./200.modify-tenant-of-ob-operator/300.other-configuration-item-modifications-of-ob-operator.md) +* [租户删除](300.delete-tenant-of-ob-operator.md) +* [租户其他运维操作](400.tenant-operation.md) diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/100.create-tenant.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/100.create-tenant.md new file mode 100644 index 000000000..c7c5e9791 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/100.create-tenant.md @@ -0,0 +1,288 @@ +# 创建租户 + +本文介绍通过 ob-operator 创建租户。 + +## 前提条件 + +创建租户前,您需要确保: + +* ob-operator v2.1.0 及以上。 + +* OceanBase 集群部署完成且正常运行。 + +## 使用配置文件创建租户 + +通过应用租户配置文件创建租户。配置文件内容可参考 [GitHub](https://github.com/oceanbase/ob-operator/blob/2.1.0_release/deploy/tenant.yaml) 。 + +创建租户的命令如下,该命令会在当前 Kubernetes 集群中创建一个 OBTenant 租户的资源。 + +```shell +kubectl apply -f tenant.yaml +``` + +## 创建租户示例 + +创建名为 t1 的一个 3 副本的 MySQL 租户,并指定允许任何客户端 IP 连接该租户。 + +创建租户时,ob-operator 会根据配置文件 `tenant.yaml` 中的 pools 按照 zone 来创建对应的 resource unit 和 resource pool。根据 resource 下的配置项来创建 resource unit 并以此作为资源规格来创建 resource pool。 + +```yaml +apiVersion: oceanbase.oceanbase.com/v1alpha1 +kind: OBTenant +metadata: + name: t1 + namespace: oceanbase +spec: + obcluster: obcluster + tenantName: t1 + unitNum: 1 + charset: utf8mb4 + connectWhiteList: '%' + forceDelete: true + credentials: # 可选 + root: t1-ro # 可选,如不传则 root 用户密码为空 + standbyRo: t1-ro # 可选,如不传则自动创建 + pools: + - zone: zone1 + type: + name: Full + replica: 1 + isActive: true + resource: + maxCPU: 1 + minCPU: 1 + memorySize: 5Gi + maxIops: 1024 + minIops: 1024 + iopsWeight: 2 + logDiskSize: 12Gi + - zone: zone2 + type: + name: Full + replica: 1 + isActive: true + resource: + maxCPU: 1 + minCPU: 1 + memorySize: 5Gi + maxIops: 1024 + minIops: 1024 + iopsWeight: 2 + logDiskSize: 12Gi + - zone: zone3 + type: + name: Full + replica: 1 + isActive: true + priority: 3 + resource: + maxCPU: 1 + minCPU: 1 + memorySize: 5Gi + maxIops: 1024 + minIops: 1024 + iopsWeight: 2 + logDiskSize: 12Gi +``` + +配置项说明如下: + +| 配置项 | 说明 | +| --- | --- | +| metadata.name | 租户资源的名称,在 K8s 的同一个命名空间下唯一;必填。 | +| metadata.namespace | 指定租户资源所在的命名空间;必填。 | +| obcluster | 指定需要创建租户的 OceanBase 数据库集群名;必填。 | +| tenantName | 租户名。租户名的合法性和变量名一致,最长 128 个字符,字符只能是大小写英文字母、数字和下划线,而且必须以字母或下划线开头,并且不能是 OceanBase 数据库的关键字。 OceanBase 数据库中所支持的关键字请参见 MySQL 模式的 [预留关键字](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000218216)和 Oracle 模式的[预留关键字](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000218217);必填。 | +| unitNum | 指定要创建的单个 ZONE 下的单元个数,取值要小于单个 ZONE 中的 OBServer 节点个数;必填。| +| charset | 指定租户的字符集,字符集相关的介绍信息请参见[字符集](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000221234);非必填,默认设置为 `utf8mb4`。 | +| collate | 指定租户的字符序,字符序相关的介绍信息请参见[字符序](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000222182);非必填。 | +| connectWhiteList | 指定允许连接该租户的客户端 IP,`%` 表示任何客户端 IP 都可以连接该租户;非必填,默认设置为 `%`。如果用户需要修改改配置,则需要将 ob-operator 所处的网段包含在配置内,否则 ob-operator 会连接不上该租户。 | +| forceDelete | 删除时是否强制删除,非必填,默认为 false。 | +| credentials | 创建租户时创建用户和修改密码的 Secret 资源引用。目前支持配置 root 账号和 standbyRo 两个用户的密码,非必填,不填则不修改密码。 | +| pools | 租户的拓扑结构,用于定义租户在每个 zone 上的副本、资源分布等情况。 | +| type.name | 指定租户在该 zone 的副本类型,支持 full 和 readonly, 需要写出完整类型, 大小写不敏感;必填。| +| type.replica | 指定租户在该 zone 的副本数;非必填,默认为 1。 | +| type.isActive | 是否启用 zone。 | +| priority | 指定当前 zone 的优先级,数字越大优先级越高;非必填,默认为 0。 | +| resource | 指定租户在该 zone 的资源情况。 | +| maxCPU | 指定租户在该 zone 上 使用的资源单元提供的 CPU 的上限;必填,最小值为 1。 | +| minCPU | 指定租户在该 zone 上 使用的资源单元提供的 CPU 的下限;非必填,默认等于 maxCPU。 | +| memorySize | 指定租户在该 zone 上 使用的资源单元提供的 Memory 的大小;必填,最小值为 1Gi;注意集群的 __min_full_resource_pool_memory 配置项的值 | +| maxIops | 指定租户在该 zone 上 使用的资源单元提供的 Iops 的上限;非必填。| +| minIops | 指定租户在该 zone 上 使用的资源单元提供的 Iops 的下限;非必填。| +| iopsWeight | 指定租户在该 zone 上 使用的资源单元提供的 Iops 权重。非必填,默认等于 1。 | +| logDiskSize | 指定租户在该 zone 上 使用的资源单元提供的日志盘规格。非必填,默认等于 3 倍的内存规格,最小值为 2Gi。 | + +## 确认租户是否创建成功 + +创建租户后,执行以下语句,查看当前 Kubernetes 集群中是否有新创建的租户的 OBTenant 资源,并且该 OBTenant 资源的 `Status.status` 为 `running`,相关配置都会在 Status 中展示。 + +```shell +kubectl describe obtenants.oceanbase.oceanbase.com -n oceanbase t1 +``` + +返回的示例结果如下: + +```shell +Name: t1 +Namespace: oceanbase +Labels: +Annotations: +API Version: oceanbase.oceanbase.com/v1alpha1 +Kind: OBTenant +Metadata: + Creation Timestamp: 2023-11-13T07:28:31Z + Finalizers: + finalizers.oceanbase.com.deleteobtenant + Generation: 2 + Resource Version: 940236 + UID: 34036a49-26bf-47cf-8201-444b3850aaa2 +Spec: + Charset: utf8mb4 + Connect White List: % + Credentials: + Root: t1-ro + Standby Ro: t1-ro + Force Delete: true + Obcluster: obcluster + Pools: + Priority: 1 + Resource: + Iops Weight: 2 + Log Disk Size: 12Gi + Max CPU: 1 + Max Iops: 1024 + Memory Size: 5Gi + Min CPU: 1 + Min Iops: 1024 + Type: + Is Active: true + Name: Full + Replica: 1 + Zone: zone1 + Priority: 1 + Resource: + Iops Weight: 2 + Log Disk Size: 12Gi + Max CPU: 1 + Max Iops: 1024 + Memory Size: 5Gi + Min CPU: 1 + Min Iops: 1024 + Type: + Is Active: true + Name: Full + Replica: 1 + Zone: zone2 + Priority: 3 + Resource: + Iops Weight: 2 + Log Disk Size: 12Gi + Max CPU: 1 + Max Iops: 1024 + Memory Size: 5Gi + Min CPU: 1 + Min Iops: 1024 + Type: + Is Active: true + Name: Full + Replica: 1 + Zone: zone3 + Tenant Name: t1 + Tenant Role: PRIMARY + Unit Num: 1 +Status: + Credentials: + Root: t1-ro + Standby Ro: t1-ro + Resource Pool: + Priority: 1 + Type: + Is Active: true + Name: FULL + Replica: 1 + Unit Config: + Iops Weight: 2 + Log Disk Size: 12884901888 + Max CPU: 1 + Max Iops: 1024 + Memory Size: 5368709120 + Min CPU: 1 + Min Iops: 1024 + Unit Num: 1 + Units: + Migrate: + Server IP: + Server Port: 0 + Server IP: 10.42.0.189 + Server Port: 2882 + Status: ACTIVE + Unit Id: 1006 + Zone List: zone1 + Priority: 1 + Type: + Is Active: true + Name: FULL + Replica: 1 + Unit Config: + Iops Weight: 2 + Log Disk Size: 12884901888 + Max CPU: 1 + Max Iops: 1024 + Memory Size: 5368709120 + Min CPU: 1 + Min Iops: 1024 + Unit Num: 1 + Units: + Migrate: + Server IP: + Server Port: 0 + Server IP: 10.42.1.118 + Server Port: 2882 + Status: ACTIVE + Unit Id: 1007 + Zone List: zone2 + Priority: 2 + Type: + Is Active: true + Name: FULL + Replica: 1 + Unit Config: + Iops Weight: 2 + Log Disk Size: 12884901888 + Max CPU: 1 + Max Iops: 1024 + Memory Size: 5368709120 + Min CPU: 1 + Min Iops: 1024 + Unit Num: 1 + Units: + Migrate: + Server IP: + Server Port: 0 + Server IP: 10.42.0.190 + Server Port: 2882 + Status: ACTIVE + Unit Id: 1008 + Zone List: zone3 + Status: running + Tenant Record Info: + Charset: utf8mb4 + Connect White List: % + Locality: FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 + Pool List: pool_t1_zone1,pool_t1_zone2,pool_t1_zone3 + Primary Zone: zone3;zone1,zone2 + Tenant ID: 1006 + Unit Num: 1 + Zone List: zone1,zone2,zone3 + Tenant Role: PRIMARY +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal 2m58s obtenant-controller start creating + Normal 115s obtenant-controller create OBTenant successfully +``` + +## 后续操作 + +租户创建成功后,其管理员账号密码为 `spec.credentials.root` 字段指定的 secret 中包含的内容,若创建时没有指定,则密码为空。您可以使用 `obclient -h${podIP} -P2881 -uroot@tenantname -p -A` 或者 `mysql -h${podIP} -P2881 -uroot@tenantname -p -A` 语句登录数据库。 diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/100.resource-management-of-ob-operator.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/100.resource-management-of-ob-operator.md new file mode 100644 index 000000000..55a7c9a0e --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/100.resource-management-of-ob-operator.md @@ -0,0 +1,135 @@ +# 资源管理 + +本文主要介绍通过 ob-operator 进行租户内的资源内容修改。 + +租户资源内容分为租户资源规格和租户资源池,修改租户资源规格和资源池,可以实现对租户的扩缩容。 + +## 修改资源规格 + +修改资源规格即是调大或调小资源单元配置中的 CPU、内存t和日志盘容量。 + +修改资源规格的注意事项,参考 [修改资源规格配置](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000218787) 内的注意事项。 + +### 操作步骤 + +修改资源规格时,通过应用租户配置文件 tenant.yaml 中 resource 下的配置项从而修改在该 zone 下的 resource unit 的规格。具体如下: + +1. 修改租户配置文件 tenant.yaml。 + + ```yaml + #示例:修改前 maxCPU 为 1 + resource: + maxCPU: 1 + memorySize: 1Gi + + #修改后,maxCPU 由 1 变为 2 + resource: + maxCPU: 2 #1 -> 2 + memorySize: 1Gi + ``` + +2. 配置文件修改后,运行如下命令使改动生效。 + + ```shell + kubectl apply -f tenant.yaml + ``` + +3. 执行以下语句,查看当前 Kubernetes 集群中租户的 OBTenant 资源,来判断是否修改成功。 + + ```shell + kubectl get obtenants.oceanbase.oceanbase.com -n oceanbase -o yaml + ``` + +当看到租户的 OBTenant 资源中 `status.pools.resource` 对应的值变为修改后的值,则说明修改成功。 + +```yaml + status: + ...... + resourcePool: + - priority: 1 + type: + isActive: true + name: FULL + replica: 1 + unitConfig: + iopsWeight: 2 + logDiskSize: "12884901888" + maxCPU: "2" # maxCPU 已修改为 2 + maxIops: 1024 + memorySize: "5368709120" + minCPU: "1" + minIops: 1024 + unitNum: 1 + units: + - migrate: + serverIP: "" + serverPort: 0 + serverIP: xxx.xxx.xxx.xxx + serverPort: 2882 + status: ACTIVE + unitId: 1006 + zoneList: zone1 +``` + +## 修改资源池 unit num + +在增加资源池 unit num 前需要保证对应的 Zone 内有足够的 OBServer 节点,如何在 zone 内添加 OBServer 节点可参考 [向 Zone 内添加 OBServer 节点](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000221562)。 + +### 操作步骤 + +修改资源池 unit num 时,通过应用租户配置文件 tenant.yaml 中 pools 下每个 Zone 对应的 unitNum。具体如下: + +1. 修改配置文件 `tenant.yaml`。 + + ```yaml + #示例:将租户在每个 zone 上的资源单元个数为调整 2 个 + spec: + unitNum: 1 + + #调整后 UnitNum 为 2 + spec: + unitNum: 2 + ``` + +2. 配置文件修改后,运行如下命令使改动生效。 + + ```shell + kubectl apply -f tenant.yaml + ``` + +3. 执行以下语句,查看当前 Kubernetes 集群中租户的 OBTenant 资源,来判断是否修改成功。 + + ```shell + kubectl get obtenants.oceanbase.oceanbase.com -n oceanbase -o yaml + ``` + +当看到租户的 OBTenant 资源中 `status.resourcePool.unitNum` 对应的值变为修改后的值,则说明修改成功。 + +```yaml + status: + ...... + resourcePool: + - priority: 1 + type: + isActive: true + name: FULL + replica: 1 + unitConfig: + iopsWeight: 2 + logDiskSize: "12884901888" + maxCPU: "1" + maxIops: 1024 + memorySize: "5368709120" + minCPU: "1" + minIops: 1024 + unitNum: 2 # unitNum 已修改为 2 + units: + - migrate: + serverIP: "" + serverPort: 0 + serverIP: 10.42.0.189 + serverPort: 2882 + status: ACTIVE + unitId: 1006 + zoneList: zone1 +``` diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/200.replica-management-of-ob-operator.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/200.replica-management-of-ob-operator.md new file mode 100644 index 000000000..f70602398 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/200.replica-management-of-ob-operator.md @@ -0,0 +1,277 @@ +# 副本管理 + +本文主要介绍通过 ob-operator 进行租户的副本管理。 + +## 修改租户 Primary Zone + +修改租户的 Primary Zone,可以修改 priority 配置项用于指定 zone 的优先级,数字越大优先级越高。最小值为 1。 + +Primary Zone 描述了 Leader 副本的偏好位置,而 Leader 副本承载了业务的强一致读写流量,即 Primary Zone 决定了 OceanBase 数据库的流量分布。通过修改 Primary Zone 属性可以切换业务流量,或者是从一个机房切换到另一个机房,或者是从一个城市切换到另一个城市,适用于容灾场景、扩缩容等场景。 + +### 操作步骤 + +1. 修改租户配置文件 `tenant.yaml`,调整每个 Zone 的 priority 值。 + + ```yaml + - zone: zone1 + priority: 1 + - zone: zone2 + priority: 1 + - zone: zone3 + priority: 3 + + # 修改后 + - zone: zone1 + priority: 3 + - zone: zone2 + priority: 2 + - zone: zone3 + priority: 1 + ``` + + 例如上述配置,租户原本的 Primary Zone 为 `zone3;zone1,zone2`,修改优先级后租户的 Primary Zone 为 `zone1;zone2;zone3`. + +2. 配置文件修改后,运行如下命令使改动生效。 + + ```shell + kubectl apply -f tenant.yaml + ``` + +3. 执行以下语句,查看当前 Kubernetes 集群中租户的 OBTenant 资源,来判断是否修改成功。 + + ```shell + kubectl get obtenants.oceanbase.oceanbase.com -n oceanbase -o yaml + ``` + + 当看到租户的 OBTenant 资源中 `status.resourcePool.priority` 对应的值变为修改后的值,则说明修改成功。 + + ```yaml + status: + ...... + resourcePool: + - zone: zone1 + priority: 3 + - zone: zone2 + priority: 2 + - zone: zone3 + priority: 1 + ``` + + 也可以通过以下命令更简单地查看结果。 + + ```shell + kubectl get obtenants.oceanbase.oceanbase.com -n oceanbase -o wide + ``` + + 返回结果示例如下: + + ```shell + NAME STATUS TENANTNAME TENANTROLE CLUSTERNAME AGE LOCALITY PRIMARYZONE POOLLIST CHARSET + t1 running t1 PRIMARY obcluster 13m ... zone1;zone2;zone3 ... utf8mb4 + ``` + + 可以看到 PRIMARYZONE 字段已经修改为了 `zone1;zone2;zone3`,与设置的 priority 相符合。 + +## 修改租户 locality + +修改租户的 locality,可以修改 type 配置项用于指定副本类型和副本数量,副本类型支持 full、logonly、readonly。 + +操作步骤可参考 [修改租户 Primary Zone](#修改租户-primary-zone)。 + +修改租户配置文件 `tenant.yaml` 内的具体内容如下: + +```yaml + type: + name: Full # 支持 Full 和 Readonly 两种副本类型 + replica: 1 +``` + +## 增加副本 + +### 前提 + +* 在集群中已增加 Zone,具体操作可参考[在集群中增加 zone](../../100.cluster-management-of-ob-operator/300.zone-management/100.add-zone.md)。 + +### 操作步骤 + +在租户中增加 Zone 的操作可以通过修改租户的配置文件 tenant.yaml 来完成。 + +当前集群中共包含 4 个可用区 `zone1、zone2、zone3、zone4`,租户对应的 zone 为 `zone1、zone2、zone3`,现需要扩容至 `zone1、zone2、zone3、zone4`。 + +1. 修改配置文件 tenant.yaml,增加 zone4。 + + ```yaml + # 示例: 租户中有 3 个 zone + pools: + - zone: zone1 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + - zone: zone2 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + - zone: zone3 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + + # 在租户中增加 zone(zone4) + pools: + - zone: zone1 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + - zone: zone2 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + - zone: zone3 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + - zone: zone4 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + ``` + +2. 配置文件修改后,运行如下命令使改动生效。 + + ```shell + kubectl apply -f tenant.yaml + ``` + +3. 执行以下语句,查看当前 Kubernetes 集群中租户的 OBTenant 资源。 + + ```shell + kubectl get obtenants.oceanbase.oceanbase.com -n oceanbase -o wide + ``` + + 返回结果示例如下,观察 LOCALITY 字段符合预期。 + + ```shell + NAME STATUS TENANTNAME TENANTROLE CLUSTERNAME AGE LOCALITY PRIMARYZONE POOLLIST CHARSET + t1 running t1 PRIMARY obcluster 19m FULL{1}@zone1,FULL{1}@zone2,FULL{1}@zone3,FULL{1}@zone4 ... ... utf8mb4 + ``` + +## 减少副本 + +### 操作步骤 + +在租户中减少 Zone 的操作可以通过修改租户的配置文件 tenant.yaml 来完成。 + +当前集群中共包含 4 个可用区 `zone1、zone2、zone3、zone4`,租户对应的 zone 为 `zone1、zone2、zone3、zone4`,现需要缩容至 `zone1、zone2、zone3`。 + +1. 修改配置文件 tenant.yaml,减少 zone4。 + + ```yaml + # 示例: 租户中有 4 个 zone + pools: + - zone: zone1 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + - zone: zone2 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + - zone: zone3 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + - zone: zone4 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + + # 在租户中减少 zone(zone4) + pools: + - zone: zone1 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + - zone: zone2 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + - zone: zone3 + unitNum: 1 + type: + name: Full + replica: 1 + priority: 3 + resource: + ... + ``` + +2. 配置文件修改后,运行如下命令使改动生效。 + + ```shell + kubectl apply -f tenant.yaml + ``` + +3. 执行以下语句,查看当前 Kubernetes 集群中租户的 OBTenant 资源。 + + ```shell + kubectl get obtenants.oceanbase.oceanbase.com -n oceanbase -o wide + ``` + + 返回结果示例如下,观察 LOCALITY 字段符合预期。 + + ```shell + NAME STATUS TENANTNAME TENANTROLE CLUSTERNAME AGE LOCALITY PRIMARYZONE POOLLIST CHARSET + t1 running t1 PRIMARY obcluster 25m FULL{1}@zone1,FULL{1}@zone2,FULL{1}@zone3 ... ... utf8mb4 + ``` diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/300.other-configuration-item-modifications-of-ob-operator.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/300.other-configuration-item-modifications-of-ob-operator.md new file mode 100644 index 000000000..5da302843 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/200.modify-tenant-of-ob-operator/300.other-configuration-item-modifications-of-ob-operator.md @@ -0,0 +1,40 @@ +# 其他配置项修改 + +本文主要介绍除租户资源、租户副本外,其他配置项的修改。 + +* 修改租户资源的详细内容可参考 [资源管理](100.resource-management-of-ob-operator.md)。 + +* 修改租户副本的详细内容可参考 [副本管理](200.replica-management-of-ob-operator.md)。 + +## 修改租户的连接白名单 + +如果您需要修改租户的客户端 IP 连接白名单,可以修改该租户的 connectWhiteList 配置项。如果用户需要修改改配置,则需要将 ob-operator 所处的网段包含在配置内,否则 ob-operator 会连接不上该租户。 + +1. 修改租户配置文件 `tenant.yaml`,调整 `spec` 下 `connectWhiteList` 值。 + + ```yaml + spec: + ...... + connectWhiteList: '%' + ``` + +2. 配置文件修改后,运行如下命令使改动生效。 + + ```shell + kubectl apply -f tenant.yaml + ``` + +3. 执行以下语句,查看当前 Kubernetes 集群中租户的 OBTenant 资源,来判断是否修改成功。 + + ```shell + kubectl get obtenants.oceanbase.oceanbase.com -n oceanbase -o yaml + ``` + + 当看到租户的 OBTenant 资源中 `spec:connectWhiteList` 对应的值变为修改后的值,则说明修改成功。 + + ```yaml + spec: + obcluster: obcluster + connectWhiteList: '%' + pools: + ``` diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/300.delete-tenant-of-ob-operator.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/300.delete-tenant-of-ob-operator.md new file mode 100644 index 000000000..92076a55f --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/300.delete-tenant-of-ob-operator.md @@ -0,0 +1,21 @@ +# 删除租户 + +本文主要介绍通过 ob-operator 在 Kubernetes 环境中删除租户。 + +## 具体操作 + +通过配置文件 tenant.yaml 在集群中删除指定的租户资源。配置文件可参考 [GitHub](https://github.com/oceanbase/ob-operator/blob/2.1.0_release/deploy/tenant.yaml)。 + +删除租户的命令如下,该命令会在当前 Kubernetes 集群中删除对应租户的 OBTenant 资源。 + +```shell +kubectl delete -f tenant.yaml +``` + +执行以下语句,查看当前 Kubernetes 集群中是否有刚才删除的租户 OBTenant 资源。 + +```shell +kubectl get obtenants.oceanbase.oceanbase.com -A -o yaml +``` + +如果不存在,则说明删除成功。 diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/400.tenant-operation.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/400.tenant-operation.md new file mode 100644 index 000000000..b58312e0c --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/200.tenant-management-of-ob-operator/400.tenant-operation.md @@ -0,0 +1,88 @@ +# 租户运维操作 + +租户资源涉及面较广,为了避免其变得过于臃肿、提高租户运维的灵活度,Operator 提供租户运维资源 OBTenantOperation 来完成租户内和租户间的运维功能。Operator 2.1.0 支持三种运维操作:修改 Root 密码、激活备租户和主备租户互切。其中,激活备租户和主备互切两个功能与[物理备库](../300.high-availability/600.standby-tenant-of-ob-operator.md)相关。三种运维操作的配置示例如下: + +```yaml op-chg-pwd.yaml +#修改密码 +apiVersion: oceanbase.oceanbase.com/v1alpha1 +kind: OBTenantOperation +metadata: + name: op-chg-pwd + namespace: oceanbase +spec: + type: "CHANGE_PASSWORD" + changePwd: + tenant: "t1" + secretRef: "t1-credential-new" +``` + +```yaml op-failover.yaml +#备租户升级为主租户 +apiVersion: oceanbase.oceanbase.com/v1alpha1 +kind: OBTenantOperation +metadata: + name: op-failover + namespace: oceanbase +spec: + type: "FAILOVER" + failover: + standbyTenant: "t1s" +``` + +```yaml op-switchover.yaml +#主备互切 +apiVersion: oceanbase.oceanbase.com/v1alpha1 +kind: OBTenantOperation +metadata: + name: op-switchover + namespace: oceanbase +spec: + type: "SWITCHOVER" + switchover: + primaryTenant: "t1" + standbyTenant: "t1s" +``` + +## 常用操作示例 + +### 创建备租户 + +```shell +kubectl apply -f tenant_restore.yaml +``` + +### 查看租户状态 + +```shell +kubectl get obtenants.oceanbase.oceanbase.com -n oceanbase +``` + +返回结果示例如下: + +```shell +NAME STATUS TENANTNAME TENANTROLE CLUSTERNAME AGE +t1 running t1 PRIMARY obcluster 3d4h +t1s running t1s STANDBY obcluster 3h30m +``` + +### 执行租户运维操作 + +```shell +kubectl apply -f tenant_op_change_pwd.yaml +kubectl apply -f tenant_op_failover.yaml +``` + +### 查看租户运维操作信息 + +```shell +kubectl get obtenantoperations.oceanbase.oceanbase.com -n oceanbase +``` + +返回结果示例如下: + +```shell +NAME TYPE STATUS AGE CLUSTER PRIMARYTENANT +op-failover FAILOVER SUCCESSFUL 8s obcluster t1s +``` + +需要说明的是,在打印的状态信息中,PRIMARYTENANT 指的是参数当中的首要租户,而非主租户。对应着的次要租户为 SECONDARYTENANT。为了节省空间默认不打印次要租户字段,使用命令 `kubectl get obtenantoperations.oceanbase.oceanbase.com -o wide` 可查看。 diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/300.high-availability/100.high-availability-intro.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/300.high-availability/100.high-availability-intro.md new file mode 100644 index 000000000..8e13ed964 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/300.high-availability/100.high-availability-intro.md @@ -0,0 +1,7 @@ +# 高可用 + +ob-operator 利用 OceanBase 的若干特性来保证数据的高可用 + +* [节点故障恢复](300.disaster-recovery-of-ob-operator.md),基于 OceanBase 分布式的特性,可以从少数派节点故障的情况恢复,利用特定的网络插件甚至能实现全部节点故障的恢复。 +* [租户数据备份恢复](400.tenant-backup-of-ob-operator.md),利用 OceanBase 的备份恢复能力,可以将租户的数据备份到其他存储介质,为数据提供更安全的保障。 +* [主备租户](600.standby-tenant-of-ob-operator.md),利用 OceanBase 的主备租户能力,可以建立两个租户的主备关系,在故障发生时可以很快切换,能保证业务受到的影响更小。 diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/300.high-availability/300.disaster-recovery-of-ob-operator.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/300.high-availability/300.disaster-recovery-of-ob-operator.md new file mode 100644 index 000000000..c2de52293 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/300.high-availability/300.disaster-recovery-of-ob-operator.md @@ -0,0 +1,40 @@ +# 故障恢复 + +本文介绍 ob-operator 对于 OceanBase 节点故障的处理 + +## 前提条件 + +* 要成功恢复 OceanBase 集群,需要部署至少三个节点,并且租户也是至少三个副本。 +* 若要使用保留 IP 地址恢复的能力,需要集群使用 calico 作为网络插件。 + +## 恢复策略 + +对于少数派故障,OceanBase 凭借多副本机制还能保证集群可用,这时 ob-operator 会发现 pod 异常,然后通过 add server 再 delete server 的方式,新建一个新的 observer 加入到集群,再删除原来的 observer +, OceanBase 会自动利用新加入的 observer 去补全数据副本。 + +如果 K8s 集群使用了 calico 网络插件,那么这个过程将更加容易,ob-operator 会通过指定 ip 的形式,指定原 IP 地址来启动一个新的 observer,这样如果数据还存在的话,会直接利用原 server 的数据,并不需要再重新复制一份数据,而且对于多数派故障,这种方式也能在新的 observer 都启动了之后恢复服务。 + +## 验证 + +您可以通过以下方式验证 ob-operator 的故障恢复能力 + +删除 pod + +```shell +kubectl delete pod obcluster-1-zone1-074bda77c272 -n oceanbase +``` + +查看恢复情况, 可以看到 zone1 对应的 pod 已经被新建出来,并且Ready。 + +```shell +kubectl get pods -n oceanbase + +NAME READY STATUS RESTARTS AGE +obcluster-1-zone3-074bda77c272 2/2 Running 0 12d +obcluster-1-zone2-7ecbd89f84de 2/2 Running 0 12d +obcluster-1-zone1-94ecf05cb290 2/2 Running 0 1m +``` + +## 部署建议 + +基于以上的介绍,如果您要部署生产使用的集群,要得到较好的故障恢复能力的话,推荐使用 calico 网络插件,并且集群至少部署 3 节点,租户副本数量至少 3 个,每个 zone 的节点选择尽量在不同的机器上,以便尽可能的降低整个集群故障无法恢复的可能,另外,ob-operator 还提供了基于[备份恢复](500.data-recovery-of-ob-operator.md)和[主备租户](400.tenant-backup-of-ob-operator.md)的高可用方案,可以参考对应章节。 diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/300.high-availability/400.tenant-backup-of-ob-operator.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/300.high-availability/400.tenant-backup-of-ob-operator.md new file mode 100644 index 000000000..2a05e3d82 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/300.high-availability/400.tenant-backup-of-ob-operator.md @@ -0,0 +1,291 @@ +# 租户备份 + +本文介绍如何进行租户数据备份。租户数据备份的关键资源为 OBTenantBackupPolicy 和 OBTenantBackup,分别表示备份策略和备份任务。通过备份策略,可以为 OceanBase 集群当中某个租户指定周期性的日志归档和数据备份配置。备份策略会通过创建备份任务的方式来执行具体的任务。备份目的地支持 NFS 和 OSS 两种。 + +## 前提条件 + +备份到 NFS 的方式需要确保部署 OceanBase 集群时设置了备份的 volume,对应的 NFS 可以正常访问并有读写权限。 + +## 备份策略的配置 + +### 参考配置 + +租户备份策略为特定的租户配置,可以参考的配置文件如下: + +```yaml +apiVersion: oceanbase.oceanbase.com/v1alpha1 +kind: OBTenantBackupPolicy +metadata: + name: backup-policy-example + namespace: oceanbase +spec: + obClusterName: "test" + tenantName: "t1" + tenantSecret: "t1-credential" + tenantCRName: "tenant-cr" + jobKeepWindow: "1d" + suspend: false + dataClean: + recoveryWindow: "8d" + logArchive: + destination: + type: "OSS" + path: "oss://bucket/archive?host=oss-cn-hangzhou.aliyuncs.com" + ossAccessSecret: "oss-access" + # type: "NFS" + # path: "t1/logArchive" + switchPieceInterval: "1d" + binding: Optional + dataBackup: + destination: + type: "OSS" + path: "oss://bucket/backup?host=oss-cn-hangzhou.aliyuncs.com" + ossAccessSecret: "oss-access" + # type: "NFS" + # path: "t1/dataBackup" + fullCrontab: "30 0 * * 6" + incrementalCrontab: "30 1 * * *" + encryptionSecret: t1-encryption +``` + +### 配置说明 + +备份策略配置说明: + +* obClusterName: 同 namespace 下 OB 集群资源的名称 +* tenantName: 数据库中的租户名 +* tenantSecret: 包含名为 tenantName 的租户 root 用户密码的 Secret 资源名 +* tenantCRName: OBTenant 租户资源名,若指定了该字段,则无需指定 tenantName 和 tenantSecret +* jobKeepWindow: 备份任务资源保留时间窗口 +* suspend: 备份任务是否暂停,如果不配置,默认为 `false` +* dataClean: 过期备份数据清理配置 + * recoveryWindow: 数据恢复的时间窗口 +* logArchive: 日志归档配置 + * destination: 备份目的地配置 + * switchPieceInterval: 日志归档中 `piece` 的切换周期,取值范围为 `[1d, 7d]`。如果不设置,默认为 `1d` + * binding: 设置归档和业务的优先模式。目前支持 `Optional` 和 `Mandatory` 两种模式。如果不配置,默认为 `Optional` 模式 +* dataBackup: 数据备份配置 + * destination: 备份目的地配置 + * fullCrontab: 全量备份的定时触发配置,[采用 cron expression 格式](https://crontab.guru/) + * incrementalCrontab: 增量备份的定时触发配置,[采用 cron expression 格式](https://crontab.guru/) + * encryptionSecret: 数据备份加密配置的 Secret 资源名 + +备份目的地配置说明: + +destination: + +* type:目的地类型,支持 NFS 和 OSS 两种。 +* path:目的地的备份路径,如果是 OSS 类型,则需要以 `oss://` 开头;如果是 NFS 类型,则是非 `/` 开头的相对路径。 +* ossAccessSecret: 存放访问 OSS 凭证的 Secret 资源名,如果备份目的地类型为 OSS,该字段必须提供。 + +tenantSecret 示例: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: tenant-root + namespace: oceanbase +data: + # base64 encoded + password: ****** +``` + +encryptionSecret 示例: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: tenant-backup-encryption + namespace: oceanbase +data: + # base64 encoded + password: ****** +``` + +ossAccessSecret 示例: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: oss-access + namespace: obcluster +data: + # base64 encoded + accessId: ****** + accessKey: ****** +``` + +## 常用操作 + +### 发起备份 + +使用如下命令,创建备份相关的 Secret 资源,文件名请根据实际情况进行指定。 + +```shell +kubectl apply -f tenant-secret.yaml +kubectl apply -f backup-encryption.yaml +kubectl apply -f oss-access.yaml +``` + +使用如下命令创建租户备份策略。 + +```shell +kubectl apply -f backup-policy.yaml +``` + +### 查看备份策略状态 + +使用如下命令查看备份策略的状态。 + +```shell +kubectl get obtenantbackuppolicies.oceanbase.oceanbase.com -n oceanbase +``` + +返回结果示例如下: + +```shell +NAME STATUS AGE TENANTNAME NEXTFULL NEXTINCREMENTAL FULLCRONTAB INCREMENTALCRONTAB +backup-policy-example RUNNING 2m46s t1 2023-11-10 11:07:58 */60 * * * * */25 * * * * +``` + +### 查看备份任务状态 + +备份策略会通过创建备份任务的形式来执行具体的备份操作,使用如下命令可以查看备份任务的状态: + +```shell +kubectl get obtenantbackups.oceanbase.oceanbase.com -n oceanbase +``` + +返回结果示例如下: + +```shell +NAME TYPE STATUS TENANTNAME STARTEDAT ENDEDAT +backup-policy-example-clean-20231110110746 CLEAN RUNNING t1 +backup-policy-example-full-20231110110756 FULL SUCCESSFUL t1 2023-11-10 11:08:06.952711 2023-11-10 11:13:31.079246 +backup-policy-example-archive-20231110110746 ARCHIVE RUNNING t1 2023-11-10 11:07:50.139978 2023-11-10 11:13:50.128627 +``` + +### 查看备份策略详细信息 + +使用如下命令可以查看备份策略的详细信息。 + +* 使用 `kubectl get -o yaml` + +```shell +kubectl get -n oceanbase obtenantbackuppolicies.oceanbase.oceanbase.com backup-policy-example -o yaml +``` + +返回结果示例如下: + +```yaml +apiVersion: oceanbase.oceanbase.com/v1alpha1 +kind: OBTenantBackupPolicy +metadata: + creationTimestamp: "2023-11-10T03:07:39Z" + finalizers: + - obtenantbackuppolicy.finalizers.oceanbase.com + generation: 1 + name: backup-policy-example + namespace: oceanbase + resourceVersion: "775461" + uid: 7ab40200-f849-434d-b1a5-6aad888cf42e +spec: + dataBackup: + destination: + ossAccessSecret: oss-access + path: oss://bucket/backup?host=oss-cn-hangzhou.aliyuncs.com + type: OSS + fullCrontab: '*/60 * * * *' + incrementalCrontab: '*/25 * * * *' + encryptionSecret: t1-encryption + dataClean: + recoveryWindow: 8d + jobKeepWindow: 1d + logArchive: + destination: + ossAccessSecret: oss-access + path: oss://bucket/archive?host=oss-cn-hangzhou.aliyuncs.com + type: OSS + switchPieceInterval: 1d + obClusterName: test + tenantName: t1 + tenantSecret: t1-credential +status: + latestArchiveLogJob: + fields: values... + latestFullBackupJob: + fields: values... + nextFull: "2023-11-10 12:00:00" + nextIncremental: "2023-11-10 11:25:00" + observedGeneration: 1 + status: RUNNING + tenantCR: + fields: values... + tenantInfo: + fields: values... +``` + +* 使用 `kubectl describe` + +```shell +kubectl describe -n oceanbase obtenantbackuppolicies.oceanbase.oceanbase.com backup-policy-example +``` + +返回结果示例如下: + +```text +Name: backup-policy-example +Namespace: oceanbase +Labels: +Annotations: +API Version: oceanbase.oceanbase.com/v1alpha1 +Kind: OBTenantBackupPolicy +Metadata: + Creation Timestamp: 2023-11-10T03:07:39Z + Finalizers: + obtenantbackuppolicy.finalizers.oceanbase.com + Generation: 1 + Resource Version: 775477 + UID: 7ab40200-f849-434d-b1a5-6aad888cf42e +Spec: + Data Backup: + Destination: + Oss Access Secret: oss-access + Path: oss://bucket/backup?host=oss-cn-hangzhou.aliyuncs.com + Type: OSS + Full Crontab: */60 * * * * + Incremental Crontab: */25 * * * * + Encryption Secret: t1-encryption + Data Clean: + Recovery Window: 8d + Job Keep Window: 1d + Log Archive: + Destination: + Oss Access Secret: oss-access + Path: oss://bucket/archive?host=oss-cn-hangzhou.aliyuncs.com + Type: OSS + Switch Piece Interval: 1d + Ob Cluster Name: test + Tenant Name: t1 + Tenant Secret: t1-credential +Status: + Latest Archive Log Job: + fields: values... + Latest Full Backup Job: + fields: values... + Next Full: 2023-11-10 12:00:00 + Next Incremental: 2023-11-10 11:25:00 + Observed Generation: 1 + Status: RUNNING + Tenant CR: + fields: values... + Tenant Info: + fields: values... +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal 12m obtenantbackuppolicy-controller init status +``` diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/300.high-availability/500.data-recovery-of-ob-operator.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/300.high-availability/500.data-recovery-of-ob-operator.md new file mode 100644 index 000000000..46c4eea58 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/300.high-availability/500.data-recovery-of-ob-operator.md @@ -0,0 +1,190 @@ +# 数据恢复 + +本文档介绍从备份数据恢复的方法。数据恢复依赖关键资源为 OBTenant 和 OBTenantRestore,分别表示租户和租户恢复任务。因数据恢复行为的最终结果是产生一个新的租户,所以使用在 OBTenant Spec 中的 Source 字段来指定租户的恢复源。在租户资源中指定了数据恢复相关的字段之后,Operator 会创建出 OBTenantRestore 资源来执行具体的恢复任务。 + +## 前提条件 + +* 存在成功备份可恢复的数据。 + +* 集群正常运行,并且剩余资源足够创建恢复租户。 + +* 如果恢复源为 NFS 类型,需要确定挂载到 OceanBase 集群的备份 Volume 可用。 + +## 数据恢复配置文件说明 + +恢复数据的配置文件即租户管理当中所提到的 OBTenant 资源描述: + +```yaml tenant_restore.yaml +apiVersion: oceanbase.oceanbase.com/v1alpha1 +kind: OBTenant +metadata: + name: t1s + # namespace: oceanbase +spec: + obcluster: obcluster + tenantName: t1s + unitNum: 1 + tenantRole: STANDBY + source: + restore: + bakDataSource: + # type: "NFS" + # path: "t1/dataBackup" + type: "OSS" + path: "oss://bucket/backup?host=oss-cn-hangzhou.aliyuncs.com" + ossAccessSecret: "oss-access" + archiveSource: + # type: "NFS" + # path: "t1/logArchive" + type: "OSS" + path: "oss://bucket/archive?host=oss-cn-hangzhou.aliyuncs.com" + ossAccessSecret: "oss-access" + until: + unlimited: true + replayLogUntil: + unlimited: true + tenant: t1 + fields: values +``` + +数据恢复相关配置说明如下: + +* tenantRole: 需要创建的租户的角色,可选值为 PRIMARY 和 STANDBY,分别代表主租户和备租户。如果不指定,默认为 PRIMARY;有关备租户/物理备库的说明文档,请查看[物理备库](./600.standby-tenant-of-ob-operator.md) +* source: 租户数据来源 + * restore: 备份数据恢复源 + * bakDataSource: 备份数据恢复的目标地址,与数据备份中数据备份目的地配置相同 + * archiveSource: 日志归档恢复的目标地址,同上 + * until: 数据恢复的截止位点 + * unlimited: 恢复到最新位点 + * timestamp: 需要恢复到的时间戳,格式为 YYYY-MM-DD HH:mm:ss,例如 2023-11-10 09:00:00 + * scn: 需要恢复到的 SCN + * replayLogUntil: 作为数据恢复截止位点的补充,表示在数据恢复之后继续回放主租户日志到指定的位点,仅在恢复成为备租户且数据恢复截止位点没有设置为最新位点时生效,配置与 `until` 相同 + * tenant: 指定主租户,仅在恢复成为备租户时生效 +* 其他配置与正常租户的配置相同 + +## 常用操作实例 + +### 发起数据恢复 + +使用以下命令发起租户数据恢复。 + +```shell +kubectl apply -f tenant_restore.yaml +``` + +### 查看数据恢复状态 + +* 使用以下命令,查看待恢复租户的状态。 + +```shell +kubectl get obtenants.oceanbase.oceanbase.com -n oceanbase +``` + +返回结果如下: + +```shell +NAME STATUS TENANTNAME TENANTROLE CLUSTERNAME AGE +t1s restoring t1s STANDBY obcluster 27s +``` + +* 使用以下命令查看创建的租户恢复任务。 + +```shell +kubectl get obtenantrestores.oceanbase.oceanbase.com -n oceanbase +``` + +返回结果如下: + +```shell +NAME STATUS AGE TARGETTENANT TARGETCLUSTER RESTOREROLE STATUSINDB +t1s-restore RUNNING 113s t1s obcluster STANDBY WAIT_TENANT_RESTORE_FINISH +``` + +* 使用以下命令查看租户恢复任务的详细信息 + +```shell +kubectl describe obtenantrestores.oceanbase.oceanbase.com -n oceanbase +``` + +返回结果如下: + +```shell +Name: t1s-restore +Namespace: oceanbase +Labels: oceanbase.oceanbase.com/tenant-name=t1s + ref-obcluster=obcluster + ref-uid=b9317541-6566-4ac0-84fb-9a4c6fca03ba +Annotations: +API Version: oceanbase.oceanbase.com/v1alpha1 +Kind: OBTenantRestore +Metadata: +Creation Timestamp: 2023-11-13T03:13:26Z +Generation: 1 +Owner References: + API Version: oceanbase.oceanbase.com/v1alpha1 + Block Owner Deletion: true + Kind: OBTenant + Name: t1s + UID: b9317541-6566-4ac0-84fb-9a4c6fca03ba +Resource Version: 927784 +UID: e439a060-9758-4074-a170-661d3e23a836 +Spec: +Primary Tenant: t1 +Restore Option: pool_list=pool_t1s_zone1&primary_zone=zone1;&locality=FULL{1}@zone1 +Restore Role: STANDBY +Source: + Archive Source: + Oss Access Secret: oss-access + Path: oss://bucket/archive?host=oss-cn-hangzhou.aliyuncs.com + Type: OSS + Bak Data Source: + Oss Access Secret: oss-access + Path: oss://bucket/backup?host=oss-cn-hangzhou.aliyuncs.com + Type: OSS + Replay Log Until: + Unlimited: true + Until: + Unlimited: true +Target Cluster: obcluster +Target Tenant: t1s +Status: +Restore Progress: + backup_cluster_name: obcluster + backup_cluster_version: + backup_dest: oss://bucket/backup?host=oss-cn-hangzhou.aliyuncs.com&access_id=xxx&access_key=yyy,oss://bucket/archive?host=oss-cn-hangzhou.aliyuncs.com&access_id=xxx&access_key=yyy + backup_piece_list: oss://bucket/archive/piece_d1005r10p10?host=oss-cn-hangzhou.aliyuncs.com&access_id=xxx&access_key=yyy + backup_set_list: oss://bucket/backup/backup_set_25_full?host=oss-cn-hangzhou.aliyuncs.com&access_id=xxx&access_key=yyy,oss://bucket/backup/backup_set_26_inc?host=oss-cn-hangzhou.aliyuncs.com&access_id=xxx&access_key=yyy + backup_tenant_id: 1016 + backup_tenant_name: t1 + Description: + finish_ls_count: 0 + finish_tablet_count: 0 + finish_timestamp: + job_id: 5 + ls_count: 0 + restore_option: pool_list=pool_t1s_zone1&primary_zone=zone1;&locality=FULL{1}@zone1 + restore_scn: 1697098764718466986 + restore_scn_display: 2023-10-12 16:19:24.718466 + restore_tenant_id: 1004 + restore_tenant_name: t1s + start_timestamp: 2023-11-13 11:13:46.220513 + Status: WAIT_TENANT_RESTORE_FINISH + tablet_count: 0 + tenant_id: 1 +Status: RUNNING +Events: +``` + +## 查看租户恢复是否成功 + +* 连接 sys 租户。 + +```shell +mysql -h$(kubectl get pods -l ref-obcluster=test -o jsonpath='{.items[0].status.podIP}') -P2881 -uroot oceanbase -A -c +``` + +* 查看需恢复的租户是否恢复。 + +```sql +select * from DBA_OB_TENANTS; +``` diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/300.high-availability/600.standby-tenant-of-ob-operator.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/300.high-availability/600.standby-tenant-of-ob-operator.md new file mode 100644 index 000000000..d76c3feef --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/300.high-availability/600.standby-tenant-of-ob-operator.md @@ -0,0 +1,60 @@ +# 物理备库 + +本文介绍物理备库功能,该功能为 OceanBase v4.x 新支持的功能,可以为用户的关键应用提供高可用、数据保护、灾难恢复等重要特性。涉及到的资源为 OBTenant 和 OBTenantOperation,分别表示租户资源和租户运维操作。物理备库可以从数据备份中创建,也可以从空租户开始创建,所以此部分与数据恢复相关性较高,互为补充。 + +## 配置文件示例 + +物理备库的配置也内置于 OBTenant 资源当中,具体可参见[数据恢复](500.data-recovery-of-ob-operator.md)章节的介绍。 + +```yaml tenant_standby.yaml +apiVersion: oceanbase.oceanbase.com/v1alpha1 +kind: OBTenant +metadata: + name: t1s + # namespace: oceanbase +spec: + obcluster: obcluster + tenantName: t1s + unitNum: 1 + tenantRole: STANDBY + source: + restore: + bakDataSource: + # type: "NFS" + # path: "t1/dataBackup" + type: "OSS" + path: "oss://bucket/backup?host=oss-cn-hangzhou.aliyuncs.com" + ossAccessSecret: "oss-access" + archiveSource: + # type: "NFS" + # path: "t1/logArchive" + type: "OSS" + path: "oss://bucket/archive?host=oss-cn-hangzhou.aliyuncs.com" + ossAccessSecret: "oss-access" + until: + unlimited: true + replayLogUntil: + unlimited: true + tenant: t1 + fields: values +``` + +物理备库相关配置项说明: + +* tenantRole:租户的角色,若租户需要作为备库则设置为 STANDBY,若不设置则为默认值 PRIMARY +* source:租户数据来源 + * restore:备份数据恢复源 + * tenant:指定需要同步的主租户 + +## 配置项组合说明 + +OBTenant.Spec.Source 当中有两个分支 `restore` 和 `tenant` 分别指定数据恢复源和主租户,当两个分支的组合条件不同时,Operator 会产生出不同的行为: + +* 同时提供 restore 和 tenant:按照 `restore` 属性恢复出租户,恢复完成后修改备租户的日志恢复源到主租户处,根据设定的数据恢复截止位点和日志回放截止位点回放日志; +* 只提供 restore:按照 `restore` 属性恢复出租户,并且按照 tenantRole 修改租户角色属性; +* 只提供 tenant:检查指定租户资源的存在性和 LS 日志完整性,如果检查通过,则创建出一个空备租户同步到指定的主租户; +* restore 和 tenant 均不提供:无法通过校验提交到集群中。 + +## 备租户升主和主备互切 + +此部分功能请参见[租户运维操作](../200.tenant-management-of-ob-operator/400.tenant-operation.md)。 diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/_category_.yml b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/_category_.yml new file mode 100644 index 000000000..1c8310214 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/500.ob-operator-user-guide/_category_.yml @@ -0,0 +1,3 @@ +position: 6 +link: + type: generated-index \ No newline at end of file diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/900.appendix/100.example.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/900.appendix/100.example.md new file mode 100644 index 000000000..161f258aa --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/900.appendix/100.example.md @@ -0,0 +1,283 @@ +# OceanBase 以及应用在 K8s 中部署的示例 + +本文介绍在实际环境中 OceanBase 和应用程序在 K8s 中部署的典型架构,通过真实示例展示如何在 K8s 中部署 OceanBase 和相关组件以及应用程序。 + +## 前提条件 + +在您开始之前,确保您已经在 k8s 集群当中部署了,[cert-manager](https://cert-manager.io/docs/) 、[local-path-provisioner](https://github.com/rancher/local-path-provisioner) 和 [ob-operator](https://github.com/oceanbase/ob-operator)。 + +本文涉及以下组件: + +* [oceanbase](https://github.com/oceanbase/oceanbase), OceanBase 数据库。 +* [ob-configserver](https://github.com/oceanbase/oceanbase/tree/master/tools/ob-configserver),用于注册 OceanBase 数据库的 rootservice 地址信息。 +* [obproxy](https://github.com/oceanbase/obproxy), OceanBase 数据库代理程序。 +* [OCP](https://hub.docker.com/r/oceanbase/ocp-ce),OceanBase 云平台。本文使用 OCP 作为 Web 应用进行演示。 +* [Prometheus](https://prometheus.io/),监控告警系统,通过 Prometheus 采集和计算 OceanBase 监控指标。 +* [Grafana](https://grafana.com/),数据可视化系统。与 Prometheus 对接可以可视化展示 OceanBase 的监控数据。 + +## 部署 OceanBase 以及相关组件 + +### 部署前准备 + +创建 namespace。 + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.0_release/example/webapp/namespace.yaml +``` + +使用以下命令查看创建的 namespace: + +```shell +kubectl get namespace oceanbase +``` + +输出如下结果表示创建成功: + +```shell +NAME STATUS AGE +oceanbase Active 98s +``` + +创建集群和租户的 secret: + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.0_release/example/webapp/secret.yaml +``` + +通过以下命令查看创建的 secret: + +```shell +kubectl get secret -n oceanbase +``` + +输出如下结果表示创建成功: + +```shell +NAME TYPE DATA AGE +sc-metatenant-root Opaque 1 11s +sc-metatenant-standbyro Opaque 1 11s +sc-sys-monitor Opaque 1 11s +sc-sys-operator Opaque 1 11s +sc-sys-proxyro Opaque 1 11s +sc-sys-root Opaque 1 11s +``` + +### 部署 ob-configserver + +ob-configserver 是提供 OceanBase rootservice 信息注册和查询的服务,元数据存储支持 MySQL 和 Sqlite3。这里为了简单使用了 Sqlite3。 +使用如下命令部署 ob-configserver 以及创建对应的 service: + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.0_release/example/webapp/configserver.yaml +``` + +检查 pod 状态: + +```shell +kubectl get pods -n oceanbase | grep ob-configserver + +# desired output +ob-configserver-856bf5d865-dlwxr 1/1 Running 0 16s +``` + +检查 svc 状态: + +```shell +kubectl get svc svc-ob-configserver -n oceanbase + +# desired output +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +svc-ob-configserver NodePort 10.96.3.39 8080:30080/TCP 98s +``` + +### 部署 OceanBase 集群 + +部署 OceanBase 集群时增加环境变量,使用 ob-configserver 的服务地址作为系统参数 obconfig_url 的值,OceanBase 会将 rootservice 信息注册到 ob-configserver 中。 +使用如下命令部署 OceanBase 集群: + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.0_release/example/webapp/obcluster.yaml +``` + +轮询使用如下命令检查 obcluster 状态,直到集群变成 running 状态。 + +```shell +kubectl get obclusters.oceanbase.oceanbase.com metadb -n oceanbase + +# desired output +NAME STATUS AGE +metadb running 3m21s +``` + +### 部署 ObProxy + +ObProxy 支持使用 ob-configserver 或者直接指定 rs_list 的形式启动,为了能充分利用 obproxy 的能力,推荐使用 ob-configserver 的形式连接集群 + +使用如下命令部署 ObProxy 以及创建 service: + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.0_release/example/webapp/obproxy.yaml +``` + +查看 ObProxy 的 pod 状态,会有两个 obproxy 的 pod。 + +```shell +kubectl get pod -A | grep obproxy + +# desired output +oceanbase obproxy-5cb8f4d975-pmr59 1/1 Running 0 21s +oceanbase obproxy-5cb8f4d975-xlvjp 1/1 Running 0 21s +``` + +查看 ObProxy 的 service: + +```shell +kubectl get svc svc-obproxy -n oceanbase + +# desired output +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +svc-obproxy ClusterIP 10.96.2.46 2883/TCP,2884/TCP 2m26s +``` + +通过 ObProxy 服务地址连接 OceanBase 集群: + +```shell +mysql -h${obproxy-service-address} -P2883 -uroot@sys#metadb -p +``` + +连接成功表示 obproxy 服务正常: + +![connection](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/observer/V4.2.0/ob-operator-1.png) + +如果提示 `cluster not exist` 表示 OceanBase 集群尚未把集群元信息注册到 ob-configserver,请稍作等待后重试连接。您可以使用 `curl "http://127.0.0.1:30080/services?Action=ObRootServiceInfo&ObCluster=metadb"` 查看注册结果。如果返回的结果 RsList 参数不为空,说明已经注册完成。 + +## 部署应用 + +### 创建租户 + +为业务单独创建一个租户,可以更好的做到资源的隔离,本文中为了简单,仅创建一个租户。 + +使用如下命令创建租户: + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.0_release/example/webapp/tenant.yaml +``` + +创建后轮询租户的资源状态, 当变成 running 时表示租户以及创建完成了 + +```shell +kubectl get obtenants.oceanbase.oceanbase.com metatenant -n oceanbase +NAME STATUS TENANTNAME TENANTROLE CLUSTERNAME AGE +metatenant running metatenant PRIMARY metadb 106s +``` + +使用如下命令连接租户进行验证: + +```shell +mysql -h${obproxy-service-address} -P2883 -uroot@metatenant#metadb -p +``` + +连接成功表示租户可以正常使用。 + +### 部署应用程序 + +本文中以部署 OCP 作为 web 应用的例子。 +创建 database +在启动应用之前,首先使用如下命令创建 database: + +```shell +# connect tenant +mysql -h${obproxy-service-address} -P2883 -uroot@metatenant#metadb -p + +# create meta database +create database ocp_metadb; + +# create monitor database +create database ocp_monitordb; +``` + +使用如下命令部署应用: + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.0_release/example/webapp/ocp.yaml +``` + +部署成功之后,可以通过如下命令进行查看部署的状态: + +```shell +# check pod +kubectl get pods -n oceanbase | grep ocp +ocp-6bb784f89f-q6cbs 1/1 Running 0 12m + +# check service +kubectl get svc svc-ocp -n oceanbase +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +svc-ocp NodePort 10.43.39.231 8080:32080/TCP 12m +``` + +部署成功之后需要一段时间才可以正常提供服务,可以通过服务地址进行访问。 + +```shell +# check by query time api +curl -L 'http://${service_ip}:${server_port}/api/v2/time' +"2023-11-27T00:00:13.687+08:00" +``` + +## 部署监控系统 + +### 部署 prometheus + +部署 OceanBase 集群的同时,在每个 pod 中创建了 obagent 的 sidecar 容器,可以提供 prometheus 协议的监控数据,同时也创建了一个 service,配合服务发现,可以做到自动识别 obagent 的地址去采集数据。 + +使用如下命令部署 prometheus: + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.0_release/example/webapp/prometheus.yaml +``` + +使用如下命令查看部署状态: + +```shell +# check pod status +kubectl get pods -n oceanbase | grep prometheus +prometheus-576d7757b9-jsvfh 1/1 Running 0 3m17s + +# check service status +kubectl get svc svc-prometheus -n oceanbase +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +svc-prometheus NodePort 10.96.1.212 9090:30090/TCP 3m45s +``` + +### 部署 grafana + +grafana 可以使用 prometheus 作为数据源,进行 OceanBase 指标的展示。 +使用如下命令部署 grafana: + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.0_release/example/webapp/grafana.yaml +``` + +使用如下命令查看部署状态: + +```shell +# check pod status +kubectl get pods -n oceanbase | grep grafana +grafana-b7c6c6ccb-dkv57 1/1 Running 0 2m + +# check service status +kubectl get svc svc-grafana -n oceanbase +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +svc-grafana NodePort 10.96.2.145 3000:30030/TCP 2m +``` + +打开浏览器访问服务地址,查看 OceanBase 的监控指标: + +![grafana](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/observer/V4.2.0/ob-operator-2.png) + +## 总结 + +本文介绍了典型的 OceanBase 部署模式,包括 OceanBase 及相关组件(oceanbase、obproxy 和 ob-configserver),应用以及监控系统的部署,其他应用的部署可以以此文档作为参考。 + +## 说明 + +本文中的配置文件均可在 [webapp 配置文件](https://github.com/oceanbase/ob-operator/tree/2.1.0_release/example/webapp) 目录中找到。 diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/900.appendix/200.FAQ.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/900.appendix/200.FAQ.md new file mode 100644 index 000000000..d2709e45c --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/900.appendix/200.FAQ.md @@ -0,0 +1,141 @@ +# FAQ + +## 1. 如何查看资源已经 ready + +以集群为例,您可以通过以下命令来查看资源状态: + +```shell +kubectl get obclusters.oceanbase.oceanbase.com test -n oceanbase +``` + +确认 status 状态,为 running 则表示资源可用。 + +```shell +# desired output +NAME STATUS AGE +test running 6m2s +``` + +## 2. 如何查看资源的运维状态 + +以集群为例,您可以通过以下命令来查看资源状态: + +```shell +kubectl get obclusters.oceanbase.oceanbase.com test -n oceanbase -o yaml +``` + +operationContext 中记录了运维的状态,您可以通过观察这个字段了解运维的状态和进度。 + +```shell +status: + image: oceanbase/oceanbase-cloud-native:4.2.0.0-101000032023091319 + obzones: + - status: delete observer + zone: obcluster-1-zone1 + - status: delete observer + zone: obcluster-1-zone2 + - status: delete observer + zone: obcluster-1-zone3 + operationContext: + failureRule: + failureStatus: running + failureStrategy: retry over + retryCount: 0 + idx: 2 + name: modify obzone replica + targetStatus: running + task: wait obzone topology match + taskId: c04aeb28-01e7-4f85-b390-8d855b9f30e3 + taskStatus: running + tasks: + - modify obzone replica + - wait obzone topology match + - wait obzone running + parameters: [] + status: modify obzone replica +``` + +## 3. ob-operator 如何排查问题 + +* ob-operator 的日志文件, 可以通过以下命令来查看,一般都是先分析 operator 的日志来找到具体哪里出现了错误。 + +```shell +kubectl logs oceanbase-controller-manager-86cfc8f7bf-js95z -n oceanbase-system -c manager | less +``` + +* observer 的日志文件 + +```shell +# 登录到 observer 的容器 +kubectl exec -it obcluster-1-zone1-8ab645f4d0f9 -n oceanbase -c observer -- bash + +# 日志文件所在目录 +cd /home/admin/oceanbase/log +``` + +## 4. ob-operator 如何修复“卡死”的资源 + +因为 ob-operator 采用基于状态机和任务流的机制来管理 CR (Custom Resource,自定义资源)及其运维操作,在配置出错、系统资源不足或者资源不匹配时,CR 有可能会陷入预期之外的状态,例如:不断重试一个必定失败的任务流、无法删除一个资源、误删资源但希望资源恢复运转等。当通过常规的 kubectl 操作无法将某一 CR 恢复正常时,可以借助 `OBResourceRescue` 资源对问题 CR 进行救治。`OBResourceRescue` 资源包含了四类操作:`重置`、`删除`、`重试`、`跳过`。 + +一个典型的 `OBResourceRescue` CR 配置如下所示: + +```yaml +apiVersion: oceanbase.oceanbase.com/v1alpha1 +kind: OBResourceRescue +metadata: + generateName: rescue-reset- # generateName 需搭配 kubectl create -f 使用 +spec: + type: reset + targetKind: OBCluster + targetResName: test + targetStatus: running # type 为 reset 时需要填写目标状态 +``` + +其中关键配置如下表说明: + +| 配置项 | 可选项 | 说明 | +| -- | -- | -- | +| type | `reset`, `delete`, `retry`, `skip` | 资源救治动作的类型 | +| targetKind | `OBCluster`, `OBZone`, `OBTenant` 等受 ob-operator 管理的 CRD Kind | 需要进行救治的资源 Kind | +| targetResName | / | 待救治的资源名称 | +| targetStatus | / | type 为 reset 需要填写该字段,表示资源重置后的状态 | + +### 重置 + +上述典型 CR 配置示例的配置信息就是重置类型的救治资源,将该资源通过 `kubectl create -f` 命令创建到 K8s 集群中后,会将 Kind 为 OBCluster,名为 test 的资源的 `status.status` 设置为 `running`(在配置文件中设置的 targetStatus),将该资源的 `status.operationContext` 置为空。 + +### 删除 + +删除类型的救治动作配置示例如下,它创建到集群中后,ob-operator 会将目标资源的 `finalizers` 字段清空,并将该资源的 `deletionTimestamp` 设置为当前时刻。 + +```yaml +# ... +spec: + type: delete + targetKind: OBCluster + targetResName: test +``` + +### 重试 + +重试类型的救治动作配置示例如下,它创建到集群中后,ob-operator 会将目标资源的 `status.operationContext.retryCount` 置为 0,并且将 `status.operationContext.taskStatus` 置为 `pending`。处在该状态的资源将重试当前任务。 + +```yaml +# ... +spec: + type: retry + targetKind: OBCluster + targetResName: test +``` + +### 跳过 + +跳过类型的救治动作配置示例如下,被创建到集群当中后,ob-operator 会把目标资源的 `status.operationContext.taskStatus` 直接置为 `successful`,任务管理器得到这个消息后会执行 `tasks` 中的下一个任务。 + +```yaml +# ... +spec: + type: skip + targetKind: OBCluster + targetResName: test +``` \ No newline at end of file diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/900.appendix/_category_.yml b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/900.appendix/_category_.yml new file mode 100644 index 000000000..18cca9025 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/900.appendix/_category_.yml @@ -0,0 +1,3 @@ +position: 7 +link: + type: generated-index \ No newline at end of file diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/999.changelog.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/999.changelog.md new file mode 100644 index 000000000..de95b0568 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-docs/current/manual/999.changelog.md @@ -0,0 +1,81 @@ +# 变更日志 + +## 2.2.0 + +### 新增特性 + +1. 支持通过创建 `service` 模式的集群,在不依赖特定的 CNI 插件的情况下保持 OBServer 的通信 IP 地址不变 +2. 支持使用 CRD `OBResourceRescue` 提供的`删除`、`重置`、`跳过`和`重试`操作矫正其他相关 CRD 资源的状态 +3. 支持在集群运行过程中动态扩容 PVC + +### 缺陷修复 + +1. 修复集群剩余资源不足情况下创建资源超限(CPU 和内存等)的租户时不断报错重试的问题 + +### 功能优化 + +1. 加速子资源发生变化时的资源调解过程 +2. 通过 Prometheus 标准接口暴露 Controller Manager 的监控指标 + +## 2.1.2 版本 (2024.01.24 发布) + +### 新增特性 + +1. 支持使用 `oceanbase.oceanbase.com/mode`: `standalone` 注解创建 standalone 集群 +2. 支持 standalone 模式集群的垂直扩展,调整 CPU 和 Memory 资源 +3. 支持使用 `oceanbase.oceanbase.com/single-pvc`: `true` 注解创建使用单一 PVC 挂载的节点 +4. 支持通过 `spec.serviceAccount` 字段向集群的 Pod 绑定指定的 ServiceAccount + +### 缺陷修复 + +1. 如果 ob-operator 的 Pod 重启,正在恢复的 OBServer Pod 无法正常恢复 +2. 当 OBZone 调整副本数量时,即使已经有正在删除的 OBServer,OBZone 仍会随机删除它的节点 + +### 功能优化 + +1. 优化任务管理器,增加令牌池限制最大运行中任务的数量 +2. 优化数据库连接池,使用带过期时间的 LRU 缓存数据库连接 +3. 精简集群初始化必要的用户凭证为 root,自动创建其他用户凭证 (proxyro、monitor 和 operator) +4. 精简租户所需的用户凭证,root 和 standbyro 均为选填,standbyro 若不传递,会默认创建 +5. 在创建集群的 Pod 之前等待所需镜像拉取到本地 + +## 2.1.1 版本 (2023.12.20 发布) + +### 新增特性 + +1. 支持向 `OBCluster` 资源添加 `oceanbase.oceanbase.com/independent-pvc-lifecycle` 注解使得 `OBCluster` 被删除时 PVC 得以保留 +2. `OBTenantOperation` 资源支持 `Upgrade` 操作 +3. 新建 `OBCluster` 资源时所携带的 parameters 参数将作为启动参数 `optstr` 传递给 observer 进程 + +### 缺陷修复 + +1. 显式设置 `memory_limit` 参数,修复某些容器运行时(CRI)中无法限制内存资源的问题 +2. 初始化集群时传递初始化参数,避免在集群初始化后再设置参数所需的长时间等待 + +### 功能优化 + +1. 减少初始的 `datafile_size` 参数值,使用步进的方式按需增大数据文件磁盘用量 +2. 加强资源规格校验,尤其针对 `OBCluster` 和 `OBTenant` + +## 2.1.0 版本(2023.11.20 发布) + +### 新增特性 +1. 集群配置中新增亲和性和容忍性的选项 +2. 支持从备份数据恢复出租户和创建备租户 +3. 提供 ARM 架构镜像 + +### 缺陷修复 +1. 修复 map 并发写可能出现的问题 +2. 修复租户备份过程中使用过期的数据库连接的问题 +3. 修复 OceanBase 4.2.1 SQL 语法兼容性问题 + +### 功能优化 +1. 采用回退机制优化出错任务重试过程 +2. 增加事件打印,优化日志输出 + +## 2.0.0 版本(2023.09.26 发布) + +### 新增特性 +1. 支持 OceanBase 集群的管理功能 +2. 支持 OceanBase 租户的管理功能 +3. 使用 obagent 来监控 OceanBase diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-pages/changelog.md b/docsite/i18n/zh-Hans/docusaurus-plugin-content-pages/changelog.md new file mode 100644 index 000000000..de95b0568 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-pages/changelog.md @@ -0,0 +1,81 @@ +# 变更日志 + +## 2.2.0 + +### 新增特性 + +1. 支持通过创建 `service` 模式的集群,在不依赖特定的 CNI 插件的情况下保持 OBServer 的通信 IP 地址不变 +2. 支持使用 CRD `OBResourceRescue` 提供的`删除`、`重置`、`跳过`和`重试`操作矫正其他相关 CRD 资源的状态 +3. 支持在集群运行过程中动态扩容 PVC + +### 缺陷修复 + +1. 修复集群剩余资源不足情况下创建资源超限(CPU 和内存等)的租户时不断报错重试的问题 + +### 功能优化 + +1. 加速子资源发生变化时的资源调解过程 +2. 通过 Prometheus 标准接口暴露 Controller Manager 的监控指标 + +## 2.1.2 版本 (2024.01.24 发布) + +### 新增特性 + +1. 支持使用 `oceanbase.oceanbase.com/mode`: `standalone` 注解创建 standalone 集群 +2. 支持 standalone 模式集群的垂直扩展,调整 CPU 和 Memory 资源 +3. 支持使用 `oceanbase.oceanbase.com/single-pvc`: `true` 注解创建使用单一 PVC 挂载的节点 +4. 支持通过 `spec.serviceAccount` 字段向集群的 Pod 绑定指定的 ServiceAccount + +### 缺陷修复 + +1. 如果 ob-operator 的 Pod 重启,正在恢复的 OBServer Pod 无法正常恢复 +2. 当 OBZone 调整副本数量时,即使已经有正在删除的 OBServer,OBZone 仍会随机删除它的节点 + +### 功能优化 + +1. 优化任务管理器,增加令牌池限制最大运行中任务的数量 +2. 优化数据库连接池,使用带过期时间的 LRU 缓存数据库连接 +3. 精简集群初始化必要的用户凭证为 root,自动创建其他用户凭证 (proxyro、monitor 和 operator) +4. 精简租户所需的用户凭证,root 和 standbyro 均为选填,standbyro 若不传递,会默认创建 +5. 在创建集群的 Pod 之前等待所需镜像拉取到本地 + +## 2.1.1 版本 (2023.12.20 发布) + +### 新增特性 + +1. 支持向 `OBCluster` 资源添加 `oceanbase.oceanbase.com/independent-pvc-lifecycle` 注解使得 `OBCluster` 被删除时 PVC 得以保留 +2. `OBTenantOperation` 资源支持 `Upgrade` 操作 +3. 新建 `OBCluster` 资源时所携带的 parameters 参数将作为启动参数 `optstr` 传递给 observer 进程 + +### 缺陷修复 + +1. 显式设置 `memory_limit` 参数,修复某些容器运行时(CRI)中无法限制内存资源的问题 +2. 初始化集群时传递初始化参数,避免在集群初始化后再设置参数所需的长时间等待 + +### 功能优化 + +1. 减少初始的 `datafile_size` 参数值,使用步进的方式按需增大数据文件磁盘用量 +2. 加强资源规格校验,尤其针对 `OBCluster` 和 `OBTenant` + +## 2.1.0 版本(2023.11.20 发布) + +### 新增特性 +1. 集群配置中新增亲和性和容忍性的选项 +2. 支持从备份数据恢复出租户和创建备租户 +3. 提供 ARM 架构镜像 + +### 缺陷修复 +1. 修复 map 并发写可能出现的问题 +2. 修复租户备份过程中使用过期的数据库连接的问题 +3. 修复 OceanBase 4.2.1 SQL 语法兼容性问题 + +### 功能优化 +1. 采用回退机制优化出错任务重试过程 +2. 增加事件打印,优化日志输出 + +## 2.0.0 版本(2023.09.26 发布) + +### 新增特性 +1. 支持 OceanBase 集群的管理功能 +2. 支持 OceanBase 租户的管理功能 +3. 使用 obagent 来监控 OceanBase diff --git a/docsite/i18n/zh-Hans/docusaurus-plugin-content-pages/index.mdx b/docsite/i18n/zh-Hans/docusaurus-plugin-content-pages/index.mdx new file mode 100644 index 000000000..31f94cbec --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-plugin-content-pages/index.mdx @@ -0,0 +1,211 @@ +import Link from "@docusaurus/Link"; + +# ob-operator + +ob-operator 是满足 Kubernetes Operator 扩展范式的自动化工具,可以极大简化在 Kubernetes 上部署和管理 OceanBase 集群及相关资源的过程。 + +## 快速上手 + +这部分以一个简单示例说明如何使用 ob-operator 快速部署 OceanBase 集群。 + +### 前提条件 + +开始之前请准备一套可用的 Kubernetes 集群,并且至少可以分配 2C, 10G 内存以及 100G 存储空间。 + +ob-operator 依赖 [cert-manager](https://cert-manager.io/docs/), cert-manager 的安装可以参考对应的[安装文档](https://cert-manager.io/docs/installation/),如果您无法访问官方制品托管在 `quay.io` 镜像站的镜像,可通过下面的指令安装我们转托在 `docker.io` 中的制品: + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.2_release/deploy/cert-manager.yaml +``` + +本例子中的 OceanBase 集群存储依赖 [local-path-provisioner](https://github.com/rancher/local-path-provisioner) 提供, 需要提前进行安装并确保其存储目的地有足够大的磁盘空间。 + +### 部署 ob-operator + +#### 使用 YAML 配置文件· + +通过以下命令即可在 K8s 集群中部署 ob-operator: + +* 稳定版本 + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.2_release/deploy/operator.yaml +``` + +* 开发版本 + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/master/deploy/operator.yaml +``` + +#### 使用 Helm Chart + +Helm Chart 将 ob-operator 部署的命名空间进行了参数化,可在安装 ob-operator 之前指定命名空间。 + +```shell +helm repo add ob-operator https://oceanbase.github.io/ob-operator/ +helm repo update +helm install ob-operator ob-operator/ob-operator --namespace=oceanbase-system --create-namespace --version=2.1.2 +``` + +#### 使用 terraform + +部署所需要的文件放在项目的 `deploy/terraform` 目录 + +1. 生成配置变量: +在开始部署前,需要通过以下命令来生成 `terraform.tfvars` 文件,用来记录当前 Kubernetes 集群的一些配置。 +```shell +cd deploy/terraform +./generate_k8s_cluster_tfvars.sh +``` + +2. 初始化 Terraform: +此步骤用来保证 terraform 获取到必要的 plugin 和模块来管理配置的资源,使用如下命令来进行初始化。 +``` +terraform init +``` + +3. 应用配置: +执行以下命令开始部署 ob-operator。 +``` +terraform apply +``` + +#### 验证部署结果 + +安装完成之后,可以使用以下命令验证 ob-operator 是否部署成功: + +```shell +kubectl get pod -n oceanbase-system + +# 预期的输出 +NAME READY STATUS RESTARTS AGE +oceanbase-controller-manager-86cfc8f7bf-4hfnj 2/2 Running 0 1m +``` + +### 部署 OceanBase 集群 + +创建 OceanBase 集群之前,需要先创建好若干 secret 来存储 OceanBase 中的特定用户的密码: + +```shell +kubectl create secret generic root-password --from-literal=password='root_password' +``` + +通过以下命令即可在 K8s 集群中部署 OceanBase: + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.2_release/example/quickstart/obcluster.yaml +``` + +一般初始化集群需要 2 分钟左右的时间,执行以下命令,查询集群状态,当集群状态变成 running 之后表示集群创建和初始化成功: + +```shell +kubectl get obclusters.oceanbase.oceanbase.com test + +# desired output +NAME STATUS AGE +test running 6m2s +``` + +### 连接集群 + +通过以下命令查找 observer 的 POD IP,POD 名的规则是 `${cluster_name}-${cluster_id}-${zone}-uuid`: + +```shell +kubectl get pods -o wide +``` + +通过以下命令连接: + +```shell +mysql -h{POD_IP} -P2881 -uroot -proot_password oceanbase -A -c +``` + +### OceanBase Dashboard +我们很高兴地宣布推出创新的OceanBase Kubernetes Dashboard v0.1.0初始版本,这是一款旨在改善用户在Kubernetes上管理和监控OceanBase集群体验的先进工具。作为我们持续开发与改进承诺的一部分,我们自豪地向用户提供这个首个版本,同时我们也在积极开发新功能和增强未来的更新。 + +安装 OceanBase Dashboard 非常简单, 只需要执行如下命令。 +``` +helm repo add ob-operator https://oceanbase.github.io/ob-operator/ +helm install oceanbase-dashboard ob-operator/oceanbase-dashboard --version=0.1.0 +``` + +![oceanbase-dashboard-install](/img/oceanbase-dashboard-install.jpg) + +OceanBase Dashboard 成功安装之后, 会自动创建一个 admin 用户和随机密码,可以通过如下命令查看密码。 +``` +echo $(kubectl get -n default secret oceanbase-dashboard-user-credentials -o jsonpath='{.data.admin}' | base64 -d) +``` +一个 NodePort 类型的 service 会默认创建,可以通过如下命令查看 service 的地址,然后在浏览器中打开。 +``` +kubectl get svc oceanbase-dashboard-ob-dashboard +``` +![oceanbase-dashboard-service](/img/oceanbase-dashboard-service.jpg) + +使用 admin 账号和查看到的密码登录。 +![oceanbase-dashboard-overview](/img/oceanbase-dashboard-overview.jpg) + +## 项目架构 + +ob-operator 以 kubebuilder 为基础,通过统一的资源管理器接口、全局的任务管理器实例以及解决长调度的任务流机制完成对 OceanBase 集群及相关应用的控制和管理。ob-operator 的架构大致如下图所示: + +![ob-operator 架构设计](/img/ob-operator-arch.png) + +有关架构细节可参见架构设计文档。 + +## 特性 + +ob-operator 支持 OceanBase 集群的管理、租户管理、备份恢复、故障恢复等功能,具体而言支持了以下功能: + +- [x] 集群管理:集群自举、调整集群拓扑、支持 K8s 拓扑配置、扩缩容、集群升级、修改参数 +- [x] 租户管理:创建租户、调整租户拓扑、管理资源单元、修改用户密码 +- [x] 备份恢复:向 OSS 或 NFS 目的地周期性备份数据、从 OSS 或 NFS 中恢复数据 +- [x] 物理备库:从备份中恢复出备租户、创建空备租户、备租户升主、主备切换 +- [x] 故障恢复:单节点故障恢复,IP 保持情况下的集群故障恢复 + +即将支持的功能有: + +- [ ] Dashboard:基于 ob-operator 的图形化 OceanBase 集群管理工具 +- [ ] 丰富的运维任务资源:包括但不限于针对集群和租户的轻量任务 + + +## 支持的 OceanBase 版本 + +支持 OceanBase v4.x 版本,已经验证过的有 4.1.x 和 4.2.x 版本,后续会不断支持 OceanBase 社区版的新版本。 + +暂不支持 OceanBase v3.x 版本。 + +## 环境依赖 + +ob-operator 使用 [kubebuilder](https://book.kubebuilder.io/introduction) 项目进行构建,所以开发和运行环境与其相近。 + +* 构建 ob-operator 需要 Go 1.20 版本及以上; +* 运行 ob-operator 需要 Kubernetes 集群和 kubectl 的版本在 1.18 及以上。我们在 1.23 ~ 1.25 版本的 K8s 集群上检验过 ob-operator 的运行是符合预期的。 +* 如果使用 Docker 作为集群的容器运行时,需要 Docker 17.03 及以上版本;我们的构建和运行环境使用的 Docker 版本为 18。 + +## 文档 + +- ob-operator 架构设计 +- 部署 ob-operator +- 开发手册 +- 用户手册 + +## 获取帮助 + +如果您在使用 ob-operator 时遇到任何问题,欢迎通过以下方式寻求帮助: + +- [GitHub Issue](https://github.com/oceanbase/ob-operator/issues) +- [官方网站](https://open.oceanbase.com/) +- [Slack](https://oceanbase.slack.com/archives/C053PT371S7) +- 钉钉群([二维码](/img/dingtalk-operator-users.png)) +- 微信群(请添加小助手微信,微信号: OBCE666) + +## 参与开发 + +- [提出 Issue](https://github.com/oceanbase/ob-operator/issues) +- [发起 Pull request](https://github.com/oceanbase/ob-operator/pulls) + +## 许可证 + +ob-operator 使用 [MulanPSL - 2.0](http://license.coscl.org.cn/MulanPSL2) 许可证。 +您可以免费复制及使用源代码。当您修改或分发源代码时,请遵守木兰协议。 diff --git a/docsite/i18n/zh-Hans/docusaurus-theme-classic/footer.json b/docsite/i18n/zh-Hans/docusaurus-theme-classic/footer.json new file mode 100644 index 000000000..3eddbfe5c --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-theme-classic/footer.json @@ -0,0 +1,66 @@ +{ + "link.title.Docs": { + "message": "文档", + "description": "The title of the footer links column with title=Docs in the footer" + }, + "link.title.Community": { + "message": "社区", + "description": "The title of the footer links column with title=Community in the footer" + }, + "link.title.More": { + "message": "更多", + "description": "The title of the footer links column with title=More in the footer" + }, + "link.item.label.ob-operator": { + "message": "ob-operator", + "description": "The label of footer link with label=ob-operator linking to https://github.com/oceanbase/ob-operator" + }, + "link.item.label.Tutorial": { + "message": "教程", + "description": "The label of footer link with label=Tutorial linking to docs/tutorial/intro" + }, + "link.item.label.Stack Overflow": { + "message": "Stack Overflow", + "description": "The label of footer link with label=Stack Overflow linking to https://stackoverflow.com/questions/tagged/oceanbase" + }, + "link.item.label.Slack": { + "message": "Slack", + "description": "The label of footer link with label=Slack linking to https://oceanbase.slack.com/" + }, + "link.item.label.Forum (in Chinese)": { + "message": "论坛", + "description": "The label of footer link with label=Forum (in Chinese) linking to https://ask.oceanbase.com/" + }, + "link.item.label.Blog": { + "message": "博客", + "description": "The label of footer link with label=Blog linking to /blog" + }, + "link.item.label.GitHub": { + "message": "GitHub", + "description": "The label of footer link with label=GitHub linking to https://github.com/oceanbase" + }, + "copyright": { + "message": "Copyright © 2024 OceanBase, Inc. Built with Docusaurus.", + "description": "The footer copyright" + }, + "link.title.Repos": { + "message": "代码仓库", + "description": "The title of the footer links column with title=Repos in the footer" + }, + "link.item.label.Manual": { + "message": "用户手册", + "description": "The label of footer link with label=Manual linking to /docs/manual/what-is-ob-operator" + }, + "link.item.label.Architecture": { + "message": "架构设计", + "description": "The label of footer link with label=Architecture linking to /docs/developer/arch" + }, + "link.item.label.Development": { + "message": "开发指南", + "description": "The label of footer link with label=Development linking to /docs/developer/develop-locally" + }, + "link.item.label.OceanBase CE": { + "message": "OceanBase 社区版", + "description": "The label of footer link with label=OceanBase CE linking to https://github.com/oceanbase/oceanbase" + } +} diff --git a/docsite/i18n/zh-Hans/docusaurus-theme-classic/navbar.json b/docsite/i18n/zh-Hans/docusaurus-theme-classic/navbar.json new file mode 100644 index 000000000..3b98105f7 --- /dev/null +++ b/docsite/i18n/zh-Hans/docusaurus-theme-classic/navbar.json @@ -0,0 +1,70 @@ +{ + "title": { + "message": "ob-operator", + "description": "The title in the navbar" + }, + "logo.alt": { + "message": "OceanBase Logo", + "description": "The alt text of navbar logo" + }, + "item.label.Documentations": { + "message": "文档", + "description": "Navbar item with label Documentations" + }, + "item.label.Blog": { + "message": "博客", + "description": "Navbar item with label Blog" + }, + "item.label.GitHub": { + "message": "GitHub", + "description": "Navbar item with label GitHub" + }, + "item.label.ob-operator": { + "message": "ob-operator", + "description": "Navbar item with label ob-operator" + }, + "item.label.Tutorial": { + "message": "教程", + "description": "Navbar item with label Tutorial" + }, + "item.label.API Reference": { + "message": "API 参考", + "description": "Navbar item with label API Reference" + }, + "item.label.Manual": { + "message": "用户手册", + "description": "Navbar item with label Manual" + }, + "item.label.Developers": { + "message": "开发手册", + "description": "Navbar item with label Developers" + }, + "item.label.Change log": { + "message": "更新日志", + "description": "Navbar item with label Change log" + }, + "item.label.Architecture": { + "message": "架构设计", + "description": "Navbar item with label Architecture" + }, + "item.label.Development on Laptop": { + "message": "在本地开发 ob-operator", + "description": "Navbar item with label Development on Laptop" + }, + "item.label.Deploy a Cluster on laptop": { + "message": "在本地通过 ob-operator 部署集群", + "description": "Navbar item with label Deploy a Cluster on laptop" + }, + "item.label.Development": { + "message": "如何构建", + "description": "Navbar item with label Development" + }, + "item.label.Contributing": { + "message": "贡献指南", + "description": "Navbar item with label Contributing" + }, + "item.label.Developer": { + "message": "开发手册", + "description": "Navbar item with label Developer" + } +} diff --git a/docsite/package.json b/docsite/package.json new file mode 100644 index 000000000..cd2c2cf91 --- /dev/null +++ b/docsite/package.json @@ -0,0 +1,47 @@ +{ + "name": "docsite", + "version": "0.0.0", + "private": true, + "scripts": { + "docusaurus": "docusaurus", + "start": "docusaurus start", + "build": "docusaurus build", + "swizzle": "docusaurus swizzle", + "deploy": "docusaurus deploy", + "clear": "docusaurus clear", + "serve": "docusaurus serve", + "write-translations": "docusaurus write-translations", + "write-heading-ids": "docusaurus write-heading-ids", + "typecheck": "tsc" + }, + "dependencies": { + "@docusaurus/core": "3.1.1", + "@docusaurus/preset-classic": "3.1.1", + "@mdx-js/react": "^3.0.0", + "clsx": "^2.0.0", + "prism-react-renderer": "^2.3.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "devDependencies": { + "@docusaurus/module-type-aliases": "3.1.1", + "@docusaurus/tsconfig": "3.1.1", + "@docusaurus/types": "3.1.1", + "typescript": "~5.2.2" + }, + "browserslist": { + "production": [ + ">0.5%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 3 chrome version", + "last 3 firefox version", + "last 5 safari version" + ] + }, + "engines": { + "node": ">=18.0" + } +} diff --git a/docsite/sidebars.ts b/docsite/sidebars.ts new file mode 100644 index 000000000..0eb11ce4a --- /dev/null +++ b/docsite/sidebars.ts @@ -0,0 +1,31 @@ +import type { SidebarsConfig } from '@docusaurus/plugin-content-docs' + +/** + * Creating a sidebar enables you to: + - create an ordered group of docs + - render a sidebar for each doc of that group + - provide next/previous navigation + + The sidebars can be generated from the filesystem, or explicitly defined here. + + Create as many sidebars as you want. + */ +const sidebars: SidebarsConfig = { + // By default, Docusaurus generates a sidebar from the docs folder structure + manualSidebar: [{ type: 'autogenerated', dirName: 'manual' }], + developerSidebar: [{ type: 'autogenerated', dirName: 'developer' }], + // But you can create a sidebar manually + /* + tutorialSidebar: [ + 'intro', + 'hello', + { + type: 'category', + label: 'Tutorial', + items: ['tutorial-basics/create-a-document'], + }, + ], + */ +} + +export default sidebars diff --git a/docsite/src/css/custom.css b/docsite/src/css/custom.css new file mode 100644 index 000000000..793a70298 --- /dev/null +++ b/docsite/src/css/custom.css @@ -0,0 +1,70 @@ +/** + * Any CSS included here will be global. The classic template + * bundles Infima by default. Infima is a CSS framework designed to + * work well for content-centric websites. + */ + +/* You can override the default Infima variables here. */ +:root { + --ifm-color-primary: #3a80f7; + --ifm-color-primary-dark: #2a75f6; + --ifm-color-primary-darker: #196bf6; + --ifm-color-primary-darkest: #0a61f4; + --ifm-color-primary-light: #4a8bf8; + --ifm-color-primary-lighter: #5b95f8; + --ifm-color-primary-lightest: #6ba0f9; + --ifm-code-font-size: 95%; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); +} + +/* For readability concerns, you should choose a lighter palette in dark mode. */ +[data-theme='dark'] { + --ifm-color-primary: #6ba0f9; + --ifm-color-primary-dark: #5b95f8; + --ifm-color-primary-darker: #4a8bf8; + --ifm-color-primary-darkest: #3a80f7; + --ifm-color-primary-light: #7baafa; + --ifm-color-primary-lighter: #8cb5fa; + --ifm-color-primary-lightest: #9cbffb; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); +} + +[data-theme='light'] .DocSearch { + /* --docsearch-primary-color: var(--ifm-color-primary); */ + /* --docsearch-text-color: var(--ifm-font-color-base); */ + --docsearch-muted-color: var(--ifm-color-secondary-darkest); + --docsearch-container-background: rgba(94, 100, 112, 0.7); + /* Modal */ + --docsearch-modal-background: var(--ifm-color-secondary-lighter); + /* Search box */ + --docsearch-searchbox-background: var(--ifm-color-secondary); + --docsearch-searchbox-focus-background: var(--ifm-color-white); + /* Hit */ + --docsearch-hit-color: var(--ifm-font-color-base); + --docsearch-hit-active-color: var(--ifm-color-white); + --docsearch-hit-background: var(--ifm-color-white); + /* Footer */ + --docsearch-footer-background: var(--ifm-color-white); +} + +[data-theme='dark'] .DocSearch { + --docsearch-text-color: var(--ifm-font-color-base); + --docsearch-muted-color: var(--ifm-color-secondary-darkest); + --docsearch-container-background: rgba(47, 55, 69, 0.7); + /* Modal */ + --docsearch-modal-background: var(--ifm-background-color); + /* Search box */ + --docsearch-searchbox-background: var(--ifm-background-color); + --docsearch-searchbox-focus-background: var(--ifm-color-black); + /* Hit */ + --docsearch-hit-color: var(--ifm-font-color-base); + --docsearch-hit-active-color: var(--ifm-color-white); + --docsearch-hit-background: var(--ifm-color-emphasis-100); + /* Footer */ + --docsearch-footer-background: var(--ifm-background-surface-color); + --docsearch-key-gradient: linear-gradient( + -26.5deg, + var(--ifm-color-emphasis-200) 0%, + var(--ifm-color-emphasis-100) 100% + ); +} \ No newline at end of file diff --git a/docsite/src/pages/changelog.md b/docsite/src/pages/changelog.md new file mode 100644 index 000000000..3f9d97f31 --- /dev/null +++ b/docsite/src/pages/changelog.md @@ -0,0 +1,81 @@ +# Changelog + +## 2.2.0 + +### New features + +1. Support for binding static IP address of observer without depending on certain CNI by introducing the `service` mode of OBCluster. +2. Support for correcting `Status` of OceanBase related resources using `delete`, `reset`, `skip` and `retry` operations offered by CRD `OBResourceRescue`. +3. Support for expanding PVCs dynamically when the OBCluster is running. + +### Bug fixes + +1. Fixed infinite retry when creating a tenant that requires resource (CPU, Memory etc.) more than available. + +### Optimization + +1. Accelerated reconciliation when sub resource changes. +2. Exposed metrics of controller manager through prometheus standard interface. + +## 2.1.2 (Released on 2024.01.24) + +### New features + +1. Support for creating OceanBase clusters in standalone mode by adding annotation `"oceanbase.oceanbase.com/mode": "standalone"`. +2. Support for scaling cluster's resources (CPU and Memory) in place in standalone mode. +3. Support for binding single PVC with pods by setting annotation `"oceanbase.oceanbase.com/single-pvc": "true"`. +4. Support for binding a service account with pods by configuring `spec.serviceAccount` for OBCluster. + +### Bug fixes + +1. Fixed unexpected behavior when ob-operator restarts during observer recovery. +2. Avoided random deletion of OBServer when modifying OBZone replicas. + +### Optimization + +1. Optimized task manager by adding token pool to limit maximum number of concurrent running tasks. +2. Optimized database connection pool by replacing `sync.Map` with expirable LRU cache. +3. Reduced required user credentials to create OBCluster. Automatically create credentials for user `proxyro`, `monitor` and `operator` if not specified. +4. Reduced required user credentials to create OBTenant. Automatically create credentials for user `root` and `standbyro` if not specified. +5. Ensured the deploying image is ready before the OceanBase cluster is actually created. + +## 2.1.1 (Released on 2023.12.20) + +### New features + +1. Support for adding annotation `oceanbase.oceanbase.com/independent-pvc-lifecycle` to the `OBCluster` resource to make PVC remain after the `OBCluster` resource is deleted. +2. Support for tenant upgrade with the `OBTenantOperation` resource, which is a feature introduced since OceanBase Database V4.1. +3. Support for setting cluster parameters with `optstr` in startup command of `observer`. + +### Bug fixes + +1. Fixed the issue of unrestricted memory consumption in some container runtimes by explicitly setting the `memory_limit` parameter. +2. Avoided long waits for changes to take effect when parameters are altered after cluster bootstraps by setting these parameters during startup. + +### Optimization + +1. Reduced initial value of `datafile_size` and use incremental step to scale up when needed. +2. Enhanced resource validation, especially for `OBCluster` and `OBTenant` resources. + +## 2.1.0 (Released on 2023.11.20) + +### New features +1. Added toleration and affinity options to cluster parameters. +2. Support for restoring tenant and creating standby tenant from backup data. +3. The ARM image is now provided. + +### Bug fixes +1. Fixed issues that may be caused by concurrent writes to map. +2. Fixed the issue where expired database connections were used during tenant backup. +3. Fixed the issue of SQL syntax compatibility with OceanBase Database 4.2.1. + +### Optimization +1. Optimized failed task retry with backoff. +2. Added event logging and improved log outputs. + +## 2.0.0 (Released on 2023.09.26) + +### New features +1. Support OceanBase Cluster management. +2. Support Oceanbase Tenant management. +3. Support for monitoring OceanBase database with OBAgent. diff --git a/docsite/src/pages/index.mdx b/docsite/src/pages/index.mdx new file mode 100644 index 000000000..942dc16c8 --- /dev/null +++ b/docsite/src/pages/index.mdx @@ -0,0 +1,211 @@ +import Link from "@docusaurus/Link"; + +# ob-operator + +The ob-operator is a Kubernetes operator that simplifies the deployment and management of OceanBase cluster and related resources on Kubernetes. + +## Quick Start + +This section provides a step-by-step guide on how to use ob-operator to deploy an OceanBase cluster. + +### Prerequisites + +Before getting started, please ensure you have a functional Kubernetes cluster with at least 2 CPU cores, 10GB of memory, and 100GB of storage space available. + +ob-operator relies on [cert-manager](https://cert-manager.io/docs/) for certificate management. For instructions on installing cert-manager, please refer to the corresponding [installation](https://cert-manager.io/docs/installation/) documentation. +If you have trouble accessing `quay.io` image registry, our mirrored cert-manager manifests can be applied through following command: + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.2_release/deploy/cert-manager.yaml +``` + +Storage of OceanBase cluster in this example relies on [local-path-provisioner](https://github.com/rancher/local-path-provisioner), which should be installed beforehand. You should confirm that there is enough disk space in storage destination of local-path-provisioner. + +### Deploy ob-operator + +#### Using YAML configuration file + +You can deploy ob-operator in a Kubernetes cluster by executing the following command: + +* Stable + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.2_release/deploy/operator.yaml +``` + +* Development + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/master/deploy/operator.yaml +``` + +#### Using Helm chart + +Helm Chart parameterizes the namespace in which ob-operator is deployed, allowing you to specify the namespace before installing ob-operator. + +```shell +helm repo add ob-operator https://oceanbase.github.io/ob-operator/ +helm repo update +helm install ob-operator ob-operator/ob-operator --namespace=oceanbase-system --create-namespace --version=2.1.2 +``` + +#### Using terraform + +The required configuration files are conveniently located within the `deploy/terraform` directory of our repository. + +1. Generate Configuration Variables: +To begin, you'll need to generate a `terraform.tfvars` file, which will hold the configuration specifics of your Kubernetes cluster. Use the following commands to create this file. +```shell +cd deploy/terraform +./generate_k8s_cluster_tfvars.sh +``` + +2. Initialize Terraform: +This step will ensure that Terraform has all the necessary plugins and modules to manage the resources. Use the following command to initialize the terraform environment. +``` +terraform init +``` + +3. Apply Configuration: +The final step is to deploy ob-operator. Execute the following command and Terraform will begin the deployment process +``` +terraform apply +``` + +#### Verify deployment + +After deployment/installation is complete, you can use the following command to verify if ob-operator is deployed successfully: + +```shell +kubectl get pod -n oceanbase-system + +# desired output +NAME READY STATUS RESTARTS AGE +oceanbase-controller-manager-86cfc8f7bf-4hfnj 2/2 Running 0 1m +``` + +### Deploy OceanBase Cluster + +Before creating an OceanBase cluster, you need to create necessary secret to store specific user's password for OceanBase. + +```shell +kubectl create secret generic root-password --from-literal=password='root_password' +``` + +You can deploy OceanBase in a Kubernetes cluster by executing the following command: + +```shell +kubectl apply -f https://raw.githubusercontent.com/oceanbase/ob-operator/2.1.2_release/example/quickstart/obcluster.yaml +``` + +It generally takes around 2 minutes to bootstrap a cluster. Execute the following command to check the status of the cluster. Once the cluster status changes to "running," it indicates that the cluster has been successfully created and bootstrapped: + +```shell +kubectl get obclusters.oceanbase.oceanbase.com test + +# desired output +NAME STATUS AGE +test running 6m2s +``` + +### Connecting to the OceanBase Cluster + +Use the following command to find the POD IP of the observer. The naming convention for PODs is `${cluster_name}-${cluster_id}-${zone}-uuid`: + +```shell +kubectl get pods -o wide +``` + +To connect, use the following command: + +```shell +mysql -h{POD_IP} -P2881 -uroot -proot_password oceanbase -A -c +``` + +### OceanBase Dashboard +We are excited to unveil the initial release of our innovative OceanBase Kubernetes Dashboard v0.1.0, a pioneering tool designed to enhance your experience with managing and monitoring OceanBase clusters on Kubernetes. As part of our ongoing commitment to development and improvement, we are proud to offer this first version to our users while actively working on new features and enhancements for future updates. + +Deploy OceanBase Dashboard is pretty simple, just run the following commands +``` +helm repo add ob-operator https://oceanbase.github.io/ob-operator/ +helm install oceanbase-dashboard ob-operator/oceanbase-dashboard --version=0.1.0 +``` + +![oceanbase-dashboard-install](/img/oceanbase-dashboard-install.jpg) + +After OceanBase Dashboard is successfully installed, a default user admin is created with a random password, you can check the password using the command printed after installation. +``` +echo $(kubectl get -n default secret oceanbase-dashboard-user-credentials -o jsonpath='{.data.admin}' | base64 -d) +``` +A service of type NodePort is created by default, you can check the address and port and open it in browser +``` +kubectl get svc oceanbase-dashboard-ob-dashboard +``` +![oceanbase-dashboard-service](/img/oceanbase-dashboard-service.jpg) + +Login with admin user and password +![oceanbase-dashboard-overview](/img/oceanbase-dashboard-overview.jpg) + +## Project Architecture + +ob-operator is built on top of kubebuilder and provides control and management of OceanBase clusters and related applications through a unified resource manager interface, a global task manager instance, and a task flow mechanism for handling long-running tasks. The architecture diagram is approximately as follows: + +![ob-operator Architecture](/img/ob-operator-arch.png) + +For more detailed information about the architecture, please refer to the Architecture Document. + + +## Features + +It provides various functionalities for managing OceanBase clusters, tenants, backup and recovery, and fault recovery. Specifically, ob-operator supports the following features: + +- [x] Cluster Management: Bootstrap the cluster, adjust cluster topology, support K8s topology configuration, scale-in/out, cluster upgrade, modify parameters. +- [x] Tenant Management: Create tenants, adjust tenant topology, manage resource units, modify user passwords. +- [x] Backup and Recovery: Periodically backup data to OSS or NFS destinations, restore data from OSS or NFS. +- [x] Physical Standby: Restore standby tenant from backup, create empty standby tenant, activate standby tenant to primary, primary-standby switchover. +- [x] Fault Recovery: Single node fault recovery, cluster-wide fault recovery with IP preservation. + +The upcoming features include: + +- [ ] Dashboard: A web-based graphical management tool for OceanBase clusters based on ob-operator. +- [ ] Enhanced operational task resources: This includes lightweight tasks focused on cluster and tenant management, among other features. + +## Supported OceanBase Versions + +ob-operator supports OceanBase v4.x versions. The validated versions include 4.1.x and 4.2.x. It will continue to support new versions of the OceanBase community edition. + +OceanBase v3.x versions are currently not supported by ob-operator. + +## Development requirements + +ob-operator is built using the [kubebuilder](https://book.kubebuilder.io/introduction) project, so the development and runtime environment are similar to it. + +* To build ob-operator: Go version 1.20 or higher is required. +* To run ob-operator: Kubernetes cluster and kubectl version 1.18 or higher are required. We examined the functionalities on k8s cluster of version from 1.23 ~ 1.25 and ob-operator performs well. +* If using Docker as the container runtime for the cluster, Docker version 17.03 or higher is required. We tested building and running ob-operator with Docker 18. + +## Documents + +- Architecture +- Contributor Guidance +- User Manual + +## Getting Help + +If you encounter any issues while using ob-operator, please feel free to seek help through the following channels: + +- [GitHub Issue](https://github.com/oceanbase/ob-operator/issues) +- [Official Website](https://open.oceanbase.com/) +- [Slack](https://oceanbase.slack.com/archives/C053PT371S7) +- DingTalk Group ([QRCode](/img/dingtalk-operator-users.png)) +- WeChat Group (Add the assistant with WeChat ID: OBCE666) + +## Contributing + +- [Submit an issue](https://github.com/oceanbase/ob-operator/issues) +- [Create a Pull request](https://github.com/oceanbase/ob-operator/pulls) + +## License + +ob-operator is licensed under the [MulanPSL - 2.0](http://license.coscl.org.cn/MulanPSL2) License. +You are free to copy and use the source code. When you modify or distribute the source code, please comply with the MulanPSL - 2.0 Agreement. diff --git a/docsite/static/.nojekyll b/docsite/static/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/docs/img/controller-manager.jpg b/docsite/static/img/controller-manager.jpg similarity index 100% rename from docs/img/controller-manager.jpg rename to docsite/static/img/controller-manager.jpg diff --git a/docs/img/crd.jpg b/docsite/static/img/crd.jpg similarity index 100% rename from docs/img/crd.jpg rename to docsite/static/img/crd.jpg diff --git a/docs/img/debug-in-vscode.png b/docsite/static/img/debug-in-vscode.png similarity index 100% rename from docs/img/debug-in-vscode.png rename to docsite/static/img/debug-in-vscode.png diff --git a/docs/img/dingtalk-operator-users.png b/docsite/static/img/dingtalk-operator-users.png similarity index 100% rename from docs/img/dingtalk-operator-users.png rename to docsite/static/img/dingtalk-operator-users.png diff --git a/docs/img/docker-limit.png b/docsite/static/img/docker-limit.png similarity index 100% rename from docs/img/docker-limit.png rename to docsite/static/img/docker-limit.png diff --git a/docsite/static/img/favicon.ico b/docsite/static/img/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..9f938fad4b1d3d24fb4fa18feeb277d469e3ccb8 GIT binary patch literal 3465 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 mOSF3MV)_UFVwO}i-!OIR_$G* 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 d4**geJWS+<<@-rAw188VDU! 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

X*8kWVlt}1T`+dEx%H;>`iUdW+8PBo? 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

XKF{42)rd){nnxS4~QI( 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 R|FB)^UqjLV$LIId{{TwDTk!w@ literal 0 HcmV?d00001 diff --git a/index.yaml b/docsite/static/index.yaml similarity index 74% rename from index.yaml rename to docsite/static/index.yaml index dd31ecd46..2638f3ab8 100644 --- a/index.yaml +++ b/docsite/static/index.yaml @@ -1,6 +1,16 @@ apiVersion: v1 entries: ob-operator: + - apiVersion: v2 + appVersion: 2.2.0 + created: "2024-03-28T08:47:56.597224238Z" + description: A Helm chart for OB-Operator + digest: 23f9e51a404dc8e09191cb88a3d665a29de56e646505d403df1b41a01c1f3ca6 + name: ob-operator + type: application + urls: + - https://github.com/oceanbase/ob-operator/releases/download/ob-operator-2.2.0/ob-operator-2.2.0.tgz + version: 2.2.0 - apiVersion: v2 appVersion: 2.1.2 created: "2024-01-24T03:59:06.855558948Z" @@ -42,6 +52,16 @@ entries: - https://github.com/oceanbase/ob-operator/releases/download/ob-operator-2.0.0/ob-operator-2.0.0.tgz version: 2.0.0 oceanbase-cluster: + - apiVersion: v2 + appVersion: 4.2.1.3-103000032023122818 + created: "2024-01-25T12:05:34.76551464Z" + description: A Helm chart for Kubernetes to deploy OceanBase cluster + digest: d21dac3c709f9115475b795c3c801a147995b7b0a5a84c0f0171a72124eff767 + name: oceanbase-cluster + type: application + urls: + - https://github.com/oceanbase/ob-operator/releases/download/oceanbase-cluster-4.2.1-sp.3-103000032023122818/oceanbase-cluster-4.2.1-sp.3-103000032023122818.tgz + version: 4.2.1-sp.3-103000032023122818 - apiVersion: v2 appVersion: 4.2.1.1-101010012023111012 created: "2024-01-24T03:59:06.977930147Z" diff --git a/docsite/tsconfig.json b/docsite/tsconfig.json new file mode 100644 index 000000000..314eab8a4 --- /dev/null +++ b/docsite/tsconfig.json @@ -0,0 +1,7 @@ +{ + // This file is not used in compilation. It is here just for a nice editor experience. + "extends": "@docusaurus/tsconfig", + "compilerOptions": { + "baseUrl": "." + } +} diff --git a/docsite/yarn.lock b/docsite/yarn.lock new file mode 100644 index 000000000..531c24734 --- /dev/null +++ b/docsite/yarn.lock @@ -0,0 +1,8385 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@algolia/autocomplete-core@1.9.3": + version "1.9.3" + resolved "https://registry.npmmirror.com/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz#1d56482a768c33aae0868c8533049e02e8961be7" + integrity sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw== + dependencies: + "@algolia/autocomplete-plugin-algolia-insights" "1.9.3" + "@algolia/autocomplete-shared" "1.9.3" + +"@algolia/autocomplete-plugin-algolia-insights@1.9.3": + version "1.9.3" + resolved "https://registry.npmmirror.com/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz#9b7f8641052c8ead6d66c1623d444cbe19dde587" + integrity sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg== + dependencies: + "@algolia/autocomplete-shared" "1.9.3" + +"@algolia/autocomplete-preset-algolia@1.9.3": + version "1.9.3" + resolved "https://registry.npmmirror.com/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz#64cca4a4304cfcad2cf730e83067e0c1b2f485da" + integrity sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA== + dependencies: + "@algolia/autocomplete-shared" "1.9.3" + +"@algolia/autocomplete-shared@1.9.3": + version "1.9.3" + resolved "https://registry.npmmirror.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz#2e22e830d36f0a9cf2c0ccd3c7f6d59435b77dfa" + integrity sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ== + +"@algolia/cache-browser-local-storage@4.23.2": + version "4.23.2" + resolved "https://registry.npmmirror.com/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.23.2.tgz#060d15e89588fcac18e73643201fce0f4f7d5ca0" + integrity sha512-PvRQdCmtiU22dw9ZcTJkrVKgNBVAxKgD0/cfiqyxhA5+PHzA2WDt6jOmZ9QASkeM2BpyzClJb/Wr1yt2/t78Kw== + dependencies: + "@algolia/cache-common" "4.23.2" + +"@algolia/cache-common@4.23.2": + version "4.23.2" + resolved "https://registry.npmmirror.com/@algolia/cache-common/-/cache-common-4.23.2.tgz#c68706ce34b18377e56e71ac13cce2dd5662dcee" + integrity sha512-OUK/6mqr6CQWxzl/QY0/mwhlGvS6fMtvEPyn/7AHUx96NjqDA4X4+Ju7aXFQKh+m3jW9VPB0B9xvEQgyAnRPNw== + +"@algolia/cache-in-memory@4.23.2": + version "4.23.2" + resolved "https://registry.npmmirror.com/@algolia/cache-in-memory/-/cache-in-memory-4.23.2.tgz#94cd828275d7a12186959bf1b95a13247e103b23" + integrity sha512-rfbi/SnhEa3MmlqQvgYz/9NNJ156NkU6xFxjbxBtLWnHbpj+qnlMoKd+amoiacHRITpajg6zYbLM9dnaD3Bczw== + dependencies: + "@algolia/cache-common" "4.23.2" + +"@algolia/client-account@4.23.2": + version "4.23.2" + resolved "https://registry.npmmirror.com/@algolia/client-account/-/client-account-4.23.2.tgz#b53cb14e730fd8e0a0a227cf650b287b570a08bc" + integrity sha512-VbrOCLIN/5I7iIdskSoSw3uOUPF516k4SjDD4Qz3BFwa3of7D9A0lzBMAvQEJJEPHWdVraBJlGgdJq/ttmquJQ== + dependencies: + "@algolia/client-common" "4.23.2" + "@algolia/client-search" "4.23.2" + "@algolia/transporter" "4.23.2" + +"@algolia/client-analytics@4.23.2": + version "4.23.2" + resolved "https://registry.npmmirror.com/@algolia/client-analytics/-/client-analytics-4.23.2.tgz#7fdcf1cb27f0ae93e5da6beb4e612fc06a880b0c" + integrity sha512-lLj7irsAztGhMoEx/SwKd1cwLY6Daf1Q5f2AOsZacpppSvuFvuBrmkzT7pap1OD/OePjLKxicJS8wNA0+zKtuw== + dependencies: + "@algolia/client-common" "4.23.2" + "@algolia/client-search" "4.23.2" + "@algolia/requester-common" "4.23.2" + "@algolia/transporter" "4.23.2" + +"@algolia/client-common@4.23.2": + version "4.23.2" + resolved "https://registry.npmmirror.com/@algolia/client-common/-/client-common-4.23.2.tgz#e5f86fc2de707eb6bf9f1109b70187dae179c72c" + integrity sha512-Q2K1FRJBern8kIfZ0EqPvUr3V29ICxCm/q42zInV+VJRjldAD9oTsMGwqUQ26GFMdFYmqkEfCbY4VGAiQhh22g== + dependencies: + "@algolia/requester-common" "4.23.2" + "@algolia/transporter" "4.23.2" + +"@algolia/client-personalization@4.23.2": + version "4.23.2" + resolved "https://registry.npmmirror.com/@algolia/client-personalization/-/client-personalization-4.23.2.tgz#0472d9c207402eefcc9c98f7ffba5d26fe8e2fd0" + integrity sha512-vwPsgnCGhUcHhhQG5IM27z8q7dWrN9itjdvgA6uKf2e9r7vB+WXt4OocK0CeoYQt3OGEAExryzsB8DWqdMK5wg== + dependencies: + "@algolia/client-common" "4.23.2" + "@algolia/requester-common" "4.23.2" + "@algolia/transporter" "4.23.2" + +"@algolia/client-search@4.23.2": + version "4.23.2" + resolved "https://registry.npmmirror.com/@algolia/client-search/-/client-search-4.23.2.tgz#9b2741f0a209596459f06a44583118207ea287f7" + integrity sha512-CxSB29OVGSE7l/iyoHvamMonzq7Ev8lnk/OkzleODZ1iBcCs3JC/XgTIKzN/4RSTrJ9QybsnlrN/bYCGufo7qw== + dependencies: + "@algolia/client-common" "4.23.2" + "@algolia/requester-common" "4.23.2" + "@algolia/transporter" "4.23.2" + +"@algolia/events@^4.0.1": + version "4.0.1" + resolved "https://registry.npmmirror.com/@algolia/events/-/events-4.0.1.tgz#fd39e7477e7bc703d7f893b556f676c032af3950" + integrity sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ== + +"@algolia/logger-common@4.23.2": + version "4.23.2" + resolved "https://registry.npmmirror.com/@algolia/logger-common/-/logger-common-4.23.2.tgz#5441a828f0fad1ceaae3a27caec7b663d40dd27f" + integrity sha512-jGM49Q7626cXZ7qRAWXn0jDlzvoA1FvN4rKTi1g0hxKsTTSReyYk0i1ADWjChDPl3Q+nSDhJuosM2bBUAay7xw== + +"@algolia/logger-console@4.23.2": + version "4.23.2" + resolved "https://registry.npmmirror.com/@algolia/logger-console/-/logger-console-4.23.2.tgz#fda4252bb02df7c52a92c63f1e357bf7370cc8db" + integrity sha512-oo+lnxxEmlhTBTFZ3fGz1O8PJ+G+8FiAoMY2Qo3Q4w23xocQev6KqDTA1JQAGPDxAewNA2VBwWOsVXeXFjrI/Q== + dependencies: + "@algolia/logger-common" "4.23.2" + +"@algolia/recommend@4.23.2": + version "4.23.2" + resolved "https://registry.npmmirror.com/@algolia/recommend/-/recommend-4.23.2.tgz#02bf57f836ced2c850633239d493a0414be76a7f" + integrity sha512-Q75CjnzRCDzgIlgWfPnkLtrfF4t82JCirhalXkSSwe/c1GH5pWh4xUyDOR3KTMo+YxxX3zTlrL/FjHmUJEWEcg== + dependencies: + "@algolia/cache-browser-local-storage" "4.23.2" + "@algolia/cache-common" "4.23.2" + "@algolia/cache-in-memory" "4.23.2" + "@algolia/client-common" "4.23.2" + "@algolia/client-search" "4.23.2" + "@algolia/logger-common" "4.23.2" + "@algolia/logger-console" "4.23.2" + "@algolia/requester-browser-xhr" "4.23.2" + "@algolia/requester-common" "4.23.2" + "@algolia/requester-node-http" "4.23.2" + "@algolia/transporter" "4.23.2" + +"@algolia/requester-browser-xhr@4.23.2": + version "4.23.2" + resolved "https://registry.npmmirror.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.23.2.tgz#2d0a6b642e2a2bbfb2e2ff3d1e82158e3e143def" + integrity sha512-TO9wLlp8+rvW9LnIfyHsu8mNAMYrqNdQ0oLF6eTWFxXfxG3k8F/Bh7nFYGk2rFAYty4Fw4XUtrv/YjeNDtM5og== + dependencies: + "@algolia/requester-common" "4.23.2" + +"@algolia/requester-common@4.23.2": + version "4.23.2" + resolved "https://registry.npmmirror.com/@algolia/requester-common/-/requester-common-4.23.2.tgz#9c2e5da4dc15e65f9b9bbe5bedb419cf23092ef1" + integrity sha512-3EfpBS0Hri0lGDB5H/BocLt7Vkop0bTTLVUBB844HH6tVycwShmsV6bDR7yXbQvFP1uNpgePRD3cdBCjeHmk6Q== + +"@algolia/requester-node-http@4.23.2": + version "4.23.2" + resolved "https://registry.npmmirror.com/@algolia/requester-node-http/-/requester-node-http-4.23.2.tgz#718ae71f58949eab3b5fcfc440be42af41bd640f" + integrity sha512-SVzgkZM/malo+2SB0NWDXpnT7nO5IZwuDTaaH6SjLeOHcya1o56LSWXk+3F3rNLz2GVH+I/rpYKiqmHhSOjerw== + dependencies: + "@algolia/requester-common" "4.23.2" + +"@algolia/transporter@4.23.2": + version "4.23.2" + resolved "https://registry.npmmirror.com/@algolia/transporter/-/transporter-4.23.2.tgz#61e7b9288d4f561b2015ddde689ba31e08c21644" + integrity sha512-GY3aGKBy+8AK4vZh8sfkatDciDVKad5rTY2S10Aefyjh7e7UGBP4zigf42qVXwU8VOPwi7l/L7OACGMOFcjB0Q== + dependencies: + "@algolia/cache-common" "4.23.2" + "@algolia/logger-common" "4.23.2" + "@algolia/requester-common" "4.23.2" + +"@ampproject/remapping@^2.2.0": + version "2.3.0" + resolved "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" + integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.24" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.23.5", "@babel/code-frame@^7.24.1", "@babel/code-frame@^7.24.2", "@babel/code-frame@^7.8.3": + version "7.24.2" + resolved "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.24.2.tgz#718b4b19841809a58b29b68cde80bc5e1aa6d9ae" + integrity sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ== + dependencies: + "@babel/highlight" "^7.24.2" + picocolors "^1.0.0" + +"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.23.5", "@babel/compat-data@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.24.1.tgz#31c1f66435f2a9c329bb5716a6d6186c516c3742" + integrity sha512-Pc65opHDliVpRHuKfzI+gSA4zcgr65O4cl64fFJIWEEh8JoHIHh0Oez1Eo8Arz8zq/JhgKodQaxEwUPRtZylVA== + +"@babel/core@^7.19.6", "@babel/core@^7.23.3": + version "7.24.3" + resolved "https://registry.npmmirror.com/@babel/core/-/core-7.24.3.tgz#568864247ea10fbd4eff04dda1e05f9e2ea985c3" + integrity sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.24.2" + "@babel/generator" "^7.24.1" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helpers" "^7.24.1" + "@babel/parser" "^7.24.1" + "@babel/template" "^7.24.0" + "@babel/traverse" "^7.24.1" + "@babel/types" "^7.24.0" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + +"@babel/generator@^7.23.3", "@babel/generator@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/generator/-/generator-7.24.1.tgz#e67e06f68568a4ebf194d1c6014235344f0476d0" + integrity sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A== + dependencies: + "@babel/types" "^7.24.0" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + jsesc "^2.5.1" + +"@babel/helper-annotate-as-pure@^7.22.5": + version "7.22.5" + resolved "https://registry.npmmirror.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882" + integrity sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.22.15": + version "7.22.15" + resolved "https://registry.npmmirror.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz#5426b109cf3ad47b91120f8328d8ab1be8b0b956" + integrity sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw== + dependencies: + "@babel/types" "^7.22.15" + +"@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.23.6": + version "7.23.6" + resolved "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz#4d79069b16cbcf1461289eccfbbd81501ae39991" + integrity sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ== + dependencies: + "@babel/compat-data" "^7.23.5" + "@babel/helper-validator-option" "^7.23.5" + browserslist "^4.22.2" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-create-class-features-plugin@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.1.tgz#db58bf57137b623b916e24874ab7188d93d7f68f" + integrity sha512-1yJa9dX9g//V6fDebXoEfEsxkZHk3Hcbm+zLhyu6qVgYFLvmTALTeV+jNU9e5RnYtioBrGEOdoI2joMSNQ/+aA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-member-expression-to-functions" "^7.23.0" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-replace-supers" "^7.24.1" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + semver "^6.3.1" + +"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.15", "@babel/helper-create-regexp-features-plugin@^7.22.5": + version "7.22.15" + resolved "https://registry.npmmirror.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz#5ee90093914ea09639b01c711db0d6775e558be1" + integrity sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + regexpu-core "^5.3.1" + semver "^6.3.1" + +"@babel/helper-define-polyfill-provider@^0.6.1": + version "0.6.1" + resolved "https://registry.npmmirror.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz#fadc63f0c2ff3c8d02ed905dcea747c5b0fb74fd" + integrity sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA== + dependencies: + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-plugin-utils" "^7.22.5" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + +"@babel/helper-environment-visitor@^7.22.20": + version "7.22.20" + resolved "https://registry.npmmirror.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== + +"@babel/helper-function-name@^7.22.5", "@babel/helper-function-name@^7.23.0": + version "7.23.0" + resolved "https://registry.npmmirror.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" + integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== + dependencies: + "@babel/template" "^7.22.15" + "@babel/types" "^7.23.0" + +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.npmmirror.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-member-expression-to-functions@^7.23.0": + version "7.23.0" + resolved "https://registry.npmmirror.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz#9263e88cc5e41d39ec18c9a3e0eced59a3e7d366" + integrity sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA== + dependencies: + "@babel/types" "^7.23.0" + +"@babel/helper-module-imports@^7.22.15", "@babel/helper-module-imports@^7.24.1", "@babel/helper-module-imports@^7.24.3": + version "7.24.3" + resolved "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz#6ac476e6d168c7c23ff3ba3cf4f7841d46ac8128" + integrity sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg== + dependencies: + "@babel/types" "^7.24.0" + +"@babel/helper-module-transforms@^7.23.3": + version "7.23.3" + resolved "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz#d7d12c3c5d30af5b3c0fcab2a6d5217773e2d0f1" + integrity sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.20" + +"@babel/helper-optimise-call-expression@^7.22.5": + version "7.22.5" + resolved "https://registry.npmmirror.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz#f21531a9ccbff644fdd156b4077c16ff0c3f609e" + integrity sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.24.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.24.0" + resolved "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz#945681931a52f15ce879fd5b86ce2dae6d3d7f2a" + integrity sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w== + +"@babel/helper-remap-async-to-generator@^7.22.20": + version "7.22.20" + resolved "https://registry.npmmirror.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz#7b68e1cb4fa964d2996fd063723fb48eca8498e0" + integrity sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-wrap-function" "^7.22.20" + +"@babel/helper-replace-supers@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz#7085bd19d4a0b7ed8f405c1ed73ccb70f323abc1" + integrity sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-member-expression-to-functions" "^7.23.0" + "@babel/helper-optimise-call-expression" "^7.22.5" + +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.npmmirror.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-skip-transparent-expression-wrappers@^7.22.5": + version "7.22.5" + resolved "https://registry.npmmirror.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz#007f15240b5751c537c40e77abb4e89eeaaa8847" + integrity sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.npmmirror.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-string-parser@^7.23.4": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz#f99c36d3593db9540705d0739a1f10b5e20c696e" + integrity sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ== + +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== + +"@babel/helper-validator-option@^7.23.5": + version "7.23.5" + resolved "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307" + integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== + +"@babel/helper-wrap-function@^7.22.20": + version "7.22.20" + resolved "https://registry.npmmirror.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz#15352b0b9bfb10fc9c76f79f6342c00e3411a569" + integrity sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw== + dependencies: + "@babel/helper-function-name" "^7.22.5" + "@babel/template" "^7.22.15" + "@babel/types" "^7.22.19" + +"@babel/helpers@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.24.1.tgz#183e44714b9eba36c3038e442516587b1e0a1a94" + integrity sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg== + dependencies: + "@babel/template" "^7.24.0" + "@babel/traverse" "^7.24.1" + "@babel/types" "^7.24.0" + +"@babel/highlight@^7.24.2": + version "7.24.2" + resolved "https://registry.npmmirror.com/@babel/highlight/-/highlight-7.24.2.tgz#3f539503efc83d3c59080a10e6634306e0370d26" + integrity sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA== + dependencies: + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" + js-tokens "^4.0.0" + picocolors "^1.0.0" + +"@babel/parser@^7.22.7", "@babel/parser@^7.24.0", "@babel/parser@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.24.1.tgz#1e416d3627393fab1cb5b0f2f1796a100ae9133a" + integrity sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg== + +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.1.tgz#b645d9ba8c2bc5b7af50f0fe949f9edbeb07c8cf" + integrity sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.1.tgz#da8261f2697f0f41b0855b91d3a20a1fbfd271d3" + integrity sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-transform-optional-chaining" "^7.24.1" + +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.1.tgz#1181d9685984c91d657b8ddf14f0487a6bab2988" + integrity sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": + version "7.21.0-placeholder-for-preset-env.2" + resolved "https://registry.npmmirror.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703" + integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w== + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.12.13": + version "7.12.13" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-class-static-block@^7.14.5": + version "7.14.5" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" + integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-export-namespace-from@^7.8.3": + version "7.8.3" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" + integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-import-assertions@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.1.tgz#db3aad724153a00eaac115a3fb898de544e34971" + integrity sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-syntax-import-attributes@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.1.tgz#c66b966c63b714c4eec508fcf5763b1f2d381093" + integrity sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-syntax-import-meta@^7.10.4": + version "7.10.4" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-jsx@^7.23.3", "@babel/plugin-syntax-jsx@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.1.tgz#3f6ca04b8c841811dbc3c5c5f837934e0d626c10" + integrity sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": + version "7.10.4" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.10.4": + version "7.10.4" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-private-property-in-object@^7.14.5": + version "7.14.5" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" + integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-top-level-await@^7.14.5": + version "7.14.5" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-typescript@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.1.tgz#b3bcc51f396d15f3591683f90239de143c076844" + integrity sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-syntax-unicode-sets-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.npmmirror.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz#d49a3b3e6b52e5be6740022317580234a6a47357" + integrity sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-arrow-functions@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.1.tgz#2bf263617060c9cc45bcdbf492b8cc805082bf27" + integrity sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-async-generator-functions@^7.24.3": + version "7.24.3" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.3.tgz#8fa7ae481b100768cc9842c8617808c5352b8b89" + integrity sha512-Qe26CMYVjpQxJ8zxM1340JFNjZaF+ISWpr1Kt/jGo+ZTUzKkfw/pphEWbRCb+lmSM6k/TOgfYLvmbHkUQ0asIg== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-remap-async-to-generator" "^7.22.20" + "@babel/plugin-syntax-async-generators" "^7.8.4" + +"@babel/plugin-transform-async-to-generator@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.1.tgz#0e220703b89f2216800ce7b1c53cb0cf521c37f4" + integrity sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw== + dependencies: + "@babel/helper-module-imports" "^7.24.1" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-remap-async-to-generator" "^7.22.20" + +"@babel/plugin-transform-block-scoped-functions@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.1.tgz#1c94799e20fcd5c4d4589523bbc57b7692979380" + integrity sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-block-scoping@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.1.tgz#27af183d7f6dad890531256c7a45019df768ac1f" + integrity sha512-h71T2QQvDgM2SmT29UYU6ozjMlAt7s7CSs5Hvy8f8cf/GM/Z4a2zMfN+fjVGaieeCrXR3EdQl6C4gQG+OgmbKw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-class-properties@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.1.tgz#bcbf1aef6ba6085cfddec9fc8d58871cf011fc29" + integrity sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.24.1" + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-class-static-block@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.1.tgz#4e37efcca1d9f2fcb908d1bae8b56b4b6e9e1cb6" + integrity sha512-FUHlKCn6J3ERiu8Dv+4eoz7w8+kFLSyeVG4vDAikwADGjUCoHw/JHokyGtr8OR4UjpwPVivyF+h8Q5iv/JmrtA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.24.1" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + +"@babel/plugin-transform-classes@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.1.tgz#5bc8fc160ed96378184bc10042af47f50884dcb1" + integrity sha512-ZTIe3W7UejJd3/3R4p7ScyyOoafetUShSf4kCqV0O7F/RiHxVj/wRaRnQlrGwflvcehNA8M42HkAiEDYZu2F1Q== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-replace-supers" "^7.24.1" + "@babel/helper-split-export-declaration" "^7.22.6" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.1.tgz#bc7e787f8e021eccfb677af5f13c29a9934ed8a7" + integrity sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/template" "^7.24.0" + +"@babel/plugin-transform-destructuring@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.1.tgz#b1e8243af4a0206841973786292b8c8dd8447345" + integrity sha512-ow8jciWqNxR3RYbSNVuF4U2Jx130nwnBnhRw6N6h1bOejNkABmcI5X5oz29K4alWX7vf1C+o6gtKXikzRKkVdw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-dotall-regex@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.1.tgz#d56913d2f12795cc9930801b84c6f8c47513ac13" + integrity sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-duplicate-keys@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.1.tgz#5347a797fe82b8d09749d10e9f5b83665adbca88" + integrity sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-dynamic-import@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.1.tgz#2a5a49959201970dd09a5fca856cb651e44439dd" + integrity sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + +"@babel/plugin-transform-exponentiation-operator@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.1.tgz#6650ebeb5bd5c012d5f5f90a26613a08162e8ba4" + integrity sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.22.15" + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-export-namespace-from@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.1.tgz#f033541fc036e3efb2dcb58eedafd4f6b8078acd" + integrity sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + +"@babel/plugin-transform-for-of@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.1.tgz#67448446b67ab6c091360ce3717e7d3a59e202fd" + integrity sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + +"@babel/plugin-transform-function-name@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.1.tgz#8cba6f7730626cc4dfe4ca2fa516215a0592b361" + integrity sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA== + dependencies: + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-json-strings@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.1.tgz#08e6369b62ab3e8a7b61089151b161180c8299f7" + integrity sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-json-strings" "^7.8.3" + +"@babel/plugin-transform-literals@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.1.tgz#0a1982297af83e6b3c94972686067df588c5c096" + integrity sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-logical-assignment-operators@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.1.tgz#719d8aded1aa94b8fb34e3a785ae8518e24cfa40" + integrity sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-transform-member-expression-literals@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.1.tgz#896d23601c92f437af8b01371ad34beb75df4489" + integrity sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-modules-amd@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.1.tgz#b6d829ed15258536977e9c7cc6437814871ffa39" + integrity sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ== + dependencies: + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-modules-commonjs@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz#e71ba1d0d69e049a22bf90b3867e263823d3f1b9" + integrity sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw== + dependencies: + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-simple-access" "^7.22.5" + +"@babel/plugin-transform-modules-systemjs@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.1.tgz#2b9625a3d4e445babac9788daec39094e6b11e3e" + integrity sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA== + dependencies: + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-validator-identifier" "^7.22.20" + +"@babel/plugin-transform-modules-umd@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.1.tgz#69220c66653a19cf2c0872b9c762b9a48b8bebef" + integrity sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg== + dependencies: + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz#67fe18ee8ce02d57c855185e27e3dc959b2e991f" + integrity sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-new-target@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.1.tgz#29c59988fa3d0157de1c871a28cd83096363cc34" + integrity sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-nullish-coalescing-operator@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.1.tgz#0cd494bb97cb07d428bd651632cb9d4140513988" + integrity sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-transform-numeric-separator@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.1.tgz#5bc019ce5b3435c1cadf37215e55e433d674d4e8" + integrity sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-transform-object-rest-spread@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.1.tgz#5a3ce73caf0e7871a02e1c31e8b473093af241ff" + integrity sha512-XjD5f0YqOtebto4HGISLNfiNMTTs6tbkFf2TOqJlYKYmbo+mN9Dnpl4SRoofiziuOWMIyq3sZEUqLo3hLITFEA== + dependencies: + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.24.1" + +"@babel/plugin-transform-object-super@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.1.tgz#e71d6ab13483cca89ed95a474f542bbfc20a0520" + integrity sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-replace-supers" "^7.24.1" + +"@babel/plugin-transform-optional-catch-binding@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.1.tgz#92a3d0efe847ba722f1a4508669b23134669e2da" + integrity sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + +"@babel/plugin-transform-optional-chaining@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.1.tgz#26e588acbedce1ab3519ac40cc748e380c5291e6" + integrity sha512-n03wmDt+987qXwAgcBlnUUivrZBPZ8z1plL0YvgQalLm+ZE5BMhGm94jhxXtA1wzv1Cu2aaOv1BM9vbVttrzSg== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +"@babel/plugin-transform-parameters@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.1.tgz#983c15d114da190506c75b616ceb0f817afcc510" + integrity sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-private-methods@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.1.tgz#a0faa1ae87eff077e1e47a5ec81c3aef383dc15a" + integrity sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.24.1" + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-private-property-in-object@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.1.tgz#756443d400274f8fb7896742962cc1b9f25c1f6a" + integrity sha512-pTHxDVa0BpUbvAgX3Gat+7cSciXqUcY9j2VZKTbSB6+VQGpNgNO9ailxTGHSXlqOnX1Hcx1Enme2+yv7VqP9bg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.24.1" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + +"@babel/plugin-transform-property-literals@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.1.tgz#d6a9aeab96f03749f4eebeb0b6ea8e90ec958825" + integrity sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-react-constant-elements@^7.18.12": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.24.1.tgz#d493a0918b9fdad7540f5afd9b5eb5c52500d18d" + integrity sha512-QXp1U9x0R7tkiGB0FOk8o74jhnap0FlZ5gNkRIWdG3eP+SvMFg118e1zaWewDzgABb106QSKpVsD3Wgd8t6ifA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-react-display-name@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.1.tgz#554e3e1a25d181f040cf698b93fd289a03bfdcdb" + integrity sha512-mvoQg2f9p2qlpDQRBC7M3c3XTr0k7cp/0+kFKKO/7Gtu0LSw16eKB+Fabe2bDT/UpsyasTBBkAnbdsLrkD5XMw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-react-jsx-development@^7.22.5": + version "7.22.5" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz#e716b6edbef972a92165cd69d92f1255f7e73e87" + integrity sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A== + dependencies: + "@babel/plugin-transform-react-jsx" "^7.22.5" + +"@babel/plugin-transform-react-jsx@^7.22.5", "@babel/plugin-transform-react-jsx@^7.23.4": + version "7.23.4" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz#393f99185110cea87184ea47bcb4a7b0c2e39312" + integrity sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-jsx" "^7.23.3" + "@babel/types" "^7.23.4" + +"@babel/plugin-transform-react-pure-annotations@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.24.1.tgz#c86bce22a53956331210d268e49a0ff06e392470" + integrity sha512-+pWEAaDJvSm9aFvJNpLiM2+ktl2Sn2U5DdyiWdZBxmLc6+xGt88dvFqsHiAiDS+8WqUwbDfkKz9jRxK3M0k+kA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-regenerator@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.1.tgz#625b7545bae52363bdc1fbbdc7252b5046409c8c" + integrity sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + regenerator-transform "^0.15.2" + +"@babel/plugin-transform-reserved-words@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.1.tgz#8de729f5ecbaaf5cf83b67de13bad38a21be57c1" + integrity sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-runtime@^7.22.9": + version "7.24.3" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.3.tgz#dc58ad4a31810a890550365cc922e1ff5acb5d7f" + integrity sha512-J0BuRPNlNqlMTRJ72eVptpt9VcInbxO6iP3jaxr+1NPhC0UkKL+6oeX6VXMEYdADnuqmMmsBspt4d5w8Y/TCbQ== + dependencies: + "@babel/helper-module-imports" "^7.24.3" + "@babel/helper-plugin-utils" "^7.24.0" + babel-plugin-polyfill-corejs2 "^0.4.10" + babel-plugin-polyfill-corejs3 "^0.10.1" + babel-plugin-polyfill-regenerator "^0.6.1" + semver "^6.3.1" + +"@babel/plugin-transform-shorthand-properties@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.1.tgz#ba9a09144cf55d35ec6b93a32253becad8ee5b55" + integrity sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-spread@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.1.tgz#a1acf9152cbf690e4da0ba10790b3ac7d2b2b391" + integrity sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + +"@babel/plugin-transform-sticky-regex@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.1.tgz#f03e672912c6e203ed8d6e0271d9c2113dc031b9" + integrity sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-template-literals@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.1.tgz#15e2166873a30d8617e3e2ccadb86643d327aab7" + integrity sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-typeof-symbol@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.1.tgz#6831f78647080dec044f7e9f68003d99424f94c7" + integrity sha512-CBfU4l/A+KruSUoW+vTQthwcAdwuqbpRNB8HQKlZABwHRhsdHZ9fezp4Sn18PeAlYxTNiLMlx4xUBV3AWfg1BA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-typescript@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.1.tgz#5c05e28bb76c7dfe7d6c5bed9951324fd2d3ab07" + integrity sha512-liYSESjX2fZ7JyBFkYG78nfvHlMKE6IpNdTVnxmlYUR+j5ZLsitFbaAE+eJSK2zPPkNWNw4mXL51rQ8WrvdK0w== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.24.1" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-typescript" "^7.24.1" + +"@babel/plugin-transform-unicode-escapes@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.1.tgz#fb3fa16676549ac7c7449db9b342614985c2a3a4" + integrity sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-unicode-property-regex@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.1.tgz#56704fd4d99da81e5e9f0c0c93cabd91dbc4889e" + integrity sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-unicode-regex@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.1.tgz#57c3c191d68f998ac46b708380c1ce4d13536385" + integrity sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-unicode-sets-regex@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.1.tgz#c1ea175b02afcffc9cf57a9c4658326625165b7f" + integrity sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/preset-env@^7.19.4", "@babel/preset-env@^7.22.9": + version "7.24.3" + resolved "https://registry.npmmirror.com/@babel/preset-env/-/preset-env-7.24.3.tgz#f3f138c844ffeeac372597b29c51b5259e8323a3" + integrity sha512-fSk430k5c2ff8536JcPvPWK4tZDwehWLGlBp0wrsBUjZVdeQV6lePbwKWZaZfK2vnh/1kQX1PzAJWsnBmVgGJA== + dependencies: + "@babel/compat-data" "^7.24.1" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-validator-option" "^7.23.5" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.24.1" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.24.1" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.24.1" + "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-import-assertions" "^7.24.1" + "@babel/plugin-syntax-import-attributes" "^7.24.1" + "@babel/plugin-syntax-import-meta" "^7.10.4" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" + "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" + "@babel/plugin-transform-arrow-functions" "^7.24.1" + "@babel/plugin-transform-async-generator-functions" "^7.24.3" + "@babel/plugin-transform-async-to-generator" "^7.24.1" + "@babel/plugin-transform-block-scoped-functions" "^7.24.1" + "@babel/plugin-transform-block-scoping" "^7.24.1" + "@babel/plugin-transform-class-properties" "^7.24.1" + "@babel/plugin-transform-class-static-block" "^7.24.1" + "@babel/plugin-transform-classes" "^7.24.1" + "@babel/plugin-transform-computed-properties" "^7.24.1" + "@babel/plugin-transform-destructuring" "^7.24.1" + "@babel/plugin-transform-dotall-regex" "^7.24.1" + "@babel/plugin-transform-duplicate-keys" "^7.24.1" + "@babel/plugin-transform-dynamic-import" "^7.24.1" + "@babel/plugin-transform-exponentiation-operator" "^7.24.1" + "@babel/plugin-transform-export-namespace-from" "^7.24.1" + "@babel/plugin-transform-for-of" "^7.24.1" + "@babel/plugin-transform-function-name" "^7.24.1" + "@babel/plugin-transform-json-strings" "^7.24.1" + "@babel/plugin-transform-literals" "^7.24.1" + "@babel/plugin-transform-logical-assignment-operators" "^7.24.1" + "@babel/plugin-transform-member-expression-literals" "^7.24.1" + "@babel/plugin-transform-modules-amd" "^7.24.1" + "@babel/plugin-transform-modules-commonjs" "^7.24.1" + "@babel/plugin-transform-modules-systemjs" "^7.24.1" + "@babel/plugin-transform-modules-umd" "^7.24.1" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.22.5" + "@babel/plugin-transform-new-target" "^7.24.1" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.24.1" + "@babel/plugin-transform-numeric-separator" "^7.24.1" + "@babel/plugin-transform-object-rest-spread" "^7.24.1" + "@babel/plugin-transform-object-super" "^7.24.1" + "@babel/plugin-transform-optional-catch-binding" "^7.24.1" + "@babel/plugin-transform-optional-chaining" "^7.24.1" + "@babel/plugin-transform-parameters" "^7.24.1" + "@babel/plugin-transform-private-methods" "^7.24.1" + "@babel/plugin-transform-private-property-in-object" "^7.24.1" + "@babel/plugin-transform-property-literals" "^7.24.1" + "@babel/plugin-transform-regenerator" "^7.24.1" + "@babel/plugin-transform-reserved-words" "^7.24.1" + "@babel/plugin-transform-shorthand-properties" "^7.24.1" + "@babel/plugin-transform-spread" "^7.24.1" + "@babel/plugin-transform-sticky-regex" "^7.24.1" + "@babel/plugin-transform-template-literals" "^7.24.1" + "@babel/plugin-transform-typeof-symbol" "^7.24.1" + "@babel/plugin-transform-unicode-escapes" "^7.24.1" + "@babel/plugin-transform-unicode-property-regex" "^7.24.1" + "@babel/plugin-transform-unicode-regex" "^7.24.1" + "@babel/plugin-transform-unicode-sets-regex" "^7.24.1" + "@babel/preset-modules" "0.1.6-no-external-plugins" + babel-plugin-polyfill-corejs2 "^0.4.10" + babel-plugin-polyfill-corejs3 "^0.10.4" + babel-plugin-polyfill-regenerator "^0.6.1" + core-js-compat "^3.31.0" + semver "^6.3.1" + +"@babel/preset-modules@0.1.6-no-external-plugins": + version "0.1.6-no-external-plugins" + resolved "https://registry.npmmirror.com/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz#ccb88a2c49c817236861fee7826080573b8a923a" + integrity sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/preset-react@^7.18.6", "@babel/preset-react@^7.22.5": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/preset-react/-/preset-react-7.24.1.tgz#2450c2ac5cc498ef6101a6ca5474de251e33aa95" + integrity sha512-eFa8up2/8cZXLIpkafhaADTXSnl7IsUFCYenRWrARBz0/qZwcT0RBXpys0LJU4+WfPoF2ZG6ew6s2V6izMCwRA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-validator-option" "^7.23.5" + "@babel/plugin-transform-react-display-name" "^7.24.1" + "@babel/plugin-transform-react-jsx" "^7.23.4" + "@babel/plugin-transform-react-jsx-development" "^7.22.5" + "@babel/plugin-transform-react-pure-annotations" "^7.24.1" + +"@babel/preset-typescript@^7.18.6", "@babel/preset-typescript@^7.22.5": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/preset-typescript/-/preset-typescript-7.24.1.tgz#89bdf13a3149a17b3b2a2c9c62547f06db8845ec" + integrity sha512-1DBaMmRDpuYQBPWD8Pf/WEwCrtgRHxsZnP4mIy9G/X+hFfbI47Q2G4t1Paakld84+qsk2fSsUPMKg71jkoOOaQ== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-validator-option" "^7.23.5" + "@babel/plugin-syntax-jsx" "^7.24.1" + "@babel/plugin-transform-modules-commonjs" "^7.24.1" + "@babel/plugin-transform-typescript" "^7.24.1" + +"@babel/regjsgen@^0.8.0": + version "0.8.0" + resolved "https://registry.npmmirror.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" + integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== + +"@babel/runtime-corejs3@^7.22.6": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/runtime-corejs3/-/runtime-corejs3-7.24.1.tgz#f39707b213441dec645ce8285ae14f281a5077c6" + integrity sha512-T9ko/35G+Bkl+win48GduaPlhSlOjjE5s1TeiEcD+QpxlLQnoEfb/nO/T+TQqkm+ipFwORn+rB8w14iJ/uD0bg== + dependencies: + core-js-pure "^3.30.2" + regenerator-runtime "^0.14.0" + +"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.22.6", "@babel/runtime@^7.8.4": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.24.1.tgz#431f9a794d173b53720e69a6464abc6f0e2a5c57" + integrity sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ== + dependencies: + regenerator-runtime "^0.14.0" + +"@babel/template@^7.22.15", "@babel/template@^7.24.0": + version "7.24.0" + resolved "https://registry.npmmirror.com/@babel/template/-/template-7.24.0.tgz#c6a524aa93a4a05d66aaf31654258fae69d87d50" + integrity sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA== + dependencies: + "@babel/code-frame" "^7.23.5" + "@babel/parser" "^7.24.0" + "@babel/types" "^7.24.0" + +"@babel/traverse@^7.22.8", "@babel/traverse@^7.24.1": + version "7.24.1" + resolved "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.24.1.tgz#d65c36ac9dd17282175d1e4a3c49d5b7988f530c" + integrity sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ== + dependencies: + "@babel/code-frame" "^7.24.1" + "@babel/generator" "^7.24.1" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.24.1" + "@babel/types" "^7.24.0" + debug "^4.3.1" + globals "^11.1.0" + +"@babel/types@^7.20.0", "@babel/types@^7.22.15", "@babel/types@^7.22.19", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.4", "@babel/types@^7.24.0", "@babel/types@^7.4.4": + version "7.24.0" + resolved "https://registry.npmmirror.com/@babel/types/-/types-7.24.0.tgz#3b951f435a92e7333eba05b7566fd297960ea1bf" + integrity sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w== + dependencies: + "@babel/helper-string-parser" "^7.23.4" + "@babel/helper-validator-identifier" "^7.22.20" + to-fast-properties "^2.0.0" + +"@colors/colors@1.5.0": + version "1.5.0" + resolved "https://registry.npmmirror.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" + integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== + +"@discoveryjs/json-ext@0.5.7": + version "0.5.7" + resolved "https://registry.npmmirror.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" + integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== + +"@docsearch/css@3.6.0": + version "3.6.0" + resolved "https://registry.npmmirror.com/@docsearch/css/-/css-3.6.0.tgz#0e9f56f704b3a34d044d15fd9962ebc1536ba4fb" + integrity sha512-+sbxb71sWre+PwDK7X2T8+bhS6clcVMLwBPznX45Qu6opJcgRjAp7gYSDzVFp187J+feSj5dNBN1mJoi6ckkUQ== + +"@docsearch/react@^3.5.2": + version "3.6.0" + resolved "https://registry.npmmirror.com/@docsearch/react/-/react-3.6.0.tgz#b4f25228ecb7fc473741aefac592121e86dd2958" + integrity sha512-HUFut4ztcVNmqy9gp/wxNbC7pTOHhgVVkHVGCACTuLhUKUhKAF9KYHJtMiLUJxEqiFLQiuri1fWF8zqwM/cu1w== + dependencies: + "@algolia/autocomplete-core" "1.9.3" + "@algolia/autocomplete-preset-algolia" "1.9.3" + "@docsearch/css" "3.6.0" + algoliasearch "^4.19.1" + +"@docusaurus/core@3.1.1": + version "3.1.1" + resolved "https://registry.npmmirror.com/@docusaurus/core/-/core-3.1.1.tgz#29ce8df7a3d3d12ee8962d6d86133b87235ff17b" + integrity sha512-2nQfKFcf+MLEM7JXsXwQxPOmQAR6ytKMZVSx7tVi9HEm9WtfwBH1fp6bn8Gj4zLUhjWKCLoysQ9/Wm+EZCQ4yQ== + dependencies: + "@babel/core" "^7.23.3" + "@babel/generator" "^7.23.3" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-transform-runtime" "^7.22.9" + "@babel/preset-env" "^7.22.9" + "@babel/preset-react" "^7.22.5" + "@babel/preset-typescript" "^7.22.5" + "@babel/runtime" "^7.22.6" + "@babel/runtime-corejs3" "^7.22.6" + "@babel/traverse" "^7.22.8" + "@docusaurus/cssnano-preset" "3.1.1" + "@docusaurus/logger" "3.1.1" + "@docusaurus/mdx-loader" "3.1.1" + "@docusaurus/react-loadable" "5.5.2" + "@docusaurus/utils" "3.1.1" + "@docusaurus/utils-common" "3.1.1" + "@docusaurus/utils-validation" "3.1.1" + "@slorber/static-site-generator-webpack-plugin" "^4.0.7" + "@svgr/webpack" "^6.5.1" + autoprefixer "^10.4.14" + babel-loader "^9.1.3" + babel-plugin-dynamic-import-node "^2.3.3" + boxen "^6.2.1" + chalk "^4.1.2" + chokidar "^3.5.3" + clean-css "^5.3.2" + cli-table3 "^0.6.3" + combine-promises "^1.1.0" + commander "^5.1.0" + copy-webpack-plugin "^11.0.0" + core-js "^3.31.1" + css-loader "^6.8.1" + css-minimizer-webpack-plugin "^4.2.2" + cssnano "^5.1.15" + del "^6.1.1" + detect-port "^1.5.1" + escape-html "^1.0.3" + eta "^2.2.0" + file-loader "^6.2.0" + fs-extra "^11.1.1" + html-minifier-terser "^7.2.0" + html-tags "^3.3.1" + html-webpack-plugin "^5.5.3" + leven "^3.1.0" + lodash "^4.17.21" + mini-css-extract-plugin "^2.7.6" + postcss "^8.4.26" + postcss-loader "^7.3.3" + prompts "^2.4.2" + react-dev-utils "^12.0.1" + react-helmet-async "^1.3.0" + react-loadable "npm:@docusaurus/react-loadable@5.5.2" + react-loadable-ssr-addon-v5-slorber "^1.0.1" + react-router "^5.3.4" + react-router-config "^5.1.1" + react-router-dom "^5.3.4" + rtl-detect "^1.0.4" + semver "^7.5.4" + serve-handler "^6.1.5" + shelljs "^0.8.5" + terser-webpack-plugin "^5.3.9" + tslib "^2.6.0" + update-notifier "^6.0.2" + url-loader "^4.1.1" + webpack "^5.88.1" + webpack-bundle-analyzer "^4.9.0" + webpack-dev-server "^4.15.1" + webpack-merge "^5.9.0" + webpackbar "^5.0.2" + +"@docusaurus/cssnano-preset@3.1.1": + version "3.1.1" + resolved "https://registry.npmmirror.com/@docusaurus/cssnano-preset/-/cssnano-preset-3.1.1.tgz#03a4cb8e6d41654d7ff5ed79fddd73fd224feea4" + integrity sha512-LnoIDjJWbirdbVZDMq+4hwmrTl2yHDnBf9MLG9qyExeAE3ac35s4yUhJI8yyTCdixzNfKit4cbXblzzqMu4+8g== + dependencies: + cssnano-preset-advanced "^5.3.10" + postcss "^8.4.26" + postcss-sort-media-queries "^4.4.1" + tslib "^2.6.0" + +"@docusaurus/logger@3.1.1": + version "3.1.1" + resolved "https://registry.npmmirror.com/@docusaurus/logger/-/logger-3.1.1.tgz#423e8270c00a57b1b3a0cc8a3ee0a4c522a68387" + integrity sha512-BjkNDpQzewcTnST8trx4idSoAla6zZ3w22NqM/UMcFtvYJgmoE4layuTzlfql3VFPNuivvj7BOExa/+21y4X2Q== + dependencies: + chalk "^4.1.2" + tslib "^2.6.0" + +"@docusaurus/mdx-loader@3.1.1": + version "3.1.1" + resolved "https://registry.npmmirror.com/@docusaurus/mdx-loader/-/mdx-loader-3.1.1.tgz#f79290abc5044bef1d7ecac4eccec887058b8e03" + integrity sha512-xN2IccH9+sv7TmxwsDJNS97BHdmlqWwho+kIVY4tcCXkp+k4QuzvWBeunIMzeayY4Fu13A6sAjHGv5qm72KyGA== + dependencies: + "@babel/parser" "^7.22.7" + "@babel/traverse" "^7.22.8" + "@docusaurus/logger" "3.1.1" + "@docusaurus/utils" "3.1.1" + "@docusaurus/utils-validation" "3.1.1" + "@mdx-js/mdx" "^3.0.0" + "@slorber/remark-comment" "^1.0.0" + escape-html "^1.0.3" + estree-util-value-to-estree "^3.0.1" + file-loader "^6.2.0" + fs-extra "^11.1.1" + image-size "^1.0.2" + mdast-util-mdx "^3.0.0" + mdast-util-to-string "^4.0.0" + rehype-raw "^7.0.0" + remark-directive "^3.0.0" + remark-emoji "^4.0.0" + remark-frontmatter "^5.0.0" + remark-gfm "^4.0.0" + stringify-object "^3.3.0" + tslib "^2.6.0" + unified "^11.0.3" + unist-util-visit "^5.0.0" + url-loader "^4.1.1" + vfile "^6.0.1" + webpack "^5.88.1" + +"@docusaurus/module-type-aliases@3.1.1": + version "3.1.1" + resolved "https://registry.npmmirror.com/@docusaurus/module-type-aliases/-/module-type-aliases-3.1.1.tgz#b304402b0535a13ebd4c0db1c368d2604d54d02f" + integrity sha512-xBJyx0TMfAfVZ9ZeIOb1awdXgR4YJMocIEzTps91rq+hJDFJgJaylDtmoRhUxkwuYmNK1GJpW95b7DLztSBJ3A== + dependencies: + "@docusaurus/react-loadable" "5.5.2" + "@docusaurus/types" "3.1.1" + "@types/history" "^4.7.11" + "@types/react" "*" + "@types/react-router-config" "*" + "@types/react-router-dom" "*" + react-helmet-async "*" + react-loadable "npm:@docusaurus/react-loadable@5.5.2" + +"@docusaurus/plugin-content-blog@3.1.1": + version "3.1.1" + resolved "https://registry.npmmirror.com/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.1.1.tgz#16f4fd723227b2158461bba6b9bcc18c1926f7ea" + integrity sha512-ew/3VtVoG3emoAKmoZl7oKe1zdFOsI0NbcHS26kIxt2Z8vcXKCUgK9jJJrz0TbOipyETPhqwq4nbitrY3baibg== + dependencies: + "@docusaurus/core" "3.1.1" + "@docusaurus/logger" "3.1.1" + "@docusaurus/mdx-loader" "3.1.1" + "@docusaurus/types" "3.1.1" + "@docusaurus/utils" "3.1.1" + "@docusaurus/utils-common" "3.1.1" + "@docusaurus/utils-validation" "3.1.1" + cheerio "^1.0.0-rc.12" + feed "^4.2.2" + fs-extra "^11.1.1" + lodash "^4.17.21" + reading-time "^1.5.0" + srcset "^4.0.0" + tslib "^2.6.0" + unist-util-visit "^5.0.0" + utility-types "^3.10.0" + webpack "^5.88.1" + +"@docusaurus/plugin-content-docs@3.1.1": + version "3.1.1" + resolved "https://registry.npmmirror.com/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.1.1.tgz#f2eddebf351dd8dd504a2c26061165c519e1f964" + integrity sha512-lhFq4E874zw0UOH7ujzxnCayOyAt0f9YPVYSb9ohxrdCM8B4szxitUw9rIX4V9JLLHVoqIJb6k+lJJ1jrcGJ0A== + dependencies: + "@docusaurus/core" "3.1.1" + "@docusaurus/logger" "3.1.1" + "@docusaurus/mdx-loader" "3.1.1" + "@docusaurus/module-type-aliases" "3.1.1" + "@docusaurus/types" "3.1.1" + "@docusaurus/utils" "3.1.1" + "@docusaurus/utils-validation" "3.1.1" + "@types/react-router-config" "^5.0.7" + combine-promises "^1.1.0" + fs-extra "^11.1.1" + js-yaml "^4.1.0" + lodash "^4.17.21" + tslib "^2.6.0" + utility-types "^3.10.0" + webpack "^5.88.1" + +"@docusaurus/plugin-content-pages@3.1.1": + version "3.1.1" + resolved "https://registry.npmmirror.com/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.1.1.tgz#05aec68c2abeac2140c7a16d4c5b506bf4d19fb2" + integrity sha512-NQHncNRAJbyLtgTim9GlEnNYsFhuCxaCNkMwikuxLTiGIPH7r/jpb7O3f3jUMYMebZZZrDq5S7om9a6rvB/YCA== + dependencies: + "@docusaurus/core" "3.1.1" + "@docusaurus/mdx-loader" "3.1.1" + "@docusaurus/types" "3.1.1" + "@docusaurus/utils" "3.1.1" + "@docusaurus/utils-validation" "3.1.1" + fs-extra "^11.1.1" + tslib "^2.6.0" + webpack "^5.88.1" + +"@docusaurus/plugin-debug@3.1.1": + version "3.1.1" + resolved "https://registry.npmmirror.com/@docusaurus/plugin-debug/-/plugin-debug-3.1.1.tgz#cee5aae1fef288fb93f68894db79a2612e313d3f" + integrity sha512-xWeMkueM9wE/8LVvl4+Qf1WqwXmreMjI5Kgr7GYCDoJ8zu4kD+KaMhrh7py7MNM38IFvU1RfrGKacCEe2DRRfQ== + dependencies: + "@docusaurus/core" "3.1.1" + "@docusaurus/types" "3.1.1" + "@docusaurus/utils" "3.1.1" + fs-extra "^11.1.1" + react-json-view-lite "^1.2.0" + tslib "^2.6.0" + +"@docusaurus/plugin-google-analytics@3.1.1": + version "3.1.1" + resolved "https://registry.npmmirror.com/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.1.1.tgz#bfc58205b4fcaf3222e04f9c3542f3bef9804887" + integrity sha512-+q2UpWTqVi8GdlLoSlD5bS/YpxW+QMoBwrPrUH/NpvpuOi0Of7MTotsQf9JWd3hymZxl2uu1o3PIrbpxfeDFDQ== + dependencies: + "@docusaurus/core" "3.1.1" + "@docusaurus/types" "3.1.1" + "@docusaurus/utils-validation" "3.1.1" + tslib "^2.6.0" + +"@docusaurus/plugin-google-gtag@3.1.1": + version "3.1.1" + resolved "https://registry.npmmirror.com/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.1.1.tgz#7e8b5aa6847a12461c104a65a335f4a45dae2f28" + integrity sha512-0mMPiBBlQ5LFHTtjxuvt/6yzh8v7OxLi3CbeEsxXZpUzcKO/GC7UA1VOWUoBeQzQL508J12HTAlR3IBU9OofSw== + dependencies: + "@docusaurus/core" "3.1.1" + "@docusaurus/types" "3.1.1" + "@docusaurus/utils-validation" "3.1.1" + "@types/gtag.js" "^0.0.12" + tslib "^2.6.0" + +"@docusaurus/plugin-google-tag-manager@3.1.1": + version "3.1.1" + resolved "https://registry.npmmirror.com/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.1.1.tgz#e1aae4d821e786d133386b4ae6e6fe66a4bc0089" + integrity sha512-d07bsrMLdDIryDtY17DgqYUbjkswZQr8cLWl4tzXrt5OR/T/zxC1SYKajzB3fd87zTu5W5klV5GmUwcNSMXQXA== + dependencies: + "@docusaurus/core" "3.1.1" + "@docusaurus/types" "3.1.1" + "@docusaurus/utils-validation" "3.1.1" + tslib "^2.6.0" + +"@docusaurus/plugin-sitemap@3.1.1": + version "3.1.1" + resolved "https://registry.npmmirror.com/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.1.1.tgz#8828bf5e2922273aad207a35189f22913e6a0dfd" + integrity sha512-iJ4hCaMmDaUqRv131XJdt/C/jJQx8UreDWTRqZKtNydvZVh/o4yXGRRFOplea1D9b/zpwL1Y+ZDwX7xMhIOTmg== + dependencies: + "@docusaurus/core" "3.1.1" + "@docusaurus/logger" "3.1.1" + "@docusaurus/types" "3.1.1" + "@docusaurus/utils" "3.1.1" + "@docusaurus/utils-common" "3.1.1" + "@docusaurus/utils-validation" "3.1.1" + fs-extra "^11.1.1" + sitemap "^7.1.1" + tslib "^2.6.0" + +"@docusaurus/preset-classic@3.1.1": + version "3.1.1" + resolved "https://registry.npmmirror.com/@docusaurus/preset-classic/-/preset-classic-3.1.1.tgz#15fd80012529dafd7e01cc0bce59d39ee6ad6bf5" + integrity sha512-jG4ys/hWYf69iaN/xOmF+3kjs4Nnz1Ay3CjFLDtYa8KdxbmUhArA9HmP26ru5N0wbVWhY+6kmpYhTJpez5wTyg== + dependencies: + "@docusaurus/core" "3.1.1" + "@docusaurus/plugin-content-blog" "3.1.1" + "@docusaurus/plugin-content-docs" "3.1.1" + "@docusaurus/plugin-content-pages" "3.1.1" + "@docusaurus/plugin-debug" "3.1.1" + "@docusaurus/plugin-google-analytics" "3.1.1" + "@docusaurus/plugin-google-gtag" "3.1.1" + "@docusaurus/plugin-google-tag-manager" "3.1.1" + "@docusaurus/plugin-sitemap" "3.1.1" + "@docusaurus/theme-classic" "3.1.1" + "@docusaurus/theme-common" "3.1.1" + "@docusaurus/theme-search-algolia" "3.1.1" + "@docusaurus/types" "3.1.1" + +"@docusaurus/react-loadable@5.5.2", "react-loadable@npm:@docusaurus/react-loadable@5.5.2": + version "5.5.2" + resolved "https://registry.npmmirror.com/@docusaurus/react-loadable/-/react-loadable-5.5.2.tgz#81aae0db81ecafbdaee3651f12804580868fa6ce" + integrity sha512-A3dYjdBGuy0IGT+wyLIGIKLRE+sAk1iNk0f1HjNDysO7u8lhL4N3VEm+FAubmJbAztn94F7MxBTPmnixbiyFdQ== + dependencies: + "@types/react" "*" + prop-types "^15.6.2" + +"@docusaurus/theme-classic@3.1.1": + version "3.1.1" + resolved "https://registry.npmmirror.com/@docusaurus/theme-classic/-/theme-classic-3.1.1.tgz#0a188c787fc4bf2bb525cc30c7aa34e555ee96b8" + integrity sha512-GiPE/jbWM8Qv1A14lk6s9fhc0LhPEQ00eIczRO4QL2nAQJZXkjPG6zaVx+1cZxPFWbAsqSjKe2lqkwF3fGkQ7Q== + dependencies: + "@docusaurus/core" "3.1.1" + "@docusaurus/mdx-loader" "3.1.1" + "@docusaurus/module-type-aliases" "3.1.1" + "@docusaurus/plugin-content-blog" "3.1.1" + "@docusaurus/plugin-content-docs" "3.1.1" + "@docusaurus/plugin-content-pages" "3.1.1" + "@docusaurus/theme-common" "3.1.1" + "@docusaurus/theme-translations" "3.1.1" + "@docusaurus/types" "3.1.1" + "@docusaurus/utils" "3.1.1" + "@docusaurus/utils-common" "3.1.1" + "@docusaurus/utils-validation" "3.1.1" + "@mdx-js/react" "^3.0.0" + clsx "^2.0.0" + copy-text-to-clipboard "^3.2.0" + infima "0.2.0-alpha.43" + lodash "^4.17.21" + nprogress "^0.2.0" + postcss "^8.4.26" + prism-react-renderer "^2.3.0" + prismjs "^1.29.0" + react-router-dom "^5.3.4" + rtlcss "^4.1.0" + tslib "^2.6.0" + utility-types "^3.10.0" + +"@docusaurus/theme-common@3.1.1": + version "3.1.1" + resolved "https://registry.npmmirror.com/@docusaurus/theme-common/-/theme-common-3.1.1.tgz#5a16893928b8379c9e83aef01d753e7e142459e2" + integrity sha512-38urZfeMhN70YaXkwIGXmcUcv2CEYK/2l4b05GkJPrbEbgpsIZM3Xc+Js2ehBGGZmfZq8GjjQ5RNQYG+MYzCYg== + dependencies: + "@docusaurus/mdx-loader" "3.1.1" + "@docusaurus/module-type-aliases" "3.1.1" + "@docusaurus/plugin-content-blog" "3.1.1" + "@docusaurus/plugin-content-docs" "3.1.1" + "@docusaurus/plugin-content-pages" "3.1.1" + "@docusaurus/utils" "3.1.1" + "@docusaurus/utils-common" "3.1.1" + "@types/history" "^4.7.11" + "@types/react" "*" + "@types/react-router-config" "*" + clsx "^2.0.0" + parse-numeric-range "^1.3.0" + prism-react-renderer "^2.3.0" + tslib "^2.6.0" + utility-types "^3.10.0" + +"@docusaurus/theme-search-algolia@3.1.1": + version "3.1.1" + resolved "https://registry.npmmirror.com/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.1.1.tgz#5170cd68cc59d150416b070bdc6d15c363ddf5e1" + integrity sha512-tBH9VY5EpRctVdaAhT+b1BY8y5dyHVZGFXyCHgTrvcXQy5CV4q7serEX7U3SveNT9zksmchPyct6i1sFDC4Z5g== + dependencies: + "@docsearch/react" "^3.5.2" + "@docusaurus/core" "3.1.1" + "@docusaurus/logger" "3.1.1" + "@docusaurus/plugin-content-docs" "3.1.1" + "@docusaurus/theme-common" "3.1.1" + "@docusaurus/theme-translations" "3.1.1" + "@docusaurus/utils" "3.1.1" + "@docusaurus/utils-validation" "3.1.1" + algoliasearch "^4.18.0" + algoliasearch-helper "^3.13.3" + clsx "^2.0.0" + eta "^2.2.0" + fs-extra "^11.1.1" + lodash "^4.17.21" + tslib "^2.6.0" + utility-types "^3.10.0" + +"@docusaurus/theme-translations@3.1.1": + version "3.1.1" + resolved "https://registry.npmmirror.com/@docusaurus/theme-translations/-/theme-translations-3.1.1.tgz#117e91ba5e3a8178cb59f3028bf41de165a508c1" + integrity sha512-xvWQFwjxHphpJq5fgk37FXCDdAa2o+r7FX8IpMg+bGZBNXyWBu3MjZ+G4+eUVNpDhVinTc+j6ucL0Ain5KCGrg== + dependencies: + fs-extra "^11.1.1" + tslib "^2.6.0" + +"@docusaurus/tsconfig@3.1.1": + version "3.1.1" + resolved "https://registry.npmmirror.com/@docusaurus/tsconfig/-/tsconfig-3.1.1.tgz#ee2297ea94f4059b69f4b9bff238c212eede65e9" + integrity sha512-FTBuY3KvaHfMVBgvlPmDQ+KS9Q/bYtVftq2ugou3PgBDJoQmw2aUZ4Sg15HKqLGbfIkxoy9t6cqE4Yw1Ta8Q1A== + +"@docusaurus/types@3.1.1": + version "3.1.1" + resolved "https://registry.npmmirror.com/@docusaurus/types/-/types-3.1.1.tgz#747c9dee8cf7c3b0e5ee7351bac5e9c4fdc7f259" + integrity sha512-grBqOLnubUecgKFXN9q3uit2HFbCxTWX4Fam3ZFbMN0sWX9wOcDoA7lwdX/8AmeL20Oc4kQvWVgNrsT8bKRvzg== + dependencies: + "@mdx-js/mdx" "^3.0.0" + "@types/history" "^4.7.11" + "@types/react" "*" + commander "^5.1.0" + joi "^17.9.2" + react-helmet-async "^1.3.0" + utility-types "^3.10.0" + webpack "^5.88.1" + webpack-merge "^5.9.0" + +"@docusaurus/utils-common@3.1.1": + version "3.1.1" + resolved "https://registry.npmmirror.com/@docusaurus/utils-common/-/utils-common-3.1.1.tgz#b48fade63523fd40f3adb67b47c3371e5183c20b" + integrity sha512-eGne3olsIoNfPug5ixjepZAIxeYFzHHnor55Wb2P57jNbtVaFvij/T+MS8U0dtZRFi50QU+UPmRrXdVUM8uyMg== + dependencies: + tslib "^2.6.0" + +"@docusaurus/utils-validation@3.1.1": + version "3.1.1" + resolved "https://registry.npmmirror.com/@docusaurus/utils-validation/-/utils-validation-3.1.1.tgz#3a747349ed05aee0e4d543552b41f3c9467ee731" + integrity sha512-KlY4P9YVDnwL+nExvlIpu79abfEv6ZCHuOX4ZQ+gtip+Wxj0daccdReIWWtqxM/Fb5Cz1nQvUCc7VEtT8IBUAA== + dependencies: + "@docusaurus/logger" "3.1.1" + "@docusaurus/utils" "3.1.1" + joi "^17.9.2" + js-yaml "^4.1.0" + tslib "^2.6.0" + +"@docusaurus/utils@3.1.1": + version "3.1.1" + resolved "https://registry.npmmirror.com/@docusaurus/utils/-/utils-3.1.1.tgz#e822d14704e4b3bb451ca464a7cc56aea9b55a45" + integrity sha512-ZJfJa5cJQtRYtqijsPEnAZoduW6sjAQ7ZCWSZavLcV10Fw0Z3gSaPKA/B4micvj2afRZ4gZxT7KfYqe5H8Cetg== + dependencies: + "@docusaurus/logger" "3.1.1" + "@svgr/webpack" "^6.5.1" + escape-string-regexp "^4.0.0" + file-loader "^6.2.0" + fs-extra "^11.1.1" + github-slugger "^1.5.0" + globby "^11.1.0" + gray-matter "^4.0.3" + jiti "^1.20.0" + js-yaml "^4.1.0" + lodash "^4.17.21" + micromatch "^4.0.5" + resolve-pathname "^3.0.0" + shelljs "^0.8.5" + tslib "^2.6.0" + url-loader "^4.1.1" + webpack "^5.88.1" + +"@hapi/hoek@^9.0.0", "@hapi/hoek@^9.3.0": + version "9.3.0" + resolved "https://registry.npmmirror.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" + integrity sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ== + +"@hapi/topo@^5.1.0": + version "5.1.0" + resolved "https://registry.npmmirror.com/@hapi/topo/-/topo-5.1.0.tgz#dc448e332c6c6e37a4dc02fd84ba8d44b9afb012" + integrity sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg== + dependencies: + "@hapi/hoek" "^9.0.0" + +"@jest/schemas@^29.6.3": + version "29.6.3" + resolved "https://registry.npmmirror.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" + integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== + dependencies: + "@sinclair/typebox" "^0.27.8" + +"@jest/types@^29.6.3": + version "29.6.3" + resolved "https://registry.npmmirror.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" + integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== + dependencies: + "@jest/schemas" "^29.6.3" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + +"@jridgewell/gen-mapping@^0.3.5": + version "0.3.5" + resolved "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" + integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== + dependencies: + "@jridgewell/set-array" "^1.2.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.24" + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.2" + resolved "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + +"@jridgewell/set-array@^1.2.1": + version "1.2.1" + resolved "https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" + integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== + +"@jridgewell/source-map@^0.3.3": + version "0.3.6" + resolved "https://registry.npmmirror.com/@jridgewell/source-map/-/source-map-0.3.6.tgz#9d71ca886e32502eb9362c9a74a46787c36df81a" + integrity sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ== + dependencies: + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.4.15" + resolved "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": + version "0.3.25" + resolved "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@leichtgewicht/ip-codec@^2.0.1": + version "2.0.5" + resolved "https://registry.npmmirror.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz#4fc56c15c580b9adb7dc3c333a134e540b44bfb1" + integrity sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw== + +"@mdx-js/mdx@^3.0.0": + version "3.0.1" + resolved "https://registry.npmmirror.com/@mdx-js/mdx/-/mdx-3.0.1.tgz#617bd2629ae561fdca1bb88e3badd947f5a82191" + integrity sha512-eIQ4QTrOWyL3LWEe/bu6Taqzq2HQvHcyTMaOrI95P2/LmJE7AsfPfgJGuFLPVqBUE1BC1rik3VIhU+s9u72arA== + dependencies: + "@types/estree" "^1.0.0" + "@types/estree-jsx" "^1.0.0" + "@types/hast" "^3.0.0" + "@types/mdx" "^2.0.0" + collapse-white-space "^2.0.0" + devlop "^1.0.0" + estree-util-build-jsx "^3.0.0" + estree-util-is-identifier-name "^3.0.0" + estree-util-to-js "^2.0.0" + estree-walker "^3.0.0" + hast-util-to-estree "^3.0.0" + hast-util-to-jsx-runtime "^2.0.0" + markdown-extensions "^2.0.0" + periscopic "^3.0.0" + remark-mdx "^3.0.0" + remark-parse "^11.0.0" + remark-rehype "^11.0.0" + source-map "^0.7.0" + unified "^11.0.0" + unist-util-position-from-estree "^2.0.0" + unist-util-stringify-position "^4.0.0" + unist-util-visit "^5.0.0" + vfile "^6.0.0" + +"@mdx-js/react@^3.0.0": + version "3.0.1" + resolved "https://registry.npmmirror.com/@mdx-js/react/-/react-3.0.1.tgz#997a19b3a5b783d936c75ae7c47cfe62f967f746" + integrity sha512-9ZrPIU4MGf6et1m1ov3zKf+q9+deetI51zprKB1D/z3NOb+rUxxtEl3mCjW5wTGh6VhRdwPueh1oRzi6ezkA8A== + dependencies: + "@types/mdx" "^2.0.0" + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@pnpm/config.env-replace@^1.1.0": + version "1.1.0" + resolved "https://registry.npmmirror.com/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz#ab29da53df41e8948a00f2433f085f54de8b3a4c" + integrity sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w== + +"@pnpm/network.ca-file@^1.0.1": + version "1.0.2" + resolved "https://registry.npmmirror.com/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz#2ab05e09c1af0cdf2fcf5035bea1484e222f7983" + integrity sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA== + dependencies: + graceful-fs "4.2.10" + +"@pnpm/npm-conf@^2.1.0": + version "2.2.2" + resolved "https://registry.npmmirror.com/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz#0058baf1c26cbb63a828f0193795401684ac86f0" + integrity sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA== + dependencies: + "@pnpm/config.env-replace" "^1.1.0" + "@pnpm/network.ca-file" "^1.0.1" + config-chain "^1.1.11" + +"@polka/url@^1.0.0-next.24": + version "1.0.0-next.25" + resolved "https://registry.npmmirror.com/@polka/url/-/url-1.0.0-next.25.tgz#f077fdc0b5d0078d30893396ff4827a13f99e817" + integrity sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ== + +"@sideway/address@^4.1.5": + version "4.1.5" + resolved "https://registry.npmmirror.com/@sideway/address/-/address-4.1.5.tgz#4bc149a0076623ced99ca8208ba780d65a99b9d5" + integrity sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q== + dependencies: + "@hapi/hoek" "^9.0.0" + +"@sideway/formula@^3.0.1": + version "3.0.1" + resolved "https://registry.npmmirror.com/@sideway/formula/-/formula-3.0.1.tgz#80fcbcbaf7ce031e0ef2dd29b1bfc7c3f583611f" + integrity sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg== + +"@sideway/pinpoint@^2.0.0": + version "2.0.0" + resolved "https://registry.npmmirror.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" + integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== + +"@sinclair/typebox@^0.27.8": + version "0.27.8" + resolved "https://registry.npmmirror.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" + integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== + +"@sindresorhus/is@^4.6.0": + version "4.6.0" + resolved "https://registry.npmmirror.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" + integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== + +"@sindresorhus/is@^5.2.0": + version "5.6.0" + resolved "https://registry.npmmirror.com/@sindresorhus/is/-/is-5.6.0.tgz#41dd6093d34652cddb5d5bdeee04eafc33826668" + integrity sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g== + +"@slorber/remark-comment@^1.0.0": + version "1.0.0" + resolved "https://registry.npmmirror.com/@slorber/remark-comment/-/remark-comment-1.0.0.tgz#2a020b3f4579c89dec0361673206c28d67e08f5a" + integrity sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA== + dependencies: + micromark-factory-space "^1.0.0" + micromark-util-character "^1.1.0" + micromark-util-symbol "^1.0.1" + +"@slorber/static-site-generator-webpack-plugin@^4.0.7": + version "4.0.7" + resolved "https://registry.npmmirror.com/@slorber/static-site-generator-webpack-plugin/-/static-site-generator-webpack-plugin-4.0.7.tgz#fc1678bddefab014e2145cbe25b3ce4e1cfc36f3" + integrity sha512-Ug7x6z5lwrz0WqdnNFOMYrDQNTPAprvHLSh6+/fmml3qUiz6l5eq+2MzLKWtn/q5K5NpSiFsZTP/fck/3vjSxA== + dependencies: + eval "^0.1.8" + p-map "^4.0.0" + webpack-sources "^3.2.2" + +"@svgr/babel-plugin-add-jsx-attribute@^6.5.1": + version "6.5.1" + resolved "https://registry.npmmirror.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.5.1.tgz#74a5d648bd0347bda99d82409d87b8ca80b9a1ba" + integrity sha512-9PYGcXrAxitycIjRmZB+Q0JaN07GZIWaTBIGQzfaZv+qr1n8X1XUEJ5rZ/vx6OVD9RRYlrNnXWExQXcmZeD/BQ== + +"@svgr/babel-plugin-remove-jsx-attribute@*": + version "8.0.0" + resolved "https://registry.npmmirror.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz#69177f7937233caca3a1afb051906698f2f59186" + integrity sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA== + +"@svgr/babel-plugin-remove-jsx-empty-expression@*": + version "8.0.0" + resolved "https://registry.npmmirror.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz#c2c48104cfd7dcd557f373b70a56e9e3bdae1d44" + integrity sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA== + +"@svgr/babel-plugin-replace-jsx-attribute-value@^6.5.1": + version "6.5.1" + resolved "https://registry.npmmirror.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-6.5.1.tgz#fb9d22ea26d2bc5e0a44b763d4c46d5d3f596c60" + integrity sha512-8DPaVVE3fd5JKuIC29dqyMB54sA6mfgki2H2+swh+zNJoynC8pMPzOkidqHOSc6Wj032fhl8Z0TVn1GiPpAiJg== + +"@svgr/babel-plugin-svg-dynamic-title@^6.5.1": + version "6.5.1" + resolved "https://registry.npmmirror.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-6.5.1.tgz#01b2024a2b53ffaa5efceaa0bf3e1d5a4c520ce4" + integrity sha512-FwOEi0Il72iAzlkaHrlemVurgSQRDFbk0OC8dSvD5fSBPHltNh7JtLsxmZUhjYBZo2PpcU/RJvvi6Q0l7O7ogw== + +"@svgr/babel-plugin-svg-em-dimensions@^6.5.1": + version "6.5.1" + resolved "https://registry.npmmirror.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-6.5.1.tgz#dd3fa9f5b24eb4f93bcf121c3d40ff5facecb217" + integrity sha512-gWGsiwjb4tw+ITOJ86ndY/DZZ6cuXMNE/SjcDRg+HLuCmwpcjOktwRF9WgAiycTqJD/QXqL2f8IzE2Rzh7aVXA== + +"@svgr/babel-plugin-transform-react-native-svg@^6.5.1": + version "6.5.1" + resolved "https://registry.npmmirror.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-6.5.1.tgz#1d8e945a03df65b601551097d8f5e34351d3d305" + integrity sha512-2jT3nTayyYP7kI6aGutkyfJ7UMGtuguD72OjeGLwVNyfPRBD8zQthlvL+fAbAKk5n9ZNcvFkp/b1lZ7VsYqVJg== + +"@svgr/babel-plugin-transform-svg-component@^6.5.1": + version "6.5.1" + resolved "https://registry.npmmirror.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-6.5.1.tgz#48620b9e590e25ff95a80f811544218d27f8a250" + integrity sha512-a1p6LF5Jt33O3rZoVRBqdxL350oge54iZWHNI6LJB5tQ7EelvD/Mb1mfBiZNAan0dt4i3VArkFRjA4iObuNykQ== + +"@svgr/babel-preset@^6.5.1": + version "6.5.1" + resolved "https://registry.npmmirror.com/@svgr/babel-preset/-/babel-preset-6.5.1.tgz#b90de7979c8843c5c580c7e2ec71f024b49eb828" + integrity sha512-6127fvO/FF2oi5EzSQOAjo1LE3OtNVh11R+/8FXa+mHx1ptAaS4cknIjnUA7e6j6fwGGJ17NzaTJFUwOV2zwCw== + dependencies: + "@svgr/babel-plugin-add-jsx-attribute" "^6.5.1" + "@svgr/babel-plugin-remove-jsx-attribute" "*" + "@svgr/babel-plugin-remove-jsx-empty-expression" "*" + "@svgr/babel-plugin-replace-jsx-attribute-value" "^6.5.1" + "@svgr/babel-plugin-svg-dynamic-title" "^6.5.1" + "@svgr/babel-plugin-svg-em-dimensions" "^6.5.1" + "@svgr/babel-plugin-transform-react-native-svg" "^6.5.1" + "@svgr/babel-plugin-transform-svg-component" "^6.5.1" + +"@svgr/core@^6.5.1": + version "6.5.1" + resolved "https://registry.npmmirror.com/@svgr/core/-/core-6.5.1.tgz#d3e8aa9dbe3fbd747f9ee4282c1c77a27410488a" + integrity sha512-/xdLSWxK5QkqG524ONSjvg3V/FkNyCv538OIBdQqPNaAta3AsXj/Bd2FbvR87yMbXO2hFSWiAe/Q6IkVPDw+mw== + dependencies: + "@babel/core" "^7.19.6" + "@svgr/babel-preset" "^6.5.1" + "@svgr/plugin-jsx" "^6.5.1" + camelcase "^6.2.0" + cosmiconfig "^7.0.1" + +"@svgr/hast-util-to-babel-ast@^6.5.1": + version "6.5.1" + resolved "https://registry.npmmirror.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-6.5.1.tgz#81800bd09b5bcdb968bf6ee7c863d2288fdb80d2" + integrity sha512-1hnUxxjd83EAxbL4a0JDJoD3Dao3hmjvyvyEV8PzWmLK3B9m9NPlW7GKjFyoWE8nM7HnXzPcmmSyOW8yOddSXw== + dependencies: + "@babel/types" "^7.20.0" + entities "^4.4.0" + +"@svgr/plugin-jsx@^6.5.1": + version "6.5.1" + resolved "https://registry.npmmirror.com/@svgr/plugin-jsx/-/plugin-jsx-6.5.1.tgz#0e30d1878e771ca753c94e69581c7971542a7072" + integrity sha512-+UdQxI3jgtSjCykNSlEMuy1jSRQlGC7pqBCPvkG/2dATdWo082zHTTK3uhnAju2/6XpE6B5mZ3z4Z8Ns01S8Gw== + dependencies: + "@babel/core" "^7.19.6" + "@svgr/babel-preset" "^6.5.1" + "@svgr/hast-util-to-babel-ast" "^6.5.1" + svg-parser "^2.0.4" + +"@svgr/plugin-svgo@^6.5.1": + version "6.5.1" + resolved "https://registry.npmmirror.com/@svgr/plugin-svgo/-/plugin-svgo-6.5.1.tgz#0f91910e988fc0b842f88e0960c2862e022abe84" + integrity sha512-omvZKf8ixP9z6GWgwbtmP9qQMPX4ODXi+wzbVZgomNFsUIlHA1sf4fThdwTWSsZGgvGAG6yE+b/F5gWUkcZ/iQ== + dependencies: + cosmiconfig "^7.0.1" + deepmerge "^4.2.2" + svgo "^2.8.0" + +"@svgr/webpack@^6.5.1": + version "6.5.1" + resolved "https://registry.npmmirror.com/@svgr/webpack/-/webpack-6.5.1.tgz#ecf027814fc1cb2decc29dc92f39c3cf691e40e8" + integrity sha512-cQ/AsnBkXPkEK8cLbv4Dm7JGXq2XrumKnL1dRpJD9rIO2fTIlJI9a1uCciYG1F2aUsox/hJQyNGbt3soDxSRkA== + dependencies: + "@babel/core" "^7.19.6" + "@babel/plugin-transform-react-constant-elements" "^7.18.12" + "@babel/preset-env" "^7.19.4" + "@babel/preset-react" "^7.18.6" + "@babel/preset-typescript" "^7.18.6" + "@svgr/core" "^6.5.1" + "@svgr/plugin-jsx" "^6.5.1" + "@svgr/plugin-svgo" "^6.5.1" + +"@szmarczak/http-timer@^5.0.1": + version "5.0.1" + resolved "https://registry.npmmirror.com/@szmarczak/http-timer/-/http-timer-5.0.1.tgz#c7c1bf1141cdd4751b0399c8fc7b8b664cd5be3a" + integrity sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw== + dependencies: + defer-to-connect "^2.0.1" + +"@trysound/sax@0.2.0": + version "0.2.0" + resolved "https://registry.npmmirror.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" + integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== + +"@types/acorn@^4.0.0": + version "4.0.6" + resolved "https://registry.npmmirror.com/@types/acorn/-/acorn-4.0.6.tgz#d61ca5480300ac41a7d973dd5b84d0a591154a22" + integrity sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ== + dependencies: + "@types/estree" "*" + +"@types/body-parser@*": + version "1.19.5" + resolved "https://registry.npmmirror.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4" + integrity sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/bonjour@^3.5.9": + version "3.5.13" + resolved "https://registry.npmmirror.com/@types/bonjour/-/bonjour-3.5.13.tgz#adf90ce1a105e81dd1f9c61fdc5afda1bfb92956" + integrity sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ== + dependencies: + "@types/node" "*" + +"@types/connect-history-api-fallback@^1.3.5": + version "1.5.4" + resolved "https://registry.npmmirror.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz#7de71645a103056b48ac3ce07b3520b819c1d5b3" + integrity sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw== + dependencies: + "@types/express-serve-static-core" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.38" + resolved "https://registry.npmmirror.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" + integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== + dependencies: + "@types/node" "*" + +"@types/debug@^4.0.0": + version "4.1.12" + resolved "https://registry.npmmirror.com/@types/debug/-/debug-4.1.12.tgz#a155f21690871953410df4b6b6f53187f0500917" + integrity sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ== + dependencies: + "@types/ms" "*" + +"@types/eslint-scope@^3.7.3": + version "3.7.7" + resolved "https://registry.npmmirror.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" + integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "8.56.6" + resolved "https://registry.npmmirror.com/@types/eslint/-/eslint-8.56.6.tgz#d5dc16cac025d313ee101108ba5714ea10eb3ed0" + integrity sha512-ymwc+qb1XkjT/gfoQwxIeHZ6ixH23A+tCT2ADSA/DPVKzAjwYkTXBMCQ/f6fe4wEa85Lhp26VPeUxI7wMhAi7A== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree-jsx@^1.0.0": + version "1.0.5" + resolved "https://registry.npmmirror.com/@types/estree-jsx/-/estree-jsx-1.0.5.tgz#858a88ea20f34fe65111f005a689fa1ebf70dc18" + integrity sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg== + dependencies: + "@types/estree" "*" + +"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.5": + version "1.0.5" + resolved "https://registry.npmmirror.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== + +"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33": + version "4.17.43" + resolved "https://registry.npmmirror.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz#10d8444be560cb789c4735aea5eac6e5af45df54" + integrity sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + "@types/send" "*" + +"@types/express@*", "@types/express@^4.17.13": + version "4.17.21" + resolved "https://registry.npmmirror.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d" + integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.33" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/gtag.js@^0.0.12": + version "0.0.12" + resolved "https://registry.npmmirror.com/@types/gtag.js/-/gtag.js-0.0.12.tgz#095122edca896689bdfcdd73b057e23064d23572" + integrity sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg== + +"@types/hast@^3.0.0": + version "3.0.4" + resolved "https://registry.npmmirror.com/@types/hast/-/hast-3.0.4.tgz#1d6b39993b82cea6ad783945b0508c25903e15aa" + integrity sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ== + dependencies: + "@types/unist" "*" + +"@types/history@^4.7.11": + version "4.7.11" + resolved "https://registry.npmmirror.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64" + integrity sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA== + +"@types/html-minifier-terser@^6.0.0": + version "6.1.0" + resolved "https://registry.npmmirror.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" + integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== + +"@types/http-cache-semantics@^4.0.2": + version "4.0.4" + resolved "https://registry.npmmirror.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz#b979ebad3919799c979b17c72621c0bc0a31c6c4" + integrity sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA== + +"@types/http-errors@*": + version "2.0.4" + resolved "https://registry.npmmirror.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" + integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== + +"@types/http-proxy@^1.17.8": + version "1.17.14" + resolved "https://registry.npmmirror.com/@types/http-proxy/-/http-proxy-1.17.14.tgz#57f8ccaa1c1c3780644f8a94f9c6b5000b5e2eec" + integrity sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w== + dependencies: + "@types/node" "*" + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": + version "2.0.6" + resolved "https://registry.npmmirror.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" + integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== + +"@types/istanbul-lib-report@*": + version "3.0.3" + resolved "https://registry.npmmirror.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf" + integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.4" + resolved "https://registry.npmmirror.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54" + integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": + version "7.0.15" + resolved "https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== + +"@types/mdast@^4.0.0", "@types/mdast@^4.0.2": + version "4.0.3" + resolved "https://registry.npmmirror.com/@types/mdast/-/mdast-4.0.3.tgz#1e011ff013566e919a4232d1701ad30d70cab333" + integrity sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg== + dependencies: + "@types/unist" "*" + +"@types/mdx@^2.0.0": + version "2.0.12" + resolved "https://registry.npmmirror.com/@types/mdx/-/mdx-2.0.12.tgz#38db34cc8999b982beaec01399620bee6c65ef2e" + integrity sha512-H9VZ9YqE+H28FQVchC83RCs5xQ2J7mAAv6qdDEaWmXEVl3OpdH+xfrSUzQ1lp7U7oSTRZ0RvW08ASPJsYBi7Cw== + +"@types/mime@*": + version "3.0.4" + resolved "https://registry.npmmirror.com/@types/mime/-/mime-3.0.4.tgz#2198ac274de6017b44d941e00261d5bc6a0e0a45" + integrity sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw== + +"@types/mime@^1": + version "1.3.5" + resolved "https://registry.npmmirror.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" + integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== + +"@types/ms@*": + version "0.7.34" + resolved "https://registry.npmmirror.com/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433" + integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g== + +"@types/node-forge@^1.3.0": + version "1.3.11" + resolved "https://registry.npmmirror.com/@types/node-forge/-/node-forge-1.3.11.tgz#0972ea538ddb0f4d9c2fa0ec5db5724773a604da" + integrity sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ== + dependencies: + "@types/node" "*" + +"@types/node@*": + version "20.11.30" + resolved "https://registry.npmmirror.com/@types/node/-/node-20.11.30.tgz#9c33467fc23167a347e73834f788f4b9f399d66f" + integrity sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw== + dependencies: + undici-types "~5.26.4" + +"@types/node@^17.0.5": + version "17.0.45" + resolved "https://registry.npmmirror.com/@types/node/-/node-17.0.45.tgz#2c0fafd78705e7a18b7906b5201a522719dc5190" + integrity sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw== + +"@types/parse-json@^4.0.0": + version "4.0.2" + resolved "https://registry.npmmirror.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" + integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== + +"@types/prismjs@^1.26.0": + version "1.26.3" + resolved "https://registry.npmmirror.com/@types/prismjs/-/prismjs-1.26.3.tgz#47fe8e784c2dee24fe636cab82e090d3da9b7dec" + integrity sha512-A0D0aTXvjlqJ5ZILMz3rNfDBOx9hHxLZYv2by47Sm/pqW35zzjusrZTryatjN/Rf8Us2gZrJD+KeHbUSTux1Cw== + +"@types/prop-types@*": + version "15.7.12" + resolved "https://registry.npmmirror.com/@types/prop-types/-/prop-types-15.7.12.tgz#12bb1e2be27293c1406acb6af1c3f3a1481d98c6" + integrity sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q== + +"@types/qs@*": + version "6.9.14" + resolved "https://registry.npmmirror.com/@types/qs/-/qs-6.9.14.tgz#169e142bfe493895287bee382af6039795e9b75b" + integrity sha512-5khscbd3SwWMhFqylJBLQ0zIu7c1K6Vz0uBIt915BI3zV0q1nfjRQD3RqSBcPaO6PHEF4ov/t9y89fSiyThlPA== + +"@types/range-parser@*": + version "1.2.7" + resolved "https://registry.npmmirror.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" + integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== + +"@types/react-router-config@*", "@types/react-router-config@^5.0.7": + version "5.0.11" + resolved "https://registry.npmmirror.com/@types/react-router-config/-/react-router-config-5.0.11.tgz#2761a23acc7905a66a94419ee40294a65aaa483a" + integrity sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw== + dependencies: + "@types/history" "^4.7.11" + "@types/react" "*" + "@types/react-router" "^5.1.0" + +"@types/react-router-dom@*": + version "5.3.3" + resolved "https://registry.npmmirror.com/@types/react-router-dom/-/react-router-dom-5.3.3.tgz#e9d6b4a66fcdbd651a5f106c2656a30088cc1e83" + integrity sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw== + dependencies: + "@types/history" "^4.7.11" + "@types/react" "*" + "@types/react-router" "*" + +"@types/react-router@*", "@types/react-router@^5.1.0": + version "5.1.20" + resolved "https://registry.npmmirror.com/@types/react-router/-/react-router-5.1.20.tgz#88eccaa122a82405ef3efbcaaa5dcdd9f021387c" + integrity sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q== + dependencies: + "@types/history" "^4.7.11" + "@types/react" "*" + +"@types/react@*": + version "18.2.73" + resolved "https://registry.npmmirror.com/@types/react/-/react-18.2.73.tgz#0579548ad122660d99e00499d22e33b81e73ed94" + integrity sha512-XcGdod0Jjv84HOC7N5ziY3x+qL0AfmubvKOZ9hJjJ2yd5EE+KYjWhdOjt387e9HPheHkdggF9atTifMRtyAaRA== + dependencies: + "@types/prop-types" "*" + csstype "^3.0.2" + +"@types/retry@0.12.0": + version "0.12.0" + resolved "https://registry.npmmirror.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" + integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== + +"@types/sax@^1.2.1": + version "1.2.7" + resolved "https://registry.npmmirror.com/@types/sax/-/sax-1.2.7.tgz#ba5fe7df9aa9c89b6dff7688a19023dd2963091d" + integrity sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A== + dependencies: + "@types/node" "*" + +"@types/send@*": + version "0.17.4" + resolved "https://registry.npmmirror.com/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a" + integrity sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/serve-index@^1.9.1": + version "1.9.4" + resolved "https://registry.npmmirror.com/@types/serve-index/-/serve-index-1.9.4.tgz#e6ae13d5053cb06ed36392110b4f9a49ac4ec898" + integrity sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug== + dependencies: + "@types/express" "*" + +"@types/serve-static@*", "@types/serve-static@^1.13.10": + version "1.15.5" + resolved "https://registry.npmmirror.com/@types/serve-static/-/serve-static-1.15.5.tgz#15e67500ec40789a1e8c9defc2d32a896f05b033" + integrity sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ== + dependencies: + "@types/http-errors" "*" + "@types/mime" "*" + "@types/node" "*" + +"@types/sockjs@^0.3.33": + version "0.3.36" + resolved "https://registry.npmmirror.com/@types/sockjs/-/sockjs-0.3.36.tgz#ce322cf07bcc119d4cbf7f88954f3a3bd0f67535" + integrity sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q== + dependencies: + "@types/node" "*" + +"@types/unist@*", "@types/unist@^3.0.0": + version "3.0.2" + resolved "https://registry.npmmirror.com/@types/unist/-/unist-3.0.2.tgz#6dd61e43ef60b34086287f83683a5c1b2dc53d20" + integrity sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ== + +"@types/unist@^2.0.0": + version "2.0.10" + resolved "https://registry.npmmirror.com/@types/unist/-/unist-2.0.10.tgz#04ffa7f406ab628f7f7e97ca23e290cd8ab15efc" + integrity sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA== + +"@types/ws@^8.5.5": + version "8.5.10" + resolved "https://registry.npmmirror.com/@types/ws/-/ws-8.5.10.tgz#4acfb517970853fa6574a3a6886791d04a396787" + integrity sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A== + dependencies: + "@types/node" "*" + +"@types/yargs-parser@*": + version "21.0.3" + resolved "https://registry.npmmirror.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" + integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== + +"@types/yargs@^17.0.8": + version "17.0.32" + resolved "https://registry.npmmirror.com/@types/yargs/-/yargs-17.0.32.tgz#030774723a2f7faafebf645f4e5a48371dca6229" + integrity sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog== + dependencies: + "@types/yargs-parser" "*" + +"@ungap/structured-clone@^1.0.0": + version "1.2.0" + resolved "https://registry.npmmirror.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" + integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== + +"@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.12.1": + version "1.12.1" + resolved "https://registry.npmmirror.com/@webassemblyjs/ast/-/ast-1.12.1.tgz#bb16a0e8b1914f979f45864c23819cc3e3f0d4bb" + integrity sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + +"@webassemblyjs/floating-point-hex-parser@1.11.6": + version "1.11.6" + resolved "https://registry.npmmirror.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz#dacbcb95aff135c8260f77fa3b4c5fea600a6431" + integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw== + +"@webassemblyjs/helper-api-error@1.11.6": + version "1.11.6" + resolved "https://registry.npmmirror.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" + integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== + +"@webassemblyjs/helper-buffer@1.12.1": + version "1.12.1" + resolved "https://registry.npmmirror.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz#6df20d272ea5439bf20ab3492b7fb70e9bfcb3f6" + integrity sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw== + +"@webassemblyjs/helper-numbers@1.11.6": + version "1.11.6" + resolved "https://registry.npmmirror.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz#cbce5e7e0c1bd32cf4905ae444ef64cea919f1b5" + integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/helper-wasm-bytecode@1.11.6": + version "1.11.6" + resolved "https://registry.npmmirror.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" + integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== + +"@webassemblyjs/helper-wasm-section@1.12.1": + version "1.12.1" + resolved "https://registry.npmmirror.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz#3da623233ae1a60409b509a52ade9bc22a37f7bf" + integrity sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/wasm-gen" "1.12.1" + +"@webassemblyjs/ieee754@1.11.6": + version "1.11.6" + resolved "https://registry.npmmirror.com/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz#bb665c91d0b14fffceb0e38298c329af043c6e3a" + integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.11.6": + version "1.11.6" + resolved "https://registry.npmmirror.com/@webassemblyjs/leb128/-/leb128-1.11.6.tgz#70e60e5e82f9ac81118bc25381a0b283893240d7" + integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.11.6": + version "1.11.6" + resolved "https://registry.npmmirror.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" + integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== + +"@webassemblyjs/wasm-edit@^1.12.1": + version "1.12.1" + resolved "https://registry.npmmirror.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz#9f9f3ff52a14c980939be0ef9d5df9ebc678ae3b" + integrity sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/helper-wasm-section" "1.12.1" + "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/wasm-opt" "1.12.1" + "@webassemblyjs/wasm-parser" "1.12.1" + "@webassemblyjs/wast-printer" "1.12.1" + +"@webassemblyjs/wasm-gen@1.12.1": + version "1.12.1" + resolved "https://registry.npmmirror.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz#a6520601da1b5700448273666a71ad0a45d78547" + integrity sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wasm-opt@1.12.1": + version "1.12.1" + resolved "https://registry.npmmirror.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz#9e6e81475dfcfb62dab574ac2dda38226c232bc5" + integrity sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/wasm-parser" "1.12.1" + +"@webassemblyjs/wasm-parser@1.12.1", "@webassemblyjs/wasm-parser@^1.12.1": + version "1.12.1" + resolved "https://registry.npmmirror.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz#c47acb90e6f083391e3fa61d113650eea1e95937" + integrity sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-api-error" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wast-printer@1.12.1": + version "1.12.1" + resolved "https://registry.npmmirror.com/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz#bcecf661d7d1abdaf989d8341a4833e33e2b31ac" + integrity sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.npmmirror.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.npmmirror.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.npmmirror.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.npmmirror.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn-jsx@^5.0.0: + version "5.3.2" + resolved "https://registry.npmmirror.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn-walk@^8.0.0: + version "8.3.2" + resolved "https://registry.npmmirror.com/acorn-walk/-/acorn-walk-8.3.2.tgz#7703af9415f1b6db9315d6895503862e231d34aa" + integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== + +acorn@^8.0.0, acorn@^8.0.4, acorn@^8.7.1, acorn@^8.8.2: + version "8.11.3" + resolved "https://registry.npmmirror.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" + integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== + +address@^1.0.1, address@^1.1.2: + version "1.2.2" + resolved "https://registry.npmmirror.com/address/-/address-1.2.2.tgz#2b5248dac5485a6390532c6a517fda2e3faac89e" + integrity sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA== + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.npmmirror.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ajv-formats@^2.1.1: + version "2.1.1" + resolved "https://registry.npmmirror.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" + +ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv-keywords@^5.1.0: + version "5.1.0" + resolved "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" + integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== + dependencies: + fast-deep-equal "^3.1.3" + +ajv@^6.12.2, ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.0, ajv@^8.9.0: + version "8.12.0" + resolved "https://registry.npmmirror.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" + integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +algoliasearch-helper@^3.13.3: + version "3.16.3" + resolved "https://registry.npmmirror.com/algoliasearch-helper/-/algoliasearch-helper-3.16.3.tgz#38c3a18e278306f565823cc7f3dd706825b4bfb9" + integrity sha512-1OuJT6sONAa9PxcOmWo5WCAT3jQSpCR9/m5Azujja7nhUQwAUDvaaAYrcmUySsrvHh74usZHbE3jFfGnWtZj8w== + dependencies: + "@algolia/events" "^4.0.1" + +algoliasearch@^4.18.0, algoliasearch@^4.19.1: + version "4.23.2" + resolved "https://registry.npmmirror.com/algoliasearch/-/algoliasearch-4.23.2.tgz#3b7bc93d98f3965628c73a06cbf9203531324a9d" + integrity sha512-8aCl055IsokLuPU8BzLjwzXjb7ty9TPcUFFOk0pYOwsE5DMVhE3kwCMFtsCFKcnoPZK7oObm+H5mbnSO/9ioxQ== + dependencies: + "@algolia/cache-browser-local-storage" "4.23.2" + "@algolia/cache-common" "4.23.2" + "@algolia/cache-in-memory" "4.23.2" + "@algolia/client-account" "4.23.2" + "@algolia/client-analytics" "4.23.2" + "@algolia/client-common" "4.23.2" + "@algolia/client-personalization" "4.23.2" + "@algolia/client-search" "4.23.2" + "@algolia/logger-common" "4.23.2" + "@algolia/logger-console" "4.23.2" + "@algolia/recommend" "4.23.2" + "@algolia/requester-browser-xhr" "4.23.2" + "@algolia/requester-common" "4.23.2" + "@algolia/requester-node-http" "4.23.2" + "@algolia/transporter" "4.23.2" + +ansi-align@^3.0.1: + version "3.0.1" + resolved "https://registry.npmmirror.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" + integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== + dependencies: + string-width "^4.1.0" + +ansi-html-community@^0.0.8: + version "0.0.8" + resolved "https://registry.npmmirror.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" + integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +arg@^5.0.0: + version "5.0.2" + resolved "https://registry.npmmirror.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c" + integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.npmmirror.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.npmmirror.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +astring@^1.8.0: + version "1.8.6" + resolved "https://registry.npmmirror.com/astring/-/astring-1.8.6.tgz#2c9c157cf1739d67561c56ba896e6948f6b93731" + integrity sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg== + +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + +autoprefixer@^10.4.12, autoprefixer@^10.4.14: + version "10.4.19" + resolved "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.19.tgz#ad25a856e82ee9d7898c59583c1afeb3fa65f89f" + integrity sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew== + dependencies: + browserslist "^4.23.0" + caniuse-lite "^1.0.30001599" + fraction.js "^4.3.7" + normalize-range "^0.1.2" + picocolors "^1.0.0" + postcss-value-parser "^4.2.0" + +babel-loader@^9.1.3: + version "9.1.3" + resolved "https://registry.npmmirror.com/babel-loader/-/babel-loader-9.1.3.tgz#3d0e01b4e69760cc694ee306fe16d358aa1c6f9a" + integrity sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw== + dependencies: + find-cache-dir "^4.0.0" + schema-utils "^4.0.0" + +babel-plugin-dynamic-import-node@^2.3.3: + version "2.3.3" + resolved "https://registry.npmmirror.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" + integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== + dependencies: + object.assign "^4.1.0" + +babel-plugin-polyfill-corejs2@^0.4.10: + version "0.4.10" + resolved "https://registry.npmmirror.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.10.tgz#276f41710b03a64f6467433cab72cbc2653c38b1" + integrity sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ== + dependencies: + "@babel/compat-data" "^7.22.6" + "@babel/helper-define-polyfill-provider" "^0.6.1" + semver "^6.3.1" + +babel-plugin-polyfill-corejs3@^0.10.1, babel-plugin-polyfill-corejs3@^0.10.4: + version "0.10.4" + resolved "https://registry.npmmirror.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz#789ac82405ad664c20476d0233b485281deb9c77" + integrity sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.6.1" + core-js-compat "^3.36.1" + +babel-plugin-polyfill-regenerator@^0.6.1: + version "0.6.1" + resolved "https://registry.npmmirror.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.1.tgz#4f08ef4c62c7a7f66a35ed4c0d75e30506acc6be" + integrity sha512-JfTApdE++cgcTWjsiCQlLyFBMbTUft9ja17saCc93lgV33h4tuCVj7tlvu//qpLwaG+3yEz7/KhahGrUMkVq9g== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.6.1" + +bail@^2.0.0: + version "2.0.2" + resolved "https://registry.npmmirror.com/bail/-/bail-2.0.2.tgz#d26f5cd8fe5d6f832a31517b9f7c356040ba6d5d" + integrity sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.npmmirror.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.npmmirror.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^2.0.0: + version "2.3.0" + resolved "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" + integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== + +body-parser@1.20.2: + version "1.20.2" + resolved "https://registry.npmmirror.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" + integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== + dependencies: + bytes "3.1.2" + content-type "~1.0.5" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.2" + type-is "~1.6.18" + unpipe "1.0.0" + +bonjour-service@^1.0.11: + version "1.2.1" + resolved "https://registry.npmmirror.com/bonjour-service/-/bonjour-service-1.2.1.tgz#eb41b3085183df3321da1264719fbada12478d02" + integrity sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw== + dependencies: + fast-deep-equal "^3.1.3" + multicast-dns "^7.2.5" + +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + +boxen@^6.2.1: + version "6.2.1" + resolved "https://registry.npmmirror.com/boxen/-/boxen-6.2.1.tgz#b098a2278b2cd2845deef2dff2efc38d329b434d" + integrity sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw== + dependencies: + ansi-align "^3.0.1" + camelcase "^6.2.0" + chalk "^4.1.2" + cli-boxes "^3.0.0" + string-width "^5.0.1" + type-fest "^2.5.0" + widest-line "^4.0.1" + wrap-ansi "^8.0.1" + +boxen@^7.0.0: + version "7.1.1" + resolved "https://registry.npmmirror.com/boxen/-/boxen-7.1.1.tgz#f9ba525413c2fec9cdb88987d835c4f7cad9c8f4" + integrity sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog== + dependencies: + ansi-align "^3.0.1" + camelcase "^7.0.1" + chalk "^5.2.0" + cli-boxes "^3.0.0" + string-width "^5.1.2" + type-fest "^2.13.0" + widest-line "^4.0.1" + wrap-ansi "^8.1.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.npmmirror.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browserslist@^4.0.0, browserslist@^4.18.1, browserslist@^4.21.10, browserslist@^4.21.4, browserslist@^4.22.2, browserslist@^4.23.0: + version "4.23.0" + resolved "https://registry.npmmirror.com/browserslist/-/browserslist-4.23.0.tgz#8f3acc2bbe73af7213399430890f86c63a5674ab" + integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ== + dependencies: + caniuse-lite "^1.0.30001587" + electron-to-chromium "^1.4.668" + node-releases "^2.0.14" + update-browserslist-db "^1.0.13" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.npmmirror.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +cacheable-lookup@^7.0.0: + version "7.0.0" + resolved "https://registry.npmmirror.com/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz#3476a8215d046e5a3202a9209dd13fec1f933a27" + integrity sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w== + +cacheable-request@^10.2.8: + version "10.2.14" + resolved "https://registry.npmmirror.com/cacheable-request/-/cacheable-request-10.2.14.tgz#eb915b665fda41b79652782df3f553449c406b9d" + integrity sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ== + dependencies: + "@types/http-cache-semantics" "^4.0.2" + get-stream "^6.0.1" + http-cache-semantics "^4.1.1" + keyv "^4.5.3" + mimic-response "^4.0.0" + normalize-url "^8.0.0" + responselike "^3.0.0" + +call-bind@^1.0.5, call-bind@^1.0.7: + version "1.0.7" + resolved "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camel-case@^4.1.2: + version "4.1.2" + resolved "https://registry.npmmirror.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" + integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== + dependencies: + pascal-case "^3.1.2" + tslib "^2.0.3" + +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.npmmirror.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +camelcase@^7.0.1: + version "7.0.1" + resolved "https://registry.npmmirror.com/camelcase/-/camelcase-7.0.1.tgz#f02e50af9fd7782bc8b88a3558c32fd3a388f048" + integrity sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw== + +caniuse-api@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" + integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== + dependencies: + browserslist "^4.0.0" + caniuse-lite "^1.0.0" + lodash.memoize "^4.1.2" + lodash.uniq "^4.5.0" + +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001587, caniuse-lite@^1.0.30001599: + version "1.0.30001600" + resolved "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001600.tgz#93a3ee17a35aa6a9f0c6ef1b2ab49507d1ab9079" + integrity sha512-+2S9/2JFhYmYaDpZvo0lKkfvuKIglrx68MwOBqMGHhQsNkLjB5xtc/TGoEPs+MxjSyN/72qer2g97nzR641mOQ== + +ccount@^2.0.0: + version "2.0.1" + resolved "https://registry.npmmirror.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5" + integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg== + +chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chalk@^5.0.1, chalk@^5.2.0: + version "5.3.0" + resolved "https://registry.npmmirror.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385" + integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w== + +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + +character-entities-html4@^2.0.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/character-entities-html4/-/character-entities-html4-2.1.0.tgz#1f1adb940c971a4b22ba39ddca6b618dc6e56b2b" + integrity sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA== + +character-entities-legacy@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz#76bc83a90738901d7bc223a9e93759fdd560125b" + integrity sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ== + +character-entities@^2.0.0: + version "2.0.2" + resolved "https://registry.npmmirror.com/character-entities/-/character-entities-2.0.2.tgz#2d09c2e72cd9523076ccb21157dff66ad43fcc22" + integrity sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ== + +character-reference-invalid@^2.0.0: + version "2.0.1" + resolved "https://registry.npmmirror.com/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz#85c66b041e43b47210faf401278abf808ac45cb9" + integrity sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw== + +cheerio-select@^2.1.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/cheerio-select/-/cheerio-select-2.1.0.tgz#4d8673286b8126ca2a8e42740d5e3c4884ae21b4" + 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" + +cheerio@^1.0.0-rc.12: + version "1.0.0-rc.12" + resolved "https://registry.npmmirror.com/cheerio/-/cheerio-1.0.0-rc.12.tgz#788bf7466506b1c6bf5fae51d24a2c4d62e47683" + integrity sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q== + 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.0.0" + parse5-htmlparser2-tree-adapter "^7.0.0" + +chokidar@^3.4.2, chokidar@^3.5.3: + version "3.6.0" + resolved "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.npmmirror.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +ci-info@^3.2.0: + version "3.9.0" + resolved "https://registry.npmmirror.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" + integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== + +clean-css@^5.2.2, clean-css@^5.3.2, clean-css@~5.3.2: + version "5.3.3" + resolved "https://registry.npmmirror.com/clean-css/-/clean-css-5.3.3.tgz#b330653cd3bd6b75009cc25c714cae7b93351ccd" + integrity sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg== + dependencies: + source-map "~0.6.0" + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.npmmirror.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-boxes@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/cli-boxes/-/cli-boxes-3.0.0.tgz#71a10c716feeba005e4504f36329ef0b17cf3145" + integrity sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g== + +cli-table3@^0.6.3: + version "0.6.4" + resolved "https://registry.npmmirror.com/cli-table3/-/cli-table3-0.6.4.tgz#d1c536b8a3f2e7bec58f67ac9e5769b1b30088b0" + integrity sha512-Lm3L0p+/npIQWNIiyF/nAn7T5dnOwR3xNTHXYEBFBFVPXzCVNZ5lqEC/1eo/EVfpDsQ1I+TX4ORPQgp+UI0CRw== + dependencies: + string-width "^4.2.0" + optionalDependencies: + "@colors/colors" "1.5.0" + +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.npmmirror.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + +clsx@^2.0.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/clsx/-/clsx-2.1.0.tgz#e851283bcb5c80ee7608db18487433f7b23f77cb" + integrity sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg== + +collapse-white-space@^2.0.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/collapse-white-space/-/collapse-white-space-2.1.0.tgz#640257174f9f42c740b40f3b55ee752924feefca" + integrity sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colord@^2.9.1: + version "2.9.3" + resolved "https://registry.npmmirror.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43" + integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw== + +colorette@^2.0.10: + version "2.0.20" + resolved "https://registry.npmmirror.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== + +combine-promises@^1.1.0: + version "1.2.0" + resolved "https://registry.npmmirror.com/combine-promises/-/combine-promises-1.2.0.tgz#5f2e68451862acf85761ded4d9e2af7769c2ca6a" + integrity sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ== + +comma-separated-tokens@^2.0.0: + version "2.0.3" + resolved "https://registry.npmmirror.com/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz#4e89c9458acb61bc8fef19f4529973b2392839ee" + integrity sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg== + +commander@^10.0.0: + version "10.0.1" + resolved "https://registry.npmmirror.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^5.1.0: + version "5.1.0" + resolved "https://registry.npmmirror.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" + integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== + +commander@^7.2.0: + version "7.2.0" + resolved "https://registry.npmmirror.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +commander@^8.3.0: + version "8.3.0" + resolved "https://registry.npmmirror.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== + +common-path-prefix@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz#7d007a7e07c58c4b4d5f433131a19141b29f11e0" + integrity sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w== + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.npmmirror.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.npmmirror.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +config-chain@^1.1.11: + version "1.1.13" + resolved "https://registry.npmmirror.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4" + integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ== + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + +configstore@^6.0.0: + version "6.0.0" + resolved "https://registry.npmmirror.com/configstore/-/configstore-6.0.0.tgz#49eca2ebc80983f77e09394a1a56e0aca8235566" + integrity sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA== + dependencies: + dot-prop "^6.0.1" + graceful-fs "^4.2.6" + unique-string "^3.0.0" + write-file-atomic "^3.0.3" + xdg-basedir "^5.0.1" + +connect-history-api-fallback@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" + integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== + +consola@^2.15.3: + version "2.15.3" + resolved "https://registry.npmmirror.com/consola/-/consola-2.15.3.tgz#2e11f98d6a4be71ff72e0bdf07bd23e12cb61550" + integrity sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw== + +content-disposition@0.5.2: + version "0.5.2" + resolved "https://registry.npmmirror.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" + integrity sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.npmmirror.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4, content-type@~1.0.5: + version "1.0.5" + resolved "https://registry.npmmirror.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.npmmirror.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.6.0: + version "0.6.0" + resolved "https://registry.npmmirror.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" + integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== + +copy-text-to-clipboard@^3.2.0: + version "3.2.0" + resolved "https://registry.npmmirror.com/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz#0202b2d9bdae30a49a53f898626dcc3b49ad960b" + integrity sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q== + +copy-webpack-plugin@^11.0.0: + version "11.0.0" + resolved "https://registry.npmmirror.com/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz#96d4dbdb5f73d02dd72d0528d1958721ab72e04a" + integrity sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ== + dependencies: + fast-glob "^3.2.11" + glob-parent "^6.0.1" + globby "^13.1.1" + normalize-path "^3.0.0" + schema-utils "^4.0.0" + serialize-javascript "^6.0.0" + +core-js-compat@^3.31.0, core-js-compat@^3.36.1: + version "3.36.1" + resolved "https://registry.npmmirror.com/core-js-compat/-/core-js-compat-3.36.1.tgz#1818695d72c99c25d621dca94e6883e190cea3c8" + integrity sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA== + dependencies: + browserslist "^4.23.0" + +core-js-pure@^3.30.2: + version "3.36.1" + resolved "https://registry.npmmirror.com/core-js-pure/-/core-js-pure-3.36.1.tgz#1461c89e76116528b54eba20a0aff30164087a94" + integrity sha512-NXCvHvSVYSrewP0L5OhltzXeWFJLo2AL2TYnj6iLV3Bw8mM62wAQMNgUCRI6EBu6hVVpbCxmOPlxh1Ikw2PfUA== + +core-js@^3.31.1: + version "3.36.1" + resolved "https://registry.npmmirror.com/core-js/-/core-js-3.36.1.tgz#c97a7160ebd00b2de19e62f4bbd3406ab720e578" + integrity sha512-BTvUrwxVBezj5SZ3f10ImnX2oRByMxql3EimVqMysepbC9EeMUOpLwdy6Eoili2x6E4kf+ZUB5k/+Jv55alPfA== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cosmiconfig@^6.0.0: + version "6.0.0" + resolved "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" + integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.7.2" + +cosmiconfig@^7.0.1: + version "7.1.0" + resolved "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" + integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" + +cosmiconfig@^8.3.5: + version "8.3.6" + resolved "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" + integrity sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA== + dependencies: + import-fresh "^3.3.0" + js-yaml "^4.1.0" + parse-json "^5.2.0" + path-type "^4.0.0" + +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +crypto-random-string@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/crypto-random-string/-/crypto-random-string-4.0.0.tgz#5a3cc53d7dd86183df5da0312816ceeeb5bb1fc2" + integrity sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA== + dependencies: + type-fest "^1.0.1" + +css-declaration-sorter@^6.3.1: + version "6.4.1" + resolved "https://registry.npmmirror.com/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz#28beac7c20bad7f1775be3a7129d7eae409a3a71" + integrity sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g== + +css-loader@^6.8.1: + version "6.10.0" + resolved "https://registry.npmmirror.com/css-loader/-/css-loader-6.10.0.tgz#7c172b270ec7b833951b52c348861206b184a4b7" + integrity sha512-LTSA/jWbwdMlk+rhmElbDR2vbtQoTBPr7fkJE+mxrHj+7ru0hUmHafDRzWIjIHTwpitWVaqY2/UWGRca3yUgRw== + dependencies: + icss-utils "^5.1.0" + postcss "^8.4.33" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.4" + postcss-modules-scope "^3.1.1" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.2.0" + semver "^7.5.4" + +css-minimizer-webpack-plugin@^4.2.2: + version "4.2.2" + resolved "https://registry.npmmirror.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-4.2.2.tgz#79f6199eb5adf1ff7ba57f105e3752d15211eb35" + integrity sha512-s3Of/4jKfw1Hj9CxEO1E5oXhQAxlayuHO2y/ML+C6I9sQ7FdzfEV6QgMLN3vI+qFsjJGIAFLKtQK7t8BOXAIyA== + dependencies: + cssnano "^5.1.8" + jest-worker "^29.1.2" + postcss "^8.4.17" + schema-utils "^4.0.0" + serialize-javascript "^6.0.0" + source-map "^0.6.1" + +css-select@^4.1.3: + version "4.3.0" + resolved "https://registry.npmmirror.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b" + integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ== + dependencies: + boolbase "^1.0.0" + css-what "^6.0.1" + domhandler "^4.3.1" + domutils "^2.8.0" + nth-check "^2.0.1" + +css-select@^5.1.0: + version "5.1.0" + resolved "https://registry.npmmirror.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" + integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg== + dependencies: + boolbase "^1.0.0" + css-what "^6.1.0" + domhandler "^5.0.2" + domutils "^3.0.1" + nth-check "^2.0.1" + +css-tree@^1.1.2, css-tree@^1.1.3: + version "1.1.3" + resolved "https://registry.npmmirror.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" + integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== + dependencies: + mdn-data "2.0.14" + source-map "^0.6.1" + +css-what@^6.0.1, css-what@^6.1.0: + version "6.1.0" + resolved "https://registry.npmmirror.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +cssnano-preset-advanced@^5.3.10: + version "5.3.10" + resolved "https://registry.npmmirror.com/cssnano-preset-advanced/-/cssnano-preset-advanced-5.3.10.tgz#25558a1fbf3a871fb6429ce71e41be7f5aca6eef" + integrity sha512-fnYJyCS9jgMU+cmHO1rPSPf9axbQyD7iUhLO5Df6O4G+fKIOMps+ZbU0PdGFejFBBZ3Pftf18fn1eG7MAPUSWQ== + dependencies: + autoprefixer "^10.4.12" + cssnano-preset-default "^5.2.14" + postcss-discard-unused "^5.1.0" + postcss-merge-idents "^5.1.1" + postcss-reduce-idents "^5.2.0" + postcss-zindex "^5.1.0" + +cssnano-preset-default@^5.2.14: + version "5.2.14" + resolved "https://registry.npmmirror.com/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz#309def4f7b7e16d71ab2438052093330d9ab45d8" + integrity sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A== + dependencies: + css-declaration-sorter "^6.3.1" + cssnano-utils "^3.1.0" + postcss-calc "^8.2.3" + postcss-colormin "^5.3.1" + postcss-convert-values "^5.1.3" + postcss-discard-comments "^5.1.2" + postcss-discard-duplicates "^5.1.0" + postcss-discard-empty "^5.1.1" + postcss-discard-overridden "^5.1.0" + postcss-merge-longhand "^5.1.7" + postcss-merge-rules "^5.1.4" + postcss-minify-font-values "^5.1.0" + postcss-minify-gradients "^5.1.1" + postcss-minify-params "^5.1.4" + postcss-minify-selectors "^5.2.1" + postcss-normalize-charset "^5.1.0" + postcss-normalize-display-values "^5.1.0" + postcss-normalize-positions "^5.1.1" + postcss-normalize-repeat-style "^5.1.1" + postcss-normalize-string "^5.1.0" + postcss-normalize-timing-functions "^5.1.0" + postcss-normalize-unicode "^5.1.1" + postcss-normalize-url "^5.1.0" + postcss-normalize-whitespace "^5.1.1" + postcss-ordered-values "^5.1.3" + postcss-reduce-initial "^5.1.2" + postcss-reduce-transforms "^5.1.0" + postcss-svgo "^5.1.0" + postcss-unique-selectors "^5.1.1" + +cssnano-utils@^3.1.0: + version "3.1.0" + resolved "https://registry.npmmirror.com/cssnano-utils/-/cssnano-utils-3.1.0.tgz#95684d08c91511edfc70d2636338ca37ef3a6861" + integrity sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA== + +cssnano@^5.1.15, cssnano@^5.1.8: + version "5.1.15" + resolved "https://registry.npmmirror.com/cssnano/-/cssnano-5.1.15.tgz#ded66b5480d5127fcb44dac12ea5a983755136bf" + integrity sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw== + dependencies: + cssnano-preset-default "^5.2.14" + lilconfig "^2.0.3" + yaml "^1.10.2" + +csso@^4.2.0: + version "4.2.0" + resolved "https://registry.npmmirror.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" + integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== + dependencies: + css-tree "^1.1.2" + +csstype@^3.0.2: + version "3.1.3" + resolved "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" + integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== + +debounce@^1.2.1: + version "1.2.1" + resolved "https://registry.npmmirror.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" + integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== + +debug@2.6.9, debug@^2.6.0: + version "2.6.9" + resolved "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: + version "4.3.4" + resolved "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +decode-named-character-reference@^1.0.0: + version "1.0.2" + resolved "https://registry.npmmirror.com/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz#daabac9690874c394c81e4162a0304b35d824f0e" + integrity sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg== + dependencies: + character-entities "^2.0.0" + +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.npmmirror.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.npmmirror.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deepmerge@^4.2.2: + version "4.3.1" + resolved "https://registry.npmmirror.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + +default-gateway@^6.0.3: + version "6.0.3" + resolved "https://registry.npmmirror.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" + integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== + dependencies: + execa "^5.0.0" + +defer-to-connect@^2.0.1: + version "2.0.1" + resolved "https://registry.npmmirror.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" + integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== + +define-data-property@^1.0.1, define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.npmmirror.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + +define-properties@^1.2.1: + version "1.2.1" + resolved "https://registry.npmmirror.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" + integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== + dependencies: + define-data-property "^1.0.1" + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + +del@^6.1.1: + version "6.1.1" + resolved "https://registry.npmmirror.com/del/-/del-6.1.1.tgz#3b70314f1ec0aa325c6b14eb36b95786671edb7a" + integrity sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg== + dependencies: + globby "^11.0.1" + graceful-fs "^4.2.4" + is-glob "^4.0.1" + is-path-cwd "^2.2.0" + is-path-inside "^3.0.2" + p-map "^4.0.0" + rimraf "^3.0.2" + slash "^3.0.0" + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.npmmirror.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== + +dequal@^2.0.0: + version "2.0.3" + resolved "https://registry.npmmirror.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" + integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.npmmirror.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +detect-node@^2.0.4: + version "2.1.0" + resolved "https://registry.npmmirror.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== + +detect-port-alt@^1.1.6: + version "1.1.6" + resolved "https://registry.npmmirror.com/detect-port-alt/-/detect-port-alt-1.1.6.tgz#24707deabe932d4a3cf621302027c2b266568275" + integrity sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q== + dependencies: + address "^1.0.1" + debug "^2.6.0" + +detect-port@^1.5.1: + version "1.5.1" + resolved "https://registry.npmmirror.com/detect-port/-/detect-port-1.5.1.tgz#451ca9b6eaf20451acb0799b8ab40dff7718727b" + integrity sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ== + dependencies: + address "^1.0.1" + debug "4" + +devlop@^1.0.0, devlop@^1.1.0: + version "1.1.0" + resolved "https://registry.npmmirror.com/devlop/-/devlop-1.1.0.tgz#4db7c2ca4dc6e0e834c30be70c94bbc976dc7018" + integrity sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA== + dependencies: + dequal "^2.0.0" + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +dns-packet@^5.2.2: + version "5.6.1" + resolved "https://registry.npmmirror.com/dns-packet/-/dns-packet-5.6.1.tgz#ae888ad425a9d1478a0674256ab866de1012cf2f" + integrity sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw== + dependencies: + "@leichtgewicht/ip-codec" "^2.0.1" + +dom-converter@^0.2.0: + version "0.2.0" + resolved "https://registry.npmmirror.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" + integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== + dependencies: + utila "~0.4" + +dom-serializer@^1.0.1: + version "1.4.1" + resolved "https://registry.npmmirror.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30" + integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.2.0" + entities "^2.0.0" + +dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" + +domelementtype@^2.0.1, domelementtype@^2.2.0, domelementtype@^2.3.0: + version "2.3.0" + resolved "https://registry.npmmirror.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1: + version "4.3.1" + resolved "https://registry.npmmirror.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" + integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== + dependencies: + domelementtype "^2.2.0" + +domhandler@^5.0.2, domhandler@^5.0.3: + version "5.0.3" + resolved "https://registry.npmmirror.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== + dependencies: + domelementtype "^2.3.0" + +domutils@^2.5.2, domutils@^2.8.0: + version "2.8.0" + resolved "https://registry.npmmirror.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" + integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + +domutils@^3.0.1: + version "3.1.0" + resolved "https://registry.npmmirror.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e" + integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA== + dependencies: + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + +dot-case@^3.0.4: + version "3.0.4" + resolved "https://registry.npmmirror.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" + integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + +dot-prop@^6.0.1: + version "6.0.1" + resolved "https://registry.npmmirror.com/dot-prop/-/dot-prop-6.0.1.tgz#fc26b3cf142b9e59b74dbd39ed66ce620c681083" + integrity sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA== + dependencies: + is-obj "^2.0.0" + +duplexer@^0.1.2: + version "0.1.2" + resolved "https://registry.npmmirror.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" + integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== + +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.npmmirror.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +electron-to-chromium@^1.4.668: + version "1.4.719" + resolved "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.719.tgz#22a94ce7a5150511ba88e900836039e159efe22c" + integrity sha512-FbWy2Q2YgdFzkFUW/W5jBjE9dj+804+98E4Pup78JBPnbdb3pv6IneY2JCPKdeKLh3AOKHQeYf+KwLr7mxGh6Q== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + +emojilib@^2.4.0: + version "2.4.0" + resolved "https://registry.npmmirror.com/emojilib/-/emojilib-2.4.0.tgz#ac518a8bb0d5f76dda57289ccb2fdf9d39ae721e" + integrity sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw== + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +emoticon@^4.0.1: + version "4.0.1" + resolved "https://registry.npmmirror.com/emoticon/-/emoticon-4.0.1.tgz#2d2bbbf231ce3a5909e185bbb64a9da703a1e749" + integrity sha512-dqx7eA9YaqyvYtUhJwT4rC1HIp82j5ybS1/vQ42ur+jBe17dJMwZE4+gvL1XadSFfxaPFFGt3Xsw+Y8akThDlw== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +enhanced-resolve@^5.16.0: + version "5.16.0" + resolved "https://registry.npmmirror.com/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz#65ec88778083056cb32487faa9aef82ed0864787" + integrity sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +entities@^2.0.0: + version "2.2.0" + resolved "https://registry.npmmirror.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + +entities@^4.2.0, entities@^4.4.0: + version "4.5.0" + resolved "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.npmmirror.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== + dependencies: + get-intrinsic "^1.2.4" + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +es-module-lexer@^1.2.1: + version "1.5.0" + resolved "https://registry.npmmirror.com/es-module-lexer/-/es-module-lexer-1.5.0.tgz#4878fee3789ad99e065f975fdd3c645529ff0236" + integrity sha512-pqrTKmwEIgafsYZAGw9kszYzmagcE/n4dbgwGWLEXg7J4QFJVQRBld8j3Q3GNez79jzxZshq0bcT962QHOghjw== + +escalade@^3.1.1: + version "3.1.2" + resolved "https://registry.npmmirror.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" + integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== + +escape-goat@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/escape-goat/-/escape-goat-4.0.0.tgz#9424820331b510b0666b98f7873fe11ac4aa8081" + integrity sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg== + +escape-html@^1.0.3, escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +escape-string-regexp@^5.0.0: + version "5.0.0" + resolved "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz#4683126b500b61762f2dbebace1806e8be31b1c8" + integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw== + +eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.npmmirror.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.npmmirror.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.npmmirror.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +estree-util-attach-comments@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz#344bde6a64c8a31d15231e5ee9e297566a691c2d" + integrity sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw== + dependencies: + "@types/estree" "^1.0.0" + +estree-util-build-jsx@^3.0.0: + version "3.0.1" + resolved "https://registry.npmmirror.com/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz#b6d0bced1dcc4f06f25cf0ceda2b2dcaf98168f1" + integrity sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ== + dependencies: + "@types/estree-jsx" "^1.0.0" + devlop "^1.0.0" + estree-util-is-identifier-name "^3.0.0" + estree-walker "^3.0.0" + +estree-util-is-identifier-name@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz#0b5ef4c4ff13508b34dcd01ecfa945f61fce5dbd" + integrity sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg== + +estree-util-to-js@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz#10a6fb924814e6abb62becf0d2bc4dea51d04f17" + integrity sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg== + dependencies: + "@types/estree-jsx" "^1.0.0" + astring "^1.8.0" + source-map "^0.7.0" + +estree-util-value-to-estree@^3.0.1: + version "3.0.1" + resolved "https://registry.npmmirror.com/estree-util-value-to-estree/-/estree-util-value-to-estree-3.0.1.tgz#0b7b5d6b6a4aaad5c60999ffbc265a985df98ac5" + integrity sha512-b2tdzTurEIbwRh+mKrEcaWfu1wgb8J1hVsgREg7FFiecWwK/PhO8X0kyc+0bIcKNtD4sqxIdNoRy6/p/TvECEA== + dependencies: + "@types/estree" "^1.0.0" + is-plain-obj "^4.0.0" + +estree-util-visit@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/estree-util-visit/-/estree-util-visit-2.0.0.tgz#13a9a9f40ff50ed0c022f831ddf4b58d05446feb" + integrity sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww== + dependencies: + "@types/estree-jsx" "^1.0.0" + "@types/unist" "^3.0.0" + +estree-walker@^3.0.0: + version "3.0.3" + resolved "https://registry.npmmirror.com/estree-walker/-/estree-walker-3.0.3.tgz#67c3e549ec402a487b4fc193d1953a524752340d" + integrity sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g== + dependencies: + "@types/estree" "^1.0.0" + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.npmmirror.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +eta@^2.2.0: + version "2.2.0" + resolved "https://registry.npmmirror.com/eta/-/eta-2.2.0.tgz#eb8b5f8c4e8b6306561a455e62cd7492fe3a9b8a" + integrity sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.npmmirror.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +eval@^0.1.8: + version "0.1.8" + resolved "https://registry.npmmirror.com/eval/-/eval-0.1.8.tgz#2b903473b8cc1d1989b83a1e7923f883eb357f85" + integrity sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw== + dependencies: + "@types/node" "*" + require-like ">= 0.1.1" + +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +events@^3.2.0: + version "3.3.0" + resolved "https://registry.npmmirror.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.npmmirror.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +express@^4.17.3: + version "4.19.2" + resolved "https://registry.npmmirror.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465" + integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.2" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.6.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.npmmirror.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== + dependencies: + is-extendable "^0.1.0" + +extend@^3.0.0: + version "3.0.2" + resolved "https://registry.npmmirror.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.2.11, fast-glob@^3.2.9, fast-glob@^3.3.0: + version "3.3.2" + resolved "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-url-parser@1.1.3: + version "1.1.3" + resolved "https://registry.npmmirror.com/fast-url-parser/-/fast-url-parser-1.1.3.tgz#f4af3ea9f34d8a271cf58ad2b3759f431f0b318d" + integrity sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ== + dependencies: + punycode "^1.3.2" + +fastq@^1.6.0: + version "1.17.1" + resolved "https://registry.npmmirror.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" + integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== + dependencies: + reusify "^1.0.4" + +fault@^2.0.0: + version "2.0.1" + resolved "https://registry.npmmirror.com/fault/-/fault-2.0.1.tgz#d47ca9f37ca26e4bd38374a7c500b5a384755b6c" + integrity sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ== + dependencies: + format "^0.2.0" + +faye-websocket@^0.11.3: + version "0.11.4" + resolved "https://registry.npmmirror.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== + dependencies: + websocket-driver ">=0.5.1" + +feed@^4.2.2: + version "4.2.2" + resolved "https://registry.npmmirror.com/feed/-/feed-4.2.2.tgz#865783ef6ed12579e2c44bbef3c9113bc4956a7e" + integrity sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ== + dependencies: + xml-js "^1.6.11" + +file-loader@^6.2.0: + version "6.2.0" + resolved "https://registry.npmmirror.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" + integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + +filesize@^8.0.6: + version "8.0.7" + resolved "https://registry.npmmirror.com/filesize/-/filesize-8.0.7.tgz#695e70d80f4e47012c132d57a059e80c6b580bd8" + integrity sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ== + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.npmmirror.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.npmmirror.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +find-cache-dir@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/find-cache-dir/-/find-cache-dir-4.0.0.tgz#a30ee0448f81a3990708f6453633c733e2f6eec2" + integrity sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg== + dependencies: + common-path-prefix "^3.0.0" + pkg-dir "^7.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +find-up@^6.3.0: + version "6.3.0" + resolved "https://registry.npmmirror.com/find-up/-/find-up-6.3.0.tgz#2abab3d3280b2dc7ac10199ef324c4e002c8c790" + integrity sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw== + dependencies: + locate-path "^7.1.0" + path-exists "^5.0.0" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.npmmirror.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +follow-redirects@^1.0.0: + version "1.15.6" + resolved "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" + integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== + +fork-ts-checker-webpack-plugin@^6.5.0: + version "6.5.3" + resolved "https://registry.npmmirror.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz#eda2eff6e22476a2688d10661688c47f611b37f3" + integrity sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ== + dependencies: + "@babel/code-frame" "^7.8.3" + "@types/json-schema" "^7.0.5" + chalk "^4.1.0" + chokidar "^3.4.2" + cosmiconfig "^6.0.0" + deepmerge "^4.2.2" + fs-extra "^9.0.0" + glob "^7.1.6" + memfs "^3.1.2" + minimatch "^3.0.4" + schema-utils "2.7.0" + semver "^7.3.2" + tapable "^1.0.0" + +form-data-encoder@^2.1.2: + version "2.1.4" + resolved "https://registry.npmmirror.com/form-data-encoder/-/form-data-encoder-2.1.4.tgz#261ea35d2a70d48d30ec7a9603130fa5515e9cd5" + integrity sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw== + +format@^0.2.0: + version "0.2.2" + resolved "https://registry.npmmirror.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b" + integrity sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww== + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.npmmirror.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fraction.js@^4.3.7: + version "4.3.7" + resolved "https://registry.npmmirror.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7" + integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.npmmirror.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +fs-extra@^11.1.1: + version "11.2.0" + resolved "https://registry.npmmirror.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" + integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-extra@^9.0.0: + version "9.1.0" + resolved "https://registry.npmmirror.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-monkey@^1.0.4: + version "1.0.5" + resolved "https://registry.npmmirror.com/fs-monkey/-/fs-monkey-1.0.5.tgz#fe450175f0db0d7ea758102e1d84096acb925788" + integrity sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-intrinsic@^1.1.3, get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + +get-own-enumerable-property-symbols@^3.0.0: + version "3.0.2" + resolved "https://registry.npmmirror.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" + integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== + +get-stream@^6.0.0, get-stream@^6.0.1: + version "6.0.1" + resolved "https://registry.npmmirror.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +github-slugger@^1.5.0: + version "1.5.0" + resolved "https://registry.npmmirror.com/github-slugger/-/github-slugger-1.5.0.tgz#17891bbc73232051474d68bd867a34625c955f7d" + integrity sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw== + +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.1: + version "6.0.2" + resolved "https://registry.npmmirror.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.npmmirror.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +glob@^7.0.0, glob@^7.1.3, glob@^7.1.6: + version "7.2.3" + resolved "https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-dirs@^3.0.0: + version "3.0.1" + resolved "https://registry.npmmirror.com/global-dirs/-/global-dirs-3.0.1.tgz#0c488971f066baceda21447aecb1a8b911d22485" + integrity sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA== + dependencies: + ini "2.0.0" + +global-modules@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" + integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== + dependencies: + global-prefix "^3.0.0" + +global-prefix@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" + integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== + dependencies: + ini "^1.3.5" + kind-of "^6.0.2" + which "^1.3.1" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.npmmirror.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globby@^11.0.1, globby@^11.0.4, globby@^11.1.0: + version "11.1.0" + resolved "https://registry.npmmirror.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +globby@^13.1.1: + version "13.2.2" + resolved "https://registry.npmmirror.com/globby/-/globby-13.2.2.tgz#63b90b1bf68619c2135475cbd4e71e66aa090592" + integrity sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w== + dependencies: + dir-glob "^3.0.1" + fast-glob "^3.3.0" + ignore "^5.2.4" + merge2 "^1.4.1" + slash "^4.0.0" + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +got@^12.1.0: + version "12.6.1" + resolved "https://registry.npmmirror.com/got/-/got-12.6.1.tgz#8869560d1383353204b5a9435f782df9c091f549" + integrity sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ== + dependencies: + "@sindresorhus/is" "^5.2.0" + "@szmarczak/http-timer" "^5.0.1" + cacheable-lookup "^7.0.0" + cacheable-request "^10.2.8" + decompress-response "^6.0.0" + form-data-encoder "^2.1.2" + get-stream "^6.0.1" + http2-wrapper "^2.1.10" + lowercase-keys "^3.0.0" + p-cancelable "^3.0.0" + responselike "^3.0.0" + +graceful-fs@4.2.10: + version "4.2.10" + resolved "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: + version "4.2.11" + resolved "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +gray-matter@^4.0.3: + version "4.0.3" + resolved "https://registry.npmmirror.com/gray-matter/-/gray-matter-4.0.3.tgz#e893c064825de73ea1f5f7d88c7a9f7274288798" + integrity sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q== + dependencies: + js-yaml "^3.13.1" + kind-of "^6.0.2" + section-matter "^1.0.0" + strip-bom-string "^1.0.0" + +gzip-size@^6.0.0: + version "6.0.0" + resolved "https://registry.npmmirror.com/gzip-size/-/gzip-size-6.0.0.tgz#065367fd50c239c0671cbcbad5be3e2eeb10e462" + integrity sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q== + dependencies: + duplexer "^0.1.2" + +handle-thing@^2.0.0: + version "2.0.1" + resolved "https://registry.npmmirror.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" + integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + +has-proto@^1.0.1: + version "1.0.3" + resolved "https://registry.npmmirror.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" + integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== + +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-yarn@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/has-yarn/-/has-yarn-3.0.0.tgz#c3c21e559730d1d3b57e28af1f30d06fac38147d" + integrity sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA== + +hasown@^2.0.0: + version "2.0.2" + resolved "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + +hast-util-from-parse5@^8.0.0: + version "8.0.1" + resolved "https://registry.npmmirror.com/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz#654a5676a41211e14ee80d1b1758c399a0327651" + integrity sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ== + dependencies: + "@types/hast" "^3.0.0" + "@types/unist" "^3.0.0" + devlop "^1.0.0" + hastscript "^8.0.0" + property-information "^6.0.0" + vfile "^6.0.0" + vfile-location "^5.0.0" + web-namespaces "^2.0.0" + +hast-util-parse-selector@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz#352879fa86e25616036037dd8931fb5f34cb4a27" + integrity sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A== + dependencies: + "@types/hast" "^3.0.0" + +hast-util-raw@^9.0.0: + version "9.0.2" + resolved "https://registry.npmmirror.com/hast-util-raw/-/hast-util-raw-9.0.2.tgz#39b4a4886bd9f0a5dd42e86d02c966c2c152884c" + integrity sha512-PldBy71wO9Uq1kyaMch9AHIghtQvIwxBUkv823pKmkTM3oV1JxtsTNYdevMxvUHqcnOAuO65JKU2+0NOxc2ksA== + dependencies: + "@types/hast" "^3.0.0" + "@types/unist" "^3.0.0" + "@ungap/structured-clone" "^1.0.0" + hast-util-from-parse5 "^8.0.0" + hast-util-to-parse5 "^8.0.0" + html-void-elements "^3.0.0" + mdast-util-to-hast "^13.0.0" + parse5 "^7.0.0" + unist-util-position "^5.0.0" + unist-util-visit "^5.0.0" + vfile "^6.0.0" + web-namespaces "^2.0.0" + zwitch "^2.0.0" + +hast-util-to-estree@^3.0.0: + version "3.1.0" + resolved "https://registry.npmmirror.com/hast-util-to-estree/-/hast-util-to-estree-3.1.0.tgz#f2afe5e869ddf0cf690c75f9fc699f3180b51b19" + integrity sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw== + dependencies: + "@types/estree" "^1.0.0" + "@types/estree-jsx" "^1.0.0" + "@types/hast" "^3.0.0" + comma-separated-tokens "^2.0.0" + devlop "^1.0.0" + estree-util-attach-comments "^3.0.0" + estree-util-is-identifier-name "^3.0.0" + hast-util-whitespace "^3.0.0" + mdast-util-mdx-expression "^2.0.0" + mdast-util-mdx-jsx "^3.0.0" + mdast-util-mdxjs-esm "^2.0.0" + property-information "^6.0.0" + space-separated-tokens "^2.0.0" + style-to-object "^0.4.0" + unist-util-position "^5.0.0" + zwitch "^2.0.0" + +hast-util-to-jsx-runtime@^2.0.0: + version "2.3.0" + resolved "https://registry.npmmirror.com/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.0.tgz#3ed27caf8dc175080117706bf7269404a0aa4f7c" + integrity sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ== + dependencies: + "@types/estree" "^1.0.0" + "@types/hast" "^3.0.0" + "@types/unist" "^3.0.0" + comma-separated-tokens "^2.0.0" + devlop "^1.0.0" + estree-util-is-identifier-name "^3.0.0" + hast-util-whitespace "^3.0.0" + mdast-util-mdx-expression "^2.0.0" + mdast-util-mdx-jsx "^3.0.0" + mdast-util-mdxjs-esm "^2.0.0" + property-information "^6.0.0" + space-separated-tokens "^2.0.0" + style-to-object "^1.0.0" + unist-util-position "^5.0.0" + vfile-message "^4.0.0" + +hast-util-to-parse5@^8.0.0: + version "8.0.0" + resolved "https://registry.npmmirror.com/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz#477cd42d278d4f036bc2ea58586130f6f39ee6ed" + integrity sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw== + dependencies: + "@types/hast" "^3.0.0" + comma-separated-tokens "^2.0.0" + devlop "^1.0.0" + property-information "^6.0.0" + space-separated-tokens "^2.0.0" + web-namespaces "^2.0.0" + zwitch "^2.0.0" + +hast-util-whitespace@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz#7778ed9d3c92dd9e8c5c8f648a49c21fc51cb621" + integrity sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw== + dependencies: + "@types/hast" "^3.0.0" + +hastscript@^8.0.0: + version "8.0.0" + resolved "https://registry.npmmirror.com/hastscript/-/hastscript-8.0.0.tgz#4ef795ec8dee867101b9f23cc830d4baf4fd781a" + integrity sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw== + dependencies: + "@types/hast" "^3.0.0" + comma-separated-tokens "^2.0.0" + hast-util-parse-selector "^4.0.0" + property-information "^6.0.0" + space-separated-tokens "^2.0.0" + +he@^1.2.0: + version "1.2.0" + resolved "https://registry.npmmirror.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +history@^4.9.0: + version "4.10.1" + resolved "https://registry.npmmirror.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3" + integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew== + dependencies: + "@babel/runtime" "^7.1.2" + loose-envify "^1.2.0" + resolve-pathname "^3.0.0" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + value-equal "^1.0.1" + +hoist-non-react-statics@^3.1.0: + version "3.3.2" + resolved "https://registry.npmmirror.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.npmmirror.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +html-entities@^2.3.2: + version "2.5.2" + resolved "https://registry.npmmirror.com/html-entities/-/html-entities-2.5.2.tgz#201a3cf95d3a15be7099521620d19dfb4f65359f" + integrity sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA== + +html-escaper@^2.0.2: + version "2.0.2" + resolved "https://registry.npmmirror.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + +html-minifier-terser@^6.0.2: + version "6.1.0" + resolved "https://registry.npmmirror.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#bfc818934cc07918f6b3669f5774ecdfd48f32ab" + integrity sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw== + dependencies: + camel-case "^4.1.2" + clean-css "^5.2.2" + commander "^8.3.0" + he "^1.2.0" + param-case "^3.0.4" + relateurl "^0.2.7" + terser "^5.10.0" + +html-minifier-terser@^7.2.0: + version "7.2.0" + resolved "https://registry.npmmirror.com/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz#18752e23a2f0ed4b0f550f217bb41693e975b942" + integrity sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA== + dependencies: + camel-case "^4.1.2" + clean-css "~5.3.2" + commander "^10.0.0" + entities "^4.4.0" + param-case "^3.0.4" + relateurl "^0.2.7" + terser "^5.15.1" + +html-tags@^3.3.1: + version "3.3.1" + resolved "https://registry.npmmirror.com/html-tags/-/html-tags-3.3.1.tgz#a04026a18c882e4bba8a01a3d39cfe465d40b5ce" + integrity sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ== + +html-void-elements@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/html-void-elements/-/html-void-elements-3.0.0.tgz#fc9dbd84af9e747249034d4d62602def6517f1d7" + integrity sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg== + +html-webpack-plugin@^5.5.3: + version "5.6.0" + resolved "https://registry.npmmirror.com/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz#50a8fa6709245608cb00e811eacecb8e0d7b7ea0" + integrity sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw== + dependencies: + "@types/html-minifier-terser" "^6.0.0" + html-minifier-terser "^6.0.2" + lodash "^4.17.21" + pretty-error "^4.0.0" + tapable "^2.0.0" + +htmlparser2@^6.1.0: + version "6.1.0" + resolved "https://registry.npmmirror.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" + integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.0.0" + domutils "^2.5.2" + entities "^2.0.0" + +htmlparser2@^8.0.1: + version "8.0.2" + resolved "https://registry.npmmirror.com/htmlparser2/-/htmlparser2-8.0.2.tgz#f002151705b383e62433b5cf466f5b716edaec21" + integrity sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.3" + domutils "^3.0.1" + entities "^4.4.0" + +http-cache-semantics@^4.1.1: + version "4.1.1" + resolved "https://registry.npmmirror.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.npmmirror.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.npmmirror.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-parser-js@>=0.5.1: + version "0.5.8" + resolved "https://registry.npmmirror.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" + integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== + +http-proxy-middleware@^2.0.3: + version "2.0.6" + resolved "https://registry.npmmirror.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" + integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== + dependencies: + "@types/http-proxy" "^1.17.8" + http-proxy "^1.18.1" + is-glob "^4.0.1" + is-plain-obj "^3.0.0" + micromatch "^4.0.2" + +http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.npmmirror.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +http2-wrapper@^2.1.10: + version "2.2.1" + resolved "https://registry.npmmirror.com/http2-wrapper/-/http2-wrapper-2.2.1.tgz#310968153dcdedb160d8b72114363ef5fce1f64a" + integrity sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ== + dependencies: + quick-lru "^5.1.1" + resolve-alpn "^1.2.0" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +icss-utils@^5.0.0, icss-utils@^5.1.0: + version "5.1.0" + resolved "https://registry.npmmirror.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== + +ignore@^5.2.0, ignore@^5.2.4: + version "5.3.1" + resolved "https://registry.npmmirror.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" + integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== + +image-size@^1.0.2: + version "1.1.1" + resolved "https://registry.npmmirror.com/image-size/-/image-size-1.1.1.tgz#ddd67d4dc340e52ac29ce5f546a09f4e29e840ac" + integrity sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ== + dependencies: + queue "6.0.2" + +immer@^9.0.7: + version "9.0.21" + resolved "https://registry.npmmirror.com/immer/-/immer-9.0.21.tgz#1e025ea31a40f24fb064f1fef23e931496330176" + integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA== + +import-fresh@^3.1.0, import-fresh@^3.2.1, import-fresh@^3.3.0: + version "3.3.0" + resolved "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-lazy@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/import-lazy/-/import-lazy-4.0.0.tgz#e8eb627483a0a43da3c03f3e35548be5cb0cc153" + integrity sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw== + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.npmmirror.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +infima@0.2.0-alpha.43: + version "0.2.0-alpha.43" + resolved "https://registry.npmmirror.com/infima/-/infima-0.2.0-alpha.43.tgz#f7aa1d7b30b6c08afef441c726bac6150228cbe0" + integrity sha512-2uw57LvUqW0rK/SWYnd/2rRfxNA5DDNOh33jxF7fy46VWoNhGxiUQyVZHbBMjQ33mQem0cjdDVwgWVAmlRfgyQ== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.npmmirror.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== + +ini@2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" + integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== + +ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: + version "1.3.8" + resolved "https://registry.npmmirror.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +inline-style-parser@0.1.1: + version "0.1.1" + resolved "https://registry.npmmirror.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1" + integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q== + +inline-style-parser@0.2.3: + version "0.2.3" + resolved "https://registry.npmmirror.com/inline-style-parser/-/inline-style-parser-0.2.3.tgz#e35c5fb45f3a83ed7849fe487336eb7efa25971c" + integrity sha512-qlD8YNDqyTKTyuITrDOffsl6Tdhv+UC4hcdAVuQsK4IMQ99nSgd1MIA/Q+jQYoh9r3hVUXhYh7urSRmXPkW04g== + +interpret@^1.0.0: + version "1.4.0" + resolved "https://registry.npmmirror.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" + integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== + +invariant@^2.2.4: + version "2.2.4" + resolved "https://registry.npmmirror.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +ipaddr.js@^2.0.1: + version "2.1.0" + resolved "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-2.1.0.tgz#2119bc447ff8c257753b196fc5f1ce08a4cdf39f" + integrity sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ== + +is-alphabetical@^2.0.0: + version "2.0.1" + resolved "https://registry.npmmirror.com/is-alphabetical/-/is-alphabetical-2.0.1.tgz#01072053ea7c1036df3c7d19a6daaec7f19e789b" + integrity sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ== + +is-alphanumerical@^2.0.0: + version "2.0.1" + resolved "https://registry.npmmirror.com/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz#7c03fbe96e3e931113e57f964b0a368cc2dfd875" + integrity sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw== + dependencies: + is-alphabetical "^2.0.0" + is-decimal "^2.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-ci@^3.0.1: + version "3.0.1" + resolved "https://registry.npmmirror.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867" + integrity sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ== + dependencies: + ci-info "^3.2.0" + +is-core-module@^2.13.0: + version "2.13.1" + resolved "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" + integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== + dependencies: + hasown "^2.0.0" + +is-decimal@^2.0.0: + version "2.0.1" + resolved "https://registry.npmmirror.com/is-decimal/-/is-decimal-2.0.1.tgz#9469d2dc190d0214fd87d78b78caecc0cc14eef7" + integrity sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A== + +is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.npmmirror.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-extendable@^0.1.0: + version "0.1.1" + resolved "https://registry.npmmirror.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-hexadecimal@^2.0.0: + version "2.0.1" + resolved "https://registry.npmmirror.com/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz#86b5bf668fca307498d319dfc03289d781a90027" + integrity sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg== + +is-installed-globally@^0.4.0: + version "0.4.0" + resolved "https://registry.npmmirror.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" + integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== + dependencies: + global-dirs "^3.0.0" + is-path-inside "^3.0.2" + +is-npm@^6.0.0: + version "6.0.0" + resolved "https://registry.npmmirror.com/is-npm/-/is-npm-6.0.0.tgz#b59e75e8915543ca5d881ecff864077cba095261" + integrity sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg== + +is-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" + integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== + +is-path-cwd@^2.2.0: + version "2.2.0" + resolved "https://registry.npmmirror.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" + integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== + +is-path-inside@^3.0.2: + version "3.0.3" + resolved "https://registry.npmmirror.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-plain-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" + integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== + +is-plain-obj@^4.0.0: + version "4.1.0" + resolved "https://registry.npmmirror.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz#d65025edec3657ce032fd7db63c97883eaed71f0" + integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg== + +is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.npmmirror.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-plain-object@^5.0.0: + version "5.0.0" + resolved "https://registry.npmmirror.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" + integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== + +is-reference@^3.0.0: + version "3.0.2" + resolved "https://registry.npmmirror.com/is-reference/-/is-reference-3.0.2.tgz#154747a01f45cd962404ee89d43837af2cba247c" + integrity sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg== + dependencies: + "@types/estree" "*" + +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + integrity sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA== + +is-root@^2.1.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" + integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.npmmirror.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-typedarray@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== + +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.npmmirror.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +is-yarn-global@^0.4.0: + version "0.4.1" + resolved "https://registry.npmmirror.com/is-yarn-global/-/is-yarn-global-0.4.1.tgz#b312d902b313f81e4eaf98b6361ba2b45cd694bb" + integrity sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ== + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.npmmirror.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.npmmirror.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + +jest-util@^29.7.0: + version "29.7.0" + resolved "https://registry.npmmirror.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" + integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-worker@^27.4.5: + version "27.5.1" + resolved "https://registry.npmmirror.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest-worker@^29.1.2: + version "29.7.0" + resolved "https://registry.npmmirror.com/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a" + integrity sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw== + dependencies: + "@types/node" "*" + jest-util "^29.7.0" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jiti@^1.20.0: + version "1.21.0" + resolved "https://registry.npmmirror.com/jiti/-/jiti-1.21.0.tgz#7c97f8fe045724e136a397f7340475244156105d" + integrity sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q== + +joi@^17.9.2: + version "17.12.2" + resolved "https://registry.npmmirror.com/joi/-/joi-17.12.2.tgz#283a664dabb80c7e52943c557aab82faea09f521" + integrity sha512-RonXAIzCiHLc8ss3Ibuz45u28GOsWE1UpfDXLbN/9NKbL4tCJf8TWYVKsoYuuh+sAUt7fsSNpA+r2+TBA6Wjmw== + dependencies: + "@hapi/hoek" "^9.3.0" + "@hapi/topo" "^5.1.0" + "@sideway/address" "^4.1.5" + "@sideway/formula" "^3.0.1" + "@sideway/pinpoint" "^2.0.0" + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.npmmirror.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.npmmirror.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.npmmirror.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== + +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.npmmirror.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + +json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: + version "2.3.1" + resolved "https://registry.npmmirror.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json5@^2.1.2, json5@^2.2.3: + version "2.2.3" + resolved "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +keyv@^4.5.3: + version "4.5.4" + resolved "https://registry.npmmirror.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.npmmirror.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.npmmirror.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + +latest-version@^7.0.0: + version "7.0.0" + resolved "https://registry.npmmirror.com/latest-version/-/latest-version-7.0.0.tgz#843201591ea81a4d404932eeb61240fe04e9e5da" + integrity sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg== + dependencies: + package-json "^8.1.0" + +launch-editor@^2.6.0: + version "2.6.1" + resolved "https://registry.npmmirror.com/launch-editor/-/launch-editor-2.6.1.tgz#f259c9ef95cbc9425620bbbd14b468fcdb4ffe3c" + integrity sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw== + dependencies: + picocolors "^1.0.0" + shell-quote "^1.8.1" + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.npmmirror.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +lilconfig@^2.0.3: + version "2.1.0" + resolved "https://registry.npmmirror.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" + integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +loader-runner@^4.2.0: + version "4.3.0" + resolved "https://registry.npmmirror.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" + integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== + +loader-utils@^2.0.0: + version "2.0.4" + resolved "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" + integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + +loader-utils@^3.2.0: + version "3.2.1" + resolved "https://registry.npmmirror.com/loader-utils/-/loader-utils-3.2.1.tgz#4fb104b599daafd82ef3e1a41fb9265f87e1f576" + integrity sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw== + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.npmmirror.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +locate-path@^7.1.0: + version "7.2.0" + resolved "https://registry.npmmirror.com/locate-path/-/locate-path-7.2.0.tgz#69cb1779bd90b35ab1e771e1f2f89a202c2a8a8a" + integrity sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA== + dependencies: + p-locate "^6.0.0" + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.npmmirror.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== + +lodash.memoize@^4.1.2: + version "4.1.2" + resolved "https://registry.npmmirror.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== + +lodash.uniq@^4.5.0: + version "4.5.0" + resolved "https://registry.npmmirror.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== + +lodash@^4.17.20, lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +longest-streak@^3.0.0: + version "3.1.0" + resolved "https://registry.npmmirror.com/longest-streak/-/longest-streak-3.1.0.tgz#62fa67cd958742a1574af9f39866364102d90cd4" + integrity sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g== + +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.npmmirror.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lower-case@^2.0.2: + version "2.0.2" + resolved "https://registry.npmmirror.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" + integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== + dependencies: + tslib "^2.0.3" + +lowercase-keys@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/lowercase-keys/-/lowercase-keys-3.0.0.tgz#c5e7d442e37ead247ae9db117a9d0a467c89d4f2" + integrity sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ== + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +markdown-extensions@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/markdown-extensions/-/markdown-extensions-2.0.0.tgz#34bebc83e9938cae16e0e017e4a9814a8330d3c4" + integrity sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q== + +markdown-table@^3.0.0: + version "3.0.3" + resolved "https://registry.npmmirror.com/markdown-table/-/markdown-table-3.0.3.tgz#e6331d30e493127e031dd385488b5bd326e4a6bd" + integrity sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw== + +mdast-util-directive@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/mdast-util-directive/-/mdast-util-directive-3.0.0.tgz#3fb1764e705bbdf0afb0d3f889e4404c3e82561f" + integrity sha512-JUpYOqKI4mM3sZcNxmF/ox04XYFFkNwr0CFlrQIkCwbvH0xzMCqkMqAde9wRd80VAhaUrwFwKm2nxretdT1h7Q== + dependencies: + "@types/mdast" "^4.0.0" + "@types/unist" "^3.0.0" + devlop "^1.0.0" + mdast-util-from-markdown "^2.0.0" + mdast-util-to-markdown "^2.0.0" + parse-entities "^4.0.0" + stringify-entities "^4.0.0" + unist-util-visit-parents "^6.0.0" + +mdast-util-find-and-replace@^3.0.0, mdast-util-find-and-replace@^3.0.1: + version "3.0.1" + resolved "https://registry.npmmirror.com/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz#a6fc7b62f0994e973490e45262e4bc07607b04e0" + integrity sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA== + dependencies: + "@types/mdast" "^4.0.0" + escape-string-regexp "^5.0.0" + unist-util-is "^6.0.0" + unist-util-visit-parents "^6.0.0" + +mdast-util-from-markdown@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.0.tgz#52f14815ec291ed061f2922fd14d6689c810cb88" + integrity sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA== + dependencies: + "@types/mdast" "^4.0.0" + "@types/unist" "^3.0.0" + decode-named-character-reference "^1.0.0" + devlop "^1.0.0" + mdast-util-to-string "^4.0.0" + micromark "^4.0.0" + micromark-util-decode-numeric-character-reference "^2.0.0" + micromark-util-decode-string "^2.0.0" + micromark-util-normalize-identifier "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + unist-util-stringify-position "^4.0.0" + +mdast-util-frontmatter@^2.0.0: + version "2.0.1" + resolved "https://registry.npmmirror.com/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz#f5f929eb1eb36c8a7737475c7eb438261f964ee8" + integrity sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA== + dependencies: + "@types/mdast" "^4.0.0" + devlop "^1.0.0" + escape-string-regexp "^5.0.0" + mdast-util-from-markdown "^2.0.0" + mdast-util-to-markdown "^2.0.0" + micromark-extension-frontmatter "^2.0.0" + +mdast-util-gfm-autolink-literal@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.0.tgz#5baf35407421310a08e68c15e5d8821e8898ba2a" + integrity sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg== + dependencies: + "@types/mdast" "^4.0.0" + ccount "^2.0.0" + devlop "^1.0.0" + mdast-util-find-and-replace "^3.0.0" + micromark-util-character "^2.0.0" + +mdast-util-gfm-footnote@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz#25a1753c7d16db8bfd53cd84fe50562bd1e6d6a9" + integrity sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ== + dependencies: + "@types/mdast" "^4.0.0" + devlop "^1.1.0" + mdast-util-from-markdown "^2.0.0" + mdast-util-to-markdown "^2.0.0" + micromark-util-normalize-identifier "^2.0.0" + +mdast-util-gfm-strikethrough@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz#d44ef9e8ed283ac8c1165ab0d0dfd058c2764c16" + integrity sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg== + dependencies: + "@types/mdast" "^4.0.0" + mdast-util-from-markdown "^2.0.0" + mdast-util-to-markdown "^2.0.0" + +mdast-util-gfm-table@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz#7a435fb6223a72b0862b33afbd712b6dae878d38" + integrity sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg== + dependencies: + "@types/mdast" "^4.0.0" + devlop "^1.0.0" + markdown-table "^3.0.0" + mdast-util-from-markdown "^2.0.0" + mdast-util-to-markdown "^2.0.0" + +mdast-util-gfm-task-list-item@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz#e68095d2f8a4303ef24094ab642e1047b991a936" + integrity sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ== + dependencies: + "@types/mdast" "^4.0.0" + devlop "^1.0.0" + mdast-util-from-markdown "^2.0.0" + mdast-util-to-markdown "^2.0.0" + +mdast-util-gfm@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz#3f2aecc879785c3cb6a81ff3a243dc11eca61095" + integrity sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw== + dependencies: + mdast-util-from-markdown "^2.0.0" + mdast-util-gfm-autolink-literal "^2.0.0" + mdast-util-gfm-footnote "^2.0.0" + mdast-util-gfm-strikethrough "^2.0.0" + mdast-util-gfm-table "^2.0.0" + mdast-util-gfm-task-list-item "^2.0.0" + mdast-util-to-markdown "^2.0.0" + +mdast-util-mdx-expression@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz#4968b73724d320a379110d853e943a501bfd9d87" + integrity sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw== + dependencies: + "@types/estree-jsx" "^1.0.0" + "@types/hast" "^3.0.0" + "@types/mdast" "^4.0.0" + devlop "^1.0.0" + mdast-util-from-markdown "^2.0.0" + mdast-util-to-markdown "^2.0.0" + +mdast-util-mdx-jsx@^3.0.0: + version "3.1.2" + resolved "https://registry.npmmirror.com/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.2.tgz#daae777c72f9c4a106592e3025aa50fb26068e1b" + integrity sha512-eKMQDeywY2wlHc97k5eD8VC+9ASMjN8ItEZQNGwJ6E0XWKiW/Z0V5/H8pvoXUf+y+Mj0VIgeRRbujBmFn4FTyA== + dependencies: + "@types/estree-jsx" "^1.0.0" + "@types/hast" "^3.0.0" + "@types/mdast" "^4.0.0" + "@types/unist" "^3.0.0" + ccount "^2.0.0" + devlop "^1.1.0" + mdast-util-from-markdown "^2.0.0" + mdast-util-to-markdown "^2.0.0" + parse-entities "^4.0.0" + stringify-entities "^4.0.0" + unist-util-remove-position "^5.0.0" + unist-util-stringify-position "^4.0.0" + vfile-message "^4.0.0" + +mdast-util-mdx@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz#792f9cf0361b46bee1fdf1ef36beac424a099c41" + integrity sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w== + dependencies: + mdast-util-from-markdown "^2.0.0" + mdast-util-mdx-expression "^2.0.0" + mdast-util-mdx-jsx "^3.0.0" + mdast-util-mdxjs-esm "^2.0.0" + mdast-util-to-markdown "^2.0.0" + +mdast-util-mdxjs-esm@^2.0.0: + version "2.0.1" + resolved "https://registry.npmmirror.com/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz#019cfbe757ad62dd557db35a695e7314bcc9fa97" + integrity sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg== + dependencies: + "@types/estree-jsx" "^1.0.0" + "@types/hast" "^3.0.0" + "@types/mdast" "^4.0.0" + devlop "^1.0.0" + mdast-util-from-markdown "^2.0.0" + mdast-util-to-markdown "^2.0.0" + +mdast-util-phrasing@^4.0.0: + version "4.1.0" + resolved "https://registry.npmmirror.com/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz#7cc0a8dec30eaf04b7b1a9661a92adb3382aa6e3" + integrity sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w== + dependencies: + "@types/mdast" "^4.0.0" + unist-util-is "^6.0.0" + +mdast-util-to-hast@^13.0.0: + version "13.1.0" + resolved "https://registry.npmmirror.com/mdast-util-to-hast/-/mdast-util-to-hast-13.1.0.tgz#1ae54d903150a10fe04d59f03b2b95fd210b2124" + integrity sha512-/e2l/6+OdGp/FB+ctrJ9Avz71AN/GRH3oi/3KAx/kMnoUsD6q0woXlDT8lLEeViVKE7oZxE7RXzvO3T8kF2/sA== + dependencies: + "@types/hast" "^3.0.0" + "@types/mdast" "^4.0.0" + "@ungap/structured-clone" "^1.0.0" + devlop "^1.0.0" + micromark-util-sanitize-uri "^2.0.0" + trim-lines "^3.0.0" + unist-util-position "^5.0.0" + unist-util-visit "^5.0.0" + vfile "^6.0.0" + +mdast-util-to-markdown@^2.0.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz#9813f1d6e0cdaac7c244ec8c6dabfdb2102ea2b4" + integrity sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ== + dependencies: + "@types/mdast" "^4.0.0" + "@types/unist" "^3.0.0" + longest-streak "^3.0.0" + mdast-util-phrasing "^4.0.0" + mdast-util-to-string "^4.0.0" + micromark-util-decode-string "^2.0.0" + unist-util-visit "^5.0.0" + zwitch "^2.0.0" + +mdast-util-to-string@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz#7a5121475556a04e7eddeb67b264aae79d312814" + integrity sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg== + dependencies: + "@types/mdast" "^4.0.0" + +mdn-data@2.0.14: + version "2.0.14" + resolved "https://registry.npmmirror.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" + integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.npmmirror.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +memfs@^3.1.2, memfs@^3.4.3: + version "3.6.0" + resolved "https://registry.npmmirror.com/memfs/-/memfs-3.6.0.tgz#d7a2110f86f79dd950a8b6df6d57bc984aa185f6" + integrity sha512-EGowvkkgbMcIChjMTMkESFDbZeSh8xZ7kNSF0hAiAN4Jh6jgHCRS0Ga/+C8y6Au+oqpezRHCfPsmJ2+DwAgiwQ== + dependencies: + fs-monkey "^1.0.4" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.npmmirror.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +micromark-core-commonmark@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/micromark-core-commonmark/-/micromark-core-commonmark-2.0.0.tgz#50740201f0ee78c12a675bf3e68ffebc0bf931a3" + integrity sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA== + dependencies: + decode-named-character-reference "^1.0.0" + devlop "^1.0.0" + micromark-factory-destination "^2.0.0" + micromark-factory-label "^2.0.0" + micromark-factory-space "^2.0.0" + micromark-factory-title "^2.0.0" + micromark-factory-whitespace "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-chunked "^2.0.0" + micromark-util-classify-character "^2.0.0" + micromark-util-html-tag-name "^2.0.0" + micromark-util-normalize-identifier "^2.0.0" + micromark-util-resolve-all "^2.0.0" + micromark-util-subtokenize "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-extension-directive@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/micromark-extension-directive/-/micromark-extension-directive-3.0.0.tgz#527869de497a6de9024138479091bc885dae076b" + integrity sha512-61OI07qpQrERc+0wEysLHMvoiO3s2R56x5u7glHq2Yqq6EHbH4dW25G9GfDdGCDYqA21KE6DWgNSzxSwHc2hSg== + dependencies: + devlop "^1.0.0" + micromark-factory-space "^2.0.0" + micromark-factory-whitespace "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + parse-entities "^4.0.0" + +micromark-extension-frontmatter@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz#651c52ffa5d7a8eeed687c513cd869885882d67a" + integrity sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg== + dependencies: + fault "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-extension-gfm-autolink-literal@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.0.0.tgz#f1e50b42e67d441528f39a67133eddde2bbabfd9" + integrity sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg== + dependencies: + micromark-util-character "^2.0.0" + micromark-util-sanitize-uri "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-extension-gfm-footnote@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.0.0.tgz#91afad310065a94b636ab1e9dab2c60d1aab953c" + integrity sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg== + dependencies: + devlop "^1.0.0" + micromark-core-commonmark "^2.0.0" + micromark-factory-space "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-normalize-identifier "^2.0.0" + micromark-util-sanitize-uri "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-extension-gfm-strikethrough@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.0.0.tgz#6917db8e320da70e39ffbf97abdbff83e6783e61" + integrity sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw== + dependencies: + devlop "^1.0.0" + micromark-util-chunked "^2.0.0" + micromark-util-classify-character "^2.0.0" + micromark-util-resolve-all "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-extension-gfm-table@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.0.0.tgz#2cf3fe352d9e089b7ef5fff003bdfe0da29649b7" + integrity sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw== + dependencies: + devlop "^1.0.0" + micromark-factory-space "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-extension-gfm-tagfilter@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz#f26d8a7807b5985fba13cf61465b58ca5ff7dc57" + integrity sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg== + dependencies: + micromark-util-types "^2.0.0" + +micromark-extension-gfm-task-list-item@^2.0.0: + version "2.0.1" + resolved "https://registry.npmmirror.com/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.0.1.tgz#ee8b208f1ced1eb9fb11c19a23666e59d86d4838" + integrity sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw== + dependencies: + devlop "^1.0.0" + micromark-factory-space "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-extension-gfm@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz#3e13376ab95dd7a5cfd0e29560dfe999657b3c5b" + integrity sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w== + dependencies: + micromark-extension-gfm-autolink-literal "^2.0.0" + micromark-extension-gfm-footnote "^2.0.0" + micromark-extension-gfm-strikethrough "^2.0.0" + micromark-extension-gfm-table "^2.0.0" + micromark-extension-gfm-tagfilter "^2.0.0" + micromark-extension-gfm-task-list-item "^2.0.0" + micromark-util-combine-extensions "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-extension-mdx-expression@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.0.tgz#1407b9ce69916cf5e03a196ad9586889df25302a" + integrity sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ== + dependencies: + "@types/estree" "^1.0.0" + devlop "^1.0.0" + micromark-factory-mdx-expression "^2.0.0" + micromark-factory-space "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-events-to-acorn "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-extension-mdx-jsx@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.0.tgz#4aba0797c25efb2366a3fd2d367c6b1c1159f4f5" + integrity sha512-uvhhss8OGuzR4/N17L1JwvmJIpPhAd8oByMawEKx6NVdBCbesjH4t+vjEp3ZXft9DwvlKSD07fCeI44/N0Vf2w== + dependencies: + "@types/acorn" "^4.0.0" + "@types/estree" "^1.0.0" + devlop "^1.0.0" + estree-util-is-identifier-name "^3.0.0" + micromark-factory-mdx-expression "^2.0.0" + micromark-factory-space "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + vfile-message "^4.0.0" + +micromark-extension-mdx-md@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz#1d252881ea35d74698423ab44917e1f5b197b92d" + integrity sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ== + dependencies: + micromark-util-types "^2.0.0" + +micromark-extension-mdxjs-esm@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz#de21b2b045fd2059bd00d36746081de38390d54a" + integrity sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A== + dependencies: + "@types/estree" "^1.0.0" + devlop "^1.0.0" + micromark-core-commonmark "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-events-to-acorn "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + unist-util-position-from-estree "^2.0.0" + vfile-message "^4.0.0" + +micromark-extension-mdxjs@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz#b5a2e0ed449288f3f6f6c544358159557549de18" + integrity sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ== + dependencies: + acorn "^8.0.0" + acorn-jsx "^5.0.0" + micromark-extension-mdx-expression "^3.0.0" + micromark-extension-mdx-jsx "^3.0.0" + micromark-extension-mdx-md "^2.0.0" + micromark-extension-mdxjs-esm "^3.0.0" + micromark-util-combine-extensions "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-factory-destination@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz#857c94debd2c873cba34e0445ab26b74f6a6ec07" + integrity sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA== + dependencies: + micromark-util-character "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-factory-label@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz#17c5c2e66ce39ad6f4fc4cbf40d972f9096f726a" + integrity sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw== + dependencies: + devlop "^1.0.0" + micromark-util-character "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-factory-mdx-expression@^2.0.0: + version "2.0.1" + resolved "https://registry.npmmirror.com/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.1.tgz#f2a9724ce174f1751173beb2c1f88062d3373b1b" + integrity sha512-F0ccWIUHRLRrYp5TC9ZYXmZo+p2AM13ggbsW4T0b5CRKP8KHVRB8t4pwtBgTxtjRmwrK0Irwm7vs2JOZabHZfg== + dependencies: + "@types/estree" "^1.0.0" + devlop "^1.0.0" + micromark-util-character "^2.0.0" + micromark-util-events-to-acorn "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + unist-util-position-from-estree "^2.0.0" + vfile-message "^4.0.0" + +micromark-factory-space@^1.0.0: + version "1.1.0" + resolved "https://registry.npmmirror.com/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz#c8f40b0640a0150751d3345ed885a080b0d15faf" + integrity sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ== + dependencies: + micromark-util-character "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-factory-space@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz#5e7afd5929c23b96566d0e1ae018ae4fcf81d030" + integrity sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg== + dependencies: + micromark-util-character "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-factory-title@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz#726140fc77892af524705d689e1cf06c8a83ea95" + integrity sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A== + dependencies: + micromark-factory-space "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-factory-whitespace@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz#9e92eb0f5468083381f923d9653632b3cfb5f763" + integrity sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA== + dependencies: + micromark-factory-space "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-util-character@^1.0.0, micromark-util-character@^1.1.0: + version "1.2.0" + resolved "https://registry.npmmirror.com/micromark-util-character/-/micromark-util-character-1.2.0.tgz#4fedaa3646db249bc58caeb000eb3549a8ca5dcc" + integrity sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg== + dependencies: + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-util-character@^2.0.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/micromark-util-character/-/micromark-util-character-2.1.0.tgz#31320ace16b4644316f6bf057531689c71e2aee1" + integrity sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ== + dependencies: + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-util-chunked@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz#e51f4db85fb203a79dbfef23fd41b2f03dc2ef89" + integrity sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg== + dependencies: + micromark-util-symbol "^2.0.0" + +micromark-util-classify-character@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz#8c7537c20d0750b12df31f86e976d1d951165f34" + integrity sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw== + dependencies: + micromark-util-character "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-util-combine-extensions@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz#75d6ab65c58b7403616db8d6b31315013bfb7ee5" + integrity sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ== + dependencies: + micromark-util-chunked "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-util-decode-numeric-character-reference@^2.0.0: + version "2.0.1" + resolved "https://registry.npmmirror.com/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz#2698bbb38f2a9ba6310e359f99fcb2b35a0d2bd5" + integrity sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ== + dependencies: + micromark-util-symbol "^2.0.0" + +micromark-util-decode-string@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz#7dfa3a63c45aecaa17824e656bcdb01f9737154a" + integrity sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA== + dependencies: + decode-named-character-reference "^1.0.0" + micromark-util-character "^2.0.0" + micromark-util-decode-numeric-character-reference "^2.0.0" + micromark-util-symbol "^2.0.0" + +micromark-util-encode@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz#0921ac7953dc3f1fd281e3d1932decfdb9382ab1" + integrity sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA== + +micromark-util-events-to-acorn@^2.0.0: + version "2.0.2" + resolved "https://registry.npmmirror.com/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.2.tgz#4275834f5453c088bd29cd72dfbf80e3327cec07" + integrity sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA== + dependencies: + "@types/acorn" "^4.0.0" + "@types/estree" "^1.0.0" + "@types/unist" "^3.0.0" + devlop "^1.0.0" + estree-util-visit "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + vfile-message "^4.0.0" + +micromark-util-html-tag-name@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz#ae34b01cbe063363847670284c6255bb12138ec4" + integrity sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw== + +micromark-util-normalize-identifier@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz#91f9a4e65fe66cc80c53b35b0254ad67aa431d8b" + integrity sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w== + dependencies: + micromark-util-symbol "^2.0.0" + +micromark-util-resolve-all@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz#189656e7e1a53d0c86a38a652b284a252389f364" + integrity sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA== + dependencies: + micromark-util-types "^2.0.0" + +micromark-util-sanitize-uri@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz#ec8fbf0258e9e6d8f13d9e4770f9be64342673de" + integrity sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw== + dependencies: + micromark-util-character "^2.0.0" + micromark-util-encode "^2.0.0" + micromark-util-symbol "^2.0.0" + +micromark-util-subtokenize@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.0.tgz#9f412442d77e0c5789ffdf42377fa8a2bcbdf581" + integrity sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg== + dependencies: + devlop "^1.0.0" + micromark-util-chunked "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-util-symbol@^1.0.0, micromark-util-symbol@^1.0.1: + version "1.1.0" + resolved "https://registry.npmmirror.com/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz#813cd17837bdb912d069a12ebe3a44b6f7063142" + integrity sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag== + +micromark-util-symbol@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz#12225c8f95edf8b17254e47080ce0862d5db8044" + integrity sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw== + +micromark-util-types@^1.0.0: + version "1.1.0" + resolved "https://registry.npmmirror.com/micromark-util-types/-/micromark-util-types-1.1.0.tgz#e6676a8cae0bb86a2171c498167971886cb7e283" + integrity sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg== + +micromark-util-types@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/micromark-util-types/-/micromark-util-types-2.0.0.tgz#63b4b7ffeb35d3ecf50d1ca20e68fc7caa36d95e" + integrity sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w== + +micromark@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/micromark/-/micromark-4.0.0.tgz#84746a249ebd904d9658cfabc1e8e5f32cbc6249" + integrity sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ== + dependencies: + "@types/debug" "^4.0.0" + debug "^4.0.0" + decode-named-character-reference "^1.0.0" + devlop "^1.0.0" + micromark-core-commonmark "^2.0.0" + micromark-factory-space "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-chunked "^2.0.0" + micromark-util-combine-extensions "^2.0.0" + micromark-util-decode-numeric-character-reference "^2.0.0" + micromark-util-encode "^2.0.0" + micromark-util-normalize-identifier "^2.0.0" + micromark-util-resolve-all "^2.0.0" + micromark-util-sanitize-uri "^2.0.0" + micromark-util-subtokenize "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: + version "4.0.5" + resolved "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": + version "1.52.0" + resolved "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-db@~1.33.0: + version "1.33.0" + resolved "https://registry.npmmirror.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" + integrity sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ== + +mime-types@2.1.18: + version "2.1.18" + resolved "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" + integrity sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ== + dependencies: + mime-db "~1.33.0" + +mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.npmmirror.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + +mimic-response@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/mimic-response/-/mimic-response-4.0.0.tgz#35468b19e7c75d10f5165ea25e75a5ceea7cf70f" + integrity sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg== + +mini-css-extract-plugin@^2.7.6: + version "2.8.1" + resolved "https://registry.npmmirror.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.8.1.tgz#75245f3f30ce3a56dbdd478084df6fe475f02dc7" + integrity sha512-/1HDlyFRxWIZPI1ZpgqlZ8jMw/1Dp/dl3P0L1jtZ+zVcHqwPhGwaJwKL00WVgfnBy6PWCde9W65or7IIETImuA== + dependencies: + schema-utils "^4.0.0" + tapable "^2.2.1" + +minimalistic-assert@^1.0.0: + version "1.0.1" + resolved "https://registry.npmmirror.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimatch@3.1.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0: + version "1.2.8" + resolved "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +mrmime@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/mrmime/-/mrmime-2.0.0.tgz#151082a6e06e59a9a39b46b3e14d5cfe92b3abb4" + integrity sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3: + version "2.1.3" + resolved "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +multicast-dns@^7.2.5: + version "7.2.5" + resolved "https://registry.npmmirror.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced" + integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== + dependencies: + dns-packet "^5.2.2" + thunky "^1.0.2" + +nanoid@^3.3.7: + version "3.3.7" + resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" + integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.npmmirror.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.npmmirror.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +no-case@^3.0.4: + version "3.0.4" + resolved "https://registry.npmmirror.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" + integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== + dependencies: + lower-case "^2.0.2" + tslib "^2.0.3" + +node-emoji@^2.1.0: + version "2.1.3" + resolved "https://registry.npmmirror.com/node-emoji/-/node-emoji-2.1.3.tgz#93cfabb5cc7c3653aa52f29d6ffb7927d8047c06" + integrity sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA== + dependencies: + "@sindresorhus/is" "^4.6.0" + char-regex "^1.0.2" + emojilib "^2.4.0" + skin-tone "^2.0.0" + +node-forge@^1: + version "1.3.1" + resolved "https://registry.npmmirror.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== + +node-releases@^2.0.14: + version "2.0.14" + resolved "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" + integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.npmmirror.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== + +normalize-url@^6.0.1: + version "6.1.0" + resolved "https://registry.npmmirror.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== + +normalize-url@^8.0.0: + version "8.0.1" + resolved "https://registry.npmmirror.com/normalize-url/-/normalize-url-8.0.1.tgz#9b7d96af9836577c58f5883e939365fa15623a4a" + integrity sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +nprogress@^0.2.0: + version "0.2.0" + resolved "https://registry.npmmirror.com/nprogress/-/nprogress-0.2.0.tgz#cb8f34c53213d895723fcbab907e9422adbcafb1" + integrity sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA== + +nth-check@^2.0.1: + version "2.1.1" + resolved "https://registry.npmmirror.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" + +object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-inspect@^1.13.1: + version "1.13.1" + resolved "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" + integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== + +object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.npmmirror.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.0: + version "4.1.5" + resolved "https://registry.npmmirror.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" + integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ== + dependencies: + call-bind "^1.0.5" + define-properties "^1.2.1" + has-symbols "^1.0.3" + object-keys "^1.1.1" + +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.npmmirror.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.npmmirror.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.npmmirror.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.npmmirror.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +open@^8.0.9, open@^8.4.0: + version "8.4.2" + resolved "https://registry.npmmirror.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" + integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + +opener@^1.5.2: + version "1.5.2" + resolved "https://registry.npmmirror.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" + integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== + +p-cancelable@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/p-cancelable/-/p-cancelable-3.0.0.tgz#63826694b54d61ca1c20ebcb6d3ecf5e14cd8050" + integrity sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw== + +p-limit@^2.0.0: + version "2.3.0" + resolved "https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-limit@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/p-limit/-/p-limit-4.0.0.tgz#914af6544ed32bfa54670b061cafcbd04984b644" + integrity sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ== + dependencies: + yocto-queue "^1.0.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.npmmirror.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-locate@^6.0.0: + version "6.0.0" + resolved "https://registry.npmmirror.com/p-locate/-/p-locate-6.0.0.tgz#3da9a49d4934b901089dca3302fa65dc5a05c04f" + integrity sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw== + dependencies: + p-limit "^4.0.0" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + +p-retry@^4.5.0: + version "4.6.2" + resolved "https://registry.npmmirror.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" + integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== + dependencies: + "@types/retry" "0.12.0" + retry "^0.13.1" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.npmmirror.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +package-json@^8.1.0: + version "8.1.1" + resolved "https://registry.npmmirror.com/package-json/-/package-json-8.1.1.tgz#3e9948e43df40d1e8e78a85485f1070bf8f03dc8" + integrity sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA== + dependencies: + got "^12.1.0" + registry-auth-token "^5.0.1" + registry-url "^6.0.0" + semver "^7.3.7" + +param-case@^3.0.4: + version "3.0.4" + resolved "https://registry.npmmirror.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" + integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== + dependencies: + dot-case "^3.0.4" + tslib "^2.0.3" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-entities@^4.0.0: + version "4.0.1" + resolved "https://registry.npmmirror.com/parse-entities/-/parse-entities-4.0.1.tgz#4e2a01111fb1c986549b944af39eeda258fc9e4e" + integrity sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w== + dependencies: + "@types/unist" "^2.0.0" + character-entities "^2.0.0" + character-entities-legacy "^3.0.0" + character-reference-invalid "^2.0.0" + decode-named-character-reference "^1.0.0" + is-alphanumerical "^2.0.0" + is-decimal "^2.0.0" + is-hexadecimal "^2.0.0" + +parse-json@^5.0.0, parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.npmmirror.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +parse-numeric-range@^1.3.0: + version "1.3.0" + resolved "https://registry.npmmirror.com/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz#7c63b61190d61e4d53a1197f0c83c47bb670ffa3" + integrity sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ== + +parse5-htmlparser2-tree-adapter@^7.0.0: + version "7.0.0" + resolved "https://registry.npmmirror.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz#23c2cc233bcf09bb7beba8b8a69d46b08c62c2f1" + integrity sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g== + dependencies: + domhandler "^5.0.2" + parse5 "^7.0.0" + +parse5@^7.0.0: + version "7.1.2" + resolved "https://registry.npmmirror.com/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32" + integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw== + dependencies: + entities "^4.4.0" + +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.npmmirror.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascal-case@^3.1.2: + version "3.1.2" + resolved "https://registry.npmmirror.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" + integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-exists@^5.0.0: + version "5.0.0" + resolved "https://registry.npmmirror.com/path-exists/-/path-exists-5.0.0.tgz#a6aad9489200b21fab31e49cf09277e5116fb9e7" + integrity sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-is-inside@1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w== + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +path-to-regexp@2.2.1: + version "2.2.1" + resolved "https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-2.2.1.tgz#90b617025a16381a879bc82a38d4e8bdeb2bcf45" + integrity sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ== + +path-to-regexp@^1.7.0: + version "1.8.0" + resolved "https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" + integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== + dependencies: + isarray "0.0.1" + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +periscopic@^3.0.0: + version "3.1.0" + resolved "https://registry.npmmirror.com/periscopic/-/periscopic-3.1.0.tgz#7e9037bf51c5855bd33b48928828db4afa79d97a" + integrity sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw== + dependencies: + "@types/estree" "^1.0.0" + estree-walker "^3.0.0" + is-reference "^3.0.0" + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pkg-dir@^7.0.0: + version "7.0.0" + resolved "https://registry.npmmirror.com/pkg-dir/-/pkg-dir-7.0.0.tgz#8f0c08d6df4476756c5ff29b3282d0bab7517d11" + integrity sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA== + dependencies: + find-up "^6.3.0" + +pkg-up@^3.1.0: + version "3.1.0" + resolved "https://registry.npmmirror.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" + integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== + dependencies: + find-up "^3.0.0" + +postcss-calc@^8.2.3: + version "8.2.4" + resolved "https://registry.npmmirror.com/postcss-calc/-/postcss-calc-8.2.4.tgz#77b9c29bfcbe8a07ff6693dc87050828889739a5" + integrity sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q== + dependencies: + postcss-selector-parser "^6.0.9" + postcss-value-parser "^4.2.0" + +postcss-colormin@^5.3.1: + version "5.3.1" + resolved "https://registry.npmmirror.com/postcss-colormin/-/postcss-colormin-5.3.1.tgz#86c27c26ed6ba00d96c79e08f3ffb418d1d1988f" + integrity sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ== + dependencies: + browserslist "^4.21.4" + caniuse-api "^3.0.0" + colord "^2.9.1" + postcss-value-parser "^4.2.0" + +postcss-convert-values@^5.1.3: + version "5.1.3" + resolved "https://registry.npmmirror.com/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz#04998bb9ba6b65aa31035d669a6af342c5f9d393" + integrity sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA== + dependencies: + browserslist "^4.21.4" + postcss-value-parser "^4.2.0" + +postcss-discard-comments@^5.1.2: + version "5.1.2" + resolved "https://registry.npmmirror.com/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz#8df5e81d2925af2780075840c1526f0660e53696" + integrity sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ== + +postcss-discard-duplicates@^5.1.0: + version "5.1.0" + resolved "https://registry.npmmirror.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz#9eb4fe8456706a4eebd6d3b7b777d07bad03e848" + integrity sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw== + +postcss-discard-empty@^5.1.1: + version "5.1.1" + resolved "https://registry.npmmirror.com/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz#e57762343ff7f503fe53fca553d18d7f0c369c6c" + integrity sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A== + +postcss-discard-overridden@^5.1.0: + version "5.1.0" + resolved "https://registry.npmmirror.com/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz#7e8c5b53325747e9d90131bb88635282fb4a276e" + integrity sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw== + +postcss-discard-unused@^5.1.0: + version "5.1.0" + resolved "https://registry.npmmirror.com/postcss-discard-unused/-/postcss-discard-unused-5.1.0.tgz#8974e9b143d887677304e558c1166d3762501142" + integrity sha512-KwLWymI9hbwXmJa0dkrzpRbSJEh0vVUd7r8t0yOGPcfKzyJJxFM8kLyC5Ev9avji6nY95pOp1W6HqIrfT+0VGw== + dependencies: + postcss-selector-parser "^6.0.5" + +postcss-loader@^7.3.3: + version "7.3.4" + resolved "https://registry.npmmirror.com/postcss-loader/-/postcss-loader-7.3.4.tgz#aed9b79ce4ed7e9e89e56199d25ad1ec8f606209" + integrity sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A== + dependencies: + cosmiconfig "^8.3.5" + jiti "^1.20.0" + semver "^7.5.4" + +postcss-merge-idents@^5.1.1: + version "5.1.1" + resolved "https://registry.npmmirror.com/postcss-merge-idents/-/postcss-merge-idents-5.1.1.tgz#7753817c2e0b75d0853b56f78a89771e15ca04a1" + integrity sha512-pCijL1TREiCoog5nQp7wUe+TUonA2tC2sQ54UGeMmryK3UFGIYKqDyjnqd6RcuI4znFn9hWSLNN8xKE/vWcUQw== + dependencies: + cssnano-utils "^3.1.0" + postcss-value-parser "^4.2.0" + +postcss-merge-longhand@^5.1.7: + version "5.1.7" + resolved "https://registry.npmmirror.com/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz#24a1bdf402d9ef0e70f568f39bdc0344d568fb16" + integrity sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ== + dependencies: + postcss-value-parser "^4.2.0" + stylehacks "^5.1.1" + +postcss-merge-rules@^5.1.4: + version "5.1.4" + resolved "https://registry.npmmirror.com/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz#2f26fa5cacb75b1402e213789f6766ae5e40313c" + integrity sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g== + dependencies: + browserslist "^4.21.4" + caniuse-api "^3.0.0" + cssnano-utils "^3.1.0" + postcss-selector-parser "^6.0.5" + +postcss-minify-font-values@^5.1.0: + version "5.1.0" + resolved "https://registry.npmmirror.com/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz#f1df0014a726083d260d3bd85d7385fb89d1f01b" + integrity sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-minify-gradients@^5.1.1: + version "5.1.1" + resolved "https://registry.npmmirror.com/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz#f1fe1b4f498134a5068240c2f25d46fcd236ba2c" + integrity sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw== + dependencies: + colord "^2.9.1" + cssnano-utils "^3.1.0" + postcss-value-parser "^4.2.0" + +postcss-minify-params@^5.1.4: + version "5.1.4" + resolved "https://registry.npmmirror.com/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz#c06a6c787128b3208b38c9364cfc40c8aa5d7352" + integrity sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw== + dependencies: + browserslist "^4.21.4" + cssnano-utils "^3.1.0" + postcss-value-parser "^4.2.0" + +postcss-minify-selectors@^5.2.1: + version "5.2.1" + resolved "https://registry.npmmirror.com/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz#d4e7e6b46147b8117ea9325a915a801d5fe656c6" + integrity sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg== + dependencies: + postcss-selector-parser "^6.0.5" + +postcss-modules-extract-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" + integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== + +postcss-modules-local-by-default@^4.0.4: + version "4.0.4" + resolved "https://registry.npmmirror.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.4.tgz#7cbed92abd312b94aaea85b68226d3dec39a14e6" + integrity sha512-L4QzMnOdVwRm1Qb8m4x8jsZzKAaPAgrUF1r/hjDR2Xj7R+8Zsf97jAlSQzWtKx5YNiNGN8QxmPFIc/sh+RQl+Q== + dependencies: + icss-utils "^5.0.0" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + +postcss-modules-scope@^3.1.1: + version "3.1.1" + resolved "https://registry.npmmirror.com/postcss-modules-scope/-/postcss-modules-scope-3.1.1.tgz#32cfab55e84887c079a19bbb215e721d683ef134" + integrity sha512-uZgqzdTleelWjzJY+Fhti6F3C9iF1JR/dODLs/JDefozYcKTBCdD8BIl6nNPbTbcLnGrk56hzwZC2DaGNvYjzA== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-modules-values@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" + integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== + dependencies: + icss-utils "^5.0.0" + +postcss-normalize-charset@^5.1.0: + version "5.1.0" + resolved "https://registry.npmmirror.com/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz#9302de0b29094b52c259e9b2cf8dc0879879f0ed" + integrity sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg== + +postcss-normalize-display-values@^5.1.0: + version "5.1.0" + resolved "https://registry.npmmirror.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz#72abbae58081960e9edd7200fcf21ab8325c3da8" + integrity sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-positions@^5.1.1: + version "5.1.1" + resolved "https://registry.npmmirror.com/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz#ef97279d894087b59325b45c47f1e863daefbb92" + integrity sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-repeat-style@^5.1.1: + version "5.1.1" + resolved "https://registry.npmmirror.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz#e9eb96805204f4766df66fd09ed2e13545420fb2" + integrity sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-string@^5.1.0: + version "5.1.0" + resolved "https://registry.npmmirror.com/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz#411961169e07308c82c1f8c55f3e8a337757e228" + integrity sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-timing-functions@^5.1.0: + version "5.1.0" + resolved "https://registry.npmmirror.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz#d5614410f8f0b2388e9f240aa6011ba6f52dafbb" + integrity sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-normalize-unicode@^5.1.1: + version "5.1.1" + resolved "https://registry.npmmirror.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz#f67297fca3fea7f17e0d2caa40769afc487aa030" + integrity sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA== + dependencies: + browserslist "^4.21.4" + postcss-value-parser "^4.2.0" + +postcss-normalize-url@^5.1.0: + version "5.1.0" + resolved "https://registry.npmmirror.com/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz#ed9d88ca82e21abef99f743457d3729a042adcdc" + integrity sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew== + dependencies: + normalize-url "^6.0.1" + postcss-value-parser "^4.2.0" + +postcss-normalize-whitespace@^5.1.1: + version "5.1.1" + resolved "https://registry.npmmirror.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz#08a1a0d1ffa17a7cc6efe1e6c9da969cc4493cfa" + integrity sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-ordered-values@^5.1.3: + version "5.1.3" + resolved "https://registry.npmmirror.com/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz#b6fd2bd10f937b23d86bc829c69e7732ce76ea38" + integrity sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ== + dependencies: + cssnano-utils "^3.1.0" + postcss-value-parser "^4.2.0" + +postcss-reduce-idents@^5.2.0: + version "5.2.0" + resolved "https://registry.npmmirror.com/postcss-reduce-idents/-/postcss-reduce-idents-5.2.0.tgz#c89c11336c432ac4b28792f24778859a67dfba95" + integrity sha512-BTrLjICoSB6gxbc58D5mdBK8OhXRDqud/zodYfdSi52qvDHdMwk+9kB9xsM8yJThH/sZU5A6QVSmMmaN001gIg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-reduce-initial@^5.1.2: + version "5.1.2" + resolved "https://registry.npmmirror.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz#798cd77b3e033eae7105c18c9d371d989e1382d6" + integrity sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg== + dependencies: + browserslist "^4.21.4" + caniuse-api "^3.0.0" + +postcss-reduce-transforms@^5.1.0: + version "5.1.0" + resolved "https://registry.npmmirror.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz#333b70e7758b802f3dd0ddfe98bb1ccfef96b6e9" + integrity sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9: + version "6.0.16" + resolved "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz#3b88b9f5c5abd989ef4e2fc9ec8eedd34b20fb04" + integrity sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-sort-media-queries@^4.4.1: + version "4.4.1" + resolved "https://registry.npmmirror.com/postcss-sort-media-queries/-/postcss-sort-media-queries-4.4.1.tgz#04a5a78db3921eb78f28a1a781a2e68e65258128" + integrity sha512-QDESFzDDGKgpiIh4GYXsSy6sek2yAwQx1JASl5AxBtU1Lq2JfKBljIPNdil989NcSKRQX1ToiaKphImtBuhXWw== + dependencies: + sort-css-media-queries "2.1.0" + +postcss-svgo@^5.1.0: + version "5.1.0" + resolved "https://registry.npmmirror.com/postcss-svgo/-/postcss-svgo-5.1.0.tgz#0a317400ced789f233a28826e77523f15857d80d" + integrity sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA== + dependencies: + postcss-value-parser "^4.2.0" + svgo "^2.7.0" + +postcss-unique-selectors@^5.1.1: + version "5.1.1" + resolved "https://registry.npmmirror.com/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz#a9f273d1eacd09e9aa6088f4b0507b18b1b541b6" + integrity sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA== + dependencies: + postcss-selector-parser "^6.0.5" + +postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: + version "4.2.0" + resolved "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss-zindex@^5.1.0: + version "5.1.0" + resolved "https://registry.npmmirror.com/postcss-zindex/-/postcss-zindex-5.1.0.tgz#4a5c7e5ff1050bd4c01d95b1847dfdcc58a496ff" + integrity sha512-fgFMf0OtVSBR1va1JNHYgMxYk73yhn/qb4uQDq1DLGYolz8gHCyr/sesEuGUaYs58E3ZJRcpoGuPVoB7Meiq9A== + +postcss@^8.4.17, postcss@^8.4.21, postcss@^8.4.26, postcss@^8.4.33: + version "8.4.38" + resolved "https://registry.npmmirror.com/postcss/-/postcss-8.4.38.tgz#b387d533baf2054288e337066d81c6bee9db9e0e" + integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A== + dependencies: + nanoid "^3.3.7" + picocolors "^1.0.0" + source-map-js "^1.2.0" + +pretty-error@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/pretty-error/-/pretty-error-4.0.0.tgz#90a703f46dd7234adb46d0f84823e9d1cb8f10d6" + integrity sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw== + dependencies: + lodash "^4.17.20" + renderkid "^3.0.0" + +pretty-time@^1.1.0: + version "1.1.0" + resolved "https://registry.npmmirror.com/pretty-time/-/pretty-time-1.1.0.tgz#ffb7429afabb8535c346a34e41873adf3d74dd0e" + integrity sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA== + +prism-react-renderer@^2.3.0: + version "2.3.1" + resolved "https://registry.npmmirror.com/prism-react-renderer/-/prism-react-renderer-2.3.1.tgz#e59e5450052ede17488f6bc85de1553f584ff8d5" + integrity sha512-Rdf+HzBLR7KYjzpJ1rSoxT9ioO85nZngQEoFIhL07XhtJHlCU3SOz0GJ6+qvMyQe0Se+BV3qpe6Yd/NmQF5Juw== + dependencies: + "@types/prismjs" "^1.26.0" + clsx "^2.0.0" + +prismjs@^1.29.0: + version "1.29.0" + resolved "https://registry.npmmirror.com/prismjs/-/prismjs-1.29.0.tgz#f113555a8fa9b57c35e637bba27509dcf802dd12" + integrity sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q== + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +prompts@^2.4.2: + version "2.4.2" + resolved "https://registry.npmmirror.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + +prop-types@^15.6.2, prop-types@^15.7.2: + version "15.8.1" + resolved "https://registry.npmmirror.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + +property-information@^6.0.0: + version "6.4.1" + resolved "https://registry.npmmirror.com/property-information/-/property-information-6.4.1.tgz#de8b79a7415fd2107dfbe65758bb2cc9dfcf60ac" + integrity sha512-OHYtXfu5aI2sS2LWFSN5rgJjrQ4pCy8i1jubJLe2QvMF8JJ++HXTUIVWFLfXJoaOfvYYjk2SN8J2wFUWIGXT4w== + +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.npmmirror.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA== + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.npmmirror.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +punycode@^1.3.2: + version "1.4.1" + resolved "https://registry.npmmirror.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== + +punycode@^2.1.0: + version "2.3.1" + resolved "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + +pupa@^3.1.0: + version "3.1.0" + resolved "https://registry.npmmirror.com/pupa/-/pupa-3.1.0.tgz#f15610274376bbcc70c9a3aa8b505ea23f41c579" + integrity sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug== + dependencies: + escape-goat "^4.0.0" + +qs@6.11.0: + version "6.11.0" + resolved "https://registry.npmmirror.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +queue@6.0.2: + version "6.0.2" + resolved "https://registry.npmmirror.com/queue/-/queue-6.0.2.tgz#b91525283e2315c7553d2efa18d83e76432fed65" + integrity sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA== + dependencies: + inherits "~2.0.3" + +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.npmmirror.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +range-parser@1.2.0: + version "1.2.0" + resolved "https://registry.npmmirror.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + integrity sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A== + +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.npmmirror.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.2: + version "2.5.2" + resolved "https://registry.npmmirror.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" + integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +rc@1.2.8: + version "1.2.8" + resolved "https://registry.npmmirror.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +react-dev-utils@^12.0.1: + version "12.0.1" + resolved "https://registry.npmmirror.com/react-dev-utils/-/react-dev-utils-12.0.1.tgz#ba92edb4a1f379bd46ccd6bcd4e7bc398df33e73" + integrity sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ== + dependencies: + "@babel/code-frame" "^7.16.0" + address "^1.1.2" + browserslist "^4.18.1" + chalk "^4.1.2" + cross-spawn "^7.0.3" + detect-port-alt "^1.1.6" + escape-string-regexp "^4.0.0" + filesize "^8.0.6" + find-up "^5.0.0" + fork-ts-checker-webpack-plugin "^6.5.0" + global-modules "^2.0.0" + globby "^11.0.4" + gzip-size "^6.0.0" + immer "^9.0.7" + is-root "^2.1.0" + loader-utils "^3.2.0" + open "^8.4.0" + pkg-up "^3.1.0" + prompts "^2.4.2" + react-error-overlay "^6.0.11" + recursive-readdir "^2.2.2" + shell-quote "^1.7.3" + strip-ansi "^6.0.1" + text-table "^0.2.0" + +react-dom@^18.0.0: + version "18.2.0" + resolved "https://registry.npmmirror.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" + integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== + dependencies: + loose-envify "^1.1.0" + scheduler "^0.23.0" + +react-error-overlay@^6.0.11: + version "6.0.11" + resolved "https://registry.npmmirror.com/react-error-overlay/-/react-error-overlay-6.0.11.tgz#92835de5841c5cf08ba00ddd2d677b6d17ff9adb" + integrity sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg== + +react-fast-compare@^3.2.0, react-fast-compare@^3.2.2: + version "3.2.2" + resolved "https://registry.npmmirror.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" + integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ== + +react-helmet-async@*: + version "2.0.4" + resolved "https://registry.npmmirror.com/react-helmet-async/-/react-helmet-async-2.0.4.tgz#50a4377778f380ed1d0136303916b38eff1bf153" + integrity sha512-yxjQMWposw+akRfvpl5+8xejl4JtUlHnEBcji6u8/e6oc7ozT+P9PNTWMhCbz2y9tc5zPegw2BvKjQA+NwdEjQ== + dependencies: + invariant "^2.2.4" + react-fast-compare "^3.2.2" + shallowequal "^1.1.0" + +react-helmet-async@^1.3.0: + version "1.3.0" + resolved "https://registry.npmmirror.com/react-helmet-async/-/react-helmet-async-1.3.0.tgz#7bd5bf8c5c69ea9f02f6083f14ce33ef545c222e" + integrity sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg== + dependencies: + "@babel/runtime" "^7.12.5" + invariant "^2.2.4" + prop-types "^15.7.2" + react-fast-compare "^3.2.0" + shallowequal "^1.1.0" + +react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0: + version "16.13.1" + resolved "https://registry.npmmirror.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +react-json-view-lite@^1.2.0: + version "1.3.0" + resolved "https://registry.npmmirror.com/react-json-view-lite/-/react-json-view-lite-1.3.0.tgz#1f1feee6f1b1d75cc498cd57812f441b88b51e21" + integrity sha512-aN1biKC5v4DQkmQBlZjuMFR09MKZGMPtIg+cut8zEeg2HXd6gl2gRy0n4HMacHf0dznQgo0SVXN7eT8zV3hEuQ== + +react-loadable-ssr-addon-v5-slorber@^1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz#2cdc91e8a744ffdf9e3556caabeb6e4278689883" + integrity sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A== + dependencies: + "@babel/runtime" "^7.10.3" + +react-router-config@^5.1.1: + version "5.1.1" + resolved "https://registry.npmmirror.com/react-router-config/-/react-router-config-5.1.1.tgz#0f4263d1a80c6b2dc7b9c1902c9526478194a988" + integrity sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg== + dependencies: + "@babel/runtime" "^7.1.2" + +react-router-dom@^5.3.4: + version "5.3.4" + resolved "https://registry.npmmirror.com/react-router-dom/-/react-router-dom-5.3.4.tgz#2ed62ffd88cae6db134445f4a0c0ae8b91d2e5e6" + integrity sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ== + dependencies: + "@babel/runtime" "^7.12.13" + history "^4.9.0" + loose-envify "^1.3.1" + prop-types "^15.6.2" + react-router "5.3.4" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + +react-router@5.3.4, react-router@^5.3.4: + version "5.3.4" + resolved "https://registry.npmmirror.com/react-router/-/react-router-5.3.4.tgz#8ca252d70fcc37841e31473c7a151cf777887bb5" + integrity sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA== + dependencies: + "@babel/runtime" "^7.12.13" + history "^4.9.0" + hoist-non-react-statics "^3.1.0" + loose-envify "^1.3.1" + path-to-regexp "^1.7.0" + prop-types "^15.6.2" + react-is "^16.6.0" + tiny-invariant "^1.0.2" + tiny-warning "^1.0.0" + +react@^18.0.0: + version "18.2.0" + resolved "https://registry.npmmirror.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" + integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== + dependencies: + loose-envify "^1.1.0" + +readable-stream@^2.0.1: + version "2.3.8" + resolved "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.0.6: + version "3.6.2" + resolved "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +reading-time@^1.5.0: + version "1.5.0" + resolved "https://registry.npmmirror.com/reading-time/-/reading-time-1.5.0.tgz#d2a7f1b6057cb2e169beaf87113cc3411b5bc5bb" + integrity sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg== + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.npmmirror.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw== + dependencies: + resolve "^1.1.6" + +recursive-readdir@^2.2.2: + version "2.2.3" + resolved "https://registry.npmmirror.com/recursive-readdir/-/recursive-readdir-2.2.3.tgz#e726f328c0d69153bcabd5c322d3195252379372" + integrity sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA== + dependencies: + minimatch "^3.0.5" + +regenerate-unicode-properties@^10.1.0: + version "10.1.1" + resolved "https://registry.npmmirror.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz#6b0e05489d9076b04c436f318d9b067bba459480" + integrity sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q== + dependencies: + regenerate "^1.4.2" + +regenerate@^1.4.2: + version "1.4.2" + resolved "https://registry.npmmirror.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== + +regenerator-runtime@^0.14.0: + version "0.14.1" + resolved "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== + +regenerator-transform@^0.15.2: + version "0.15.2" + resolved "https://registry.npmmirror.com/regenerator-transform/-/regenerator-transform-0.15.2.tgz#5bbae58b522098ebdf09bca2f83838929001c7a4" + integrity sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg== + dependencies: + "@babel/runtime" "^7.8.4" + +regexpu-core@^5.3.1: + version "5.3.2" + resolved "https://registry.npmmirror.com/regexpu-core/-/regexpu-core-5.3.2.tgz#11a2b06884f3527aec3e93dbbf4a3b958a95546b" + integrity sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ== + dependencies: + "@babel/regjsgen" "^0.8.0" + regenerate "^1.4.2" + regenerate-unicode-properties "^10.1.0" + regjsparser "^0.9.1" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.1.0" + +registry-auth-token@^5.0.1: + version "5.0.2" + resolved "https://registry.npmmirror.com/registry-auth-token/-/registry-auth-token-5.0.2.tgz#8b026cc507c8552ebbe06724136267e63302f756" + integrity sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ== + dependencies: + "@pnpm/npm-conf" "^2.1.0" + +registry-url@^6.0.0: + version "6.0.1" + resolved "https://registry.npmmirror.com/registry-url/-/registry-url-6.0.1.tgz#056d9343680f2f64400032b1e199faa692286c58" + integrity sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q== + dependencies: + rc "1.2.8" + +regjsparser@^0.9.1: + version "0.9.1" + resolved "https://registry.npmmirror.com/regjsparser/-/regjsparser-0.9.1.tgz#272d05aa10c7c1f67095b1ff0addae8442fc5709" + integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ== + dependencies: + jsesc "~0.5.0" + +rehype-raw@^7.0.0: + version "7.0.0" + resolved "https://registry.npmmirror.com/rehype-raw/-/rehype-raw-7.0.0.tgz#59d7348fd5dbef3807bbaa1d443efd2dd85ecee4" + integrity sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww== + dependencies: + "@types/hast" "^3.0.0" + hast-util-raw "^9.0.0" + vfile "^6.0.0" + +relateurl@^0.2.7: + version "0.2.7" + resolved "https://registry.npmmirror.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + integrity sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog== + +remark-directive@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/remark-directive/-/remark-directive-3.0.0.tgz#34452d951b37e6207d2e2a4f830dc33442923268" + integrity sha512-l1UyWJ6Eg1VPU7Hm/9tt0zKtReJQNOA4+iDMAxTyZNWnJnFlbS/7zhiel/rogTLQ2vMYwDzSJa4BiVNqGlqIMA== + dependencies: + "@types/mdast" "^4.0.0" + mdast-util-directive "^3.0.0" + micromark-extension-directive "^3.0.0" + unified "^11.0.0" + +remark-emoji@^4.0.0: + version "4.0.1" + resolved "https://registry.npmmirror.com/remark-emoji/-/remark-emoji-4.0.1.tgz#671bfda668047689e26b2078c7356540da299f04" + integrity sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg== + dependencies: + "@types/mdast" "^4.0.2" + emoticon "^4.0.1" + mdast-util-find-and-replace "^3.0.1" + node-emoji "^2.1.0" + unified "^11.0.4" + +remark-frontmatter@^5.0.0: + version "5.0.0" + resolved "https://registry.npmmirror.com/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz#b68d61552a421ec412c76f4f66c344627dc187a2" + integrity sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ== + dependencies: + "@types/mdast" "^4.0.0" + mdast-util-frontmatter "^2.0.0" + micromark-extension-frontmatter "^2.0.0" + unified "^11.0.0" + +remark-gfm@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/remark-gfm/-/remark-gfm-4.0.0.tgz#aea777f0744701aa288b67d28c43565c7e8c35de" + integrity sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA== + dependencies: + "@types/mdast" "^4.0.0" + mdast-util-gfm "^3.0.0" + micromark-extension-gfm "^3.0.0" + remark-parse "^11.0.0" + remark-stringify "^11.0.0" + unified "^11.0.0" + +remark-mdx@^3.0.0: + version "3.0.1" + resolved "https://registry.npmmirror.com/remark-mdx/-/remark-mdx-3.0.1.tgz#8f73dd635c1874e44426e243f72c0977cf60e212" + integrity sha512-3Pz3yPQ5Rht2pM5R+0J2MrGoBSrzf+tJG94N+t/ilfdh8YLyyKYtidAYwTveB20BoHAcwIopOUqhcmh2F7hGYA== + dependencies: + mdast-util-mdx "^3.0.0" + micromark-extension-mdxjs "^3.0.0" + +remark-parse@^11.0.0: + version "11.0.0" + resolved "https://registry.npmmirror.com/remark-parse/-/remark-parse-11.0.0.tgz#aa60743fcb37ebf6b069204eb4da304e40db45a1" + integrity sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA== + dependencies: + "@types/mdast" "^4.0.0" + mdast-util-from-markdown "^2.0.0" + micromark-util-types "^2.0.0" + unified "^11.0.0" + +remark-rehype@^11.0.0: + version "11.1.0" + resolved "https://registry.npmmirror.com/remark-rehype/-/remark-rehype-11.1.0.tgz#d5f264f42bcbd4d300f030975609d01a1697ccdc" + integrity sha512-z3tJrAs2kIs1AqIIy6pzHmAHlF1hWQ+OdY4/hv+Wxe35EhyLKcajL33iUEn3ScxtFox9nUvRufR/Zre8Q08H/g== + dependencies: + "@types/hast" "^3.0.0" + "@types/mdast" "^4.0.0" + mdast-util-to-hast "^13.0.0" + unified "^11.0.0" + vfile "^6.0.0" + +remark-stringify@^11.0.0: + version "11.0.0" + resolved "https://registry.npmmirror.com/remark-stringify/-/remark-stringify-11.0.0.tgz#4c5b01dd711c269df1aaae11743eb7e2e7636fd3" + integrity sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw== + dependencies: + "@types/mdast" "^4.0.0" + mdast-util-to-markdown "^2.0.0" + unified "^11.0.0" + +renderkid@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/renderkid/-/renderkid-3.0.0.tgz#5fd823e4d6951d37358ecc9a58b1f06836b6268a" + integrity sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg== + dependencies: + css-select "^4.1.3" + dom-converter "^0.2.0" + htmlparser2 "^6.1.0" + lodash "^4.17.21" + strip-ansi "^6.0.1" + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.npmmirror.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +"require-like@>= 0.1.1": + version "0.1.2" + resolved "https://registry.npmmirror.com/require-like/-/require-like-0.1.2.tgz#ad6f30c13becd797010c468afa775c0c0a6b47fa" + integrity sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + +resolve-alpn@^1.2.0: + version "1.2.1" + resolved "https://registry.npmmirror.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" + integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-pathname@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" + integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== + +resolve@^1.1.6, resolve@^1.14.2: + version "1.22.8" + resolved "https://registry.npmmirror.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +responselike@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/responselike/-/responselike-3.0.0.tgz#20decb6c298aff0dbee1c355ca95461d42823626" + integrity sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg== + dependencies: + lowercase-keys "^3.0.0" + +retry@^0.13.1: + version "0.13.1" + resolved "https://registry.npmmirror.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +rtl-detect@^1.0.4: + version "1.1.2" + resolved "https://registry.npmmirror.com/rtl-detect/-/rtl-detect-1.1.2.tgz#ca7f0330af5c6bb626c15675c642ba85ad6273c6" + integrity sha512-PGMBq03+TTG/p/cRB7HCLKJ1MgDIi07+QU1faSjiYRfmY5UsAttV9Hs08jDAHVwcOwmVLcSJkpwyfXszVjWfIQ== + +rtlcss@^4.1.0: + version "4.1.1" + resolved "https://registry.npmmirror.com/rtlcss/-/rtlcss-4.1.1.tgz#f20409fcc197e47d1925996372be196fee900c0c" + integrity sha512-/oVHgBtnPNcggP2aVXQjSy6N1mMAfHg4GSag0QtZBlD5bdDgAHwr4pydqJGd+SUCu9260+Pjqbjwtvu7EMH1KQ== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + postcss "^8.4.21" + strip-json-comments "^3.1.1" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sax@^1.2.4: + version "1.3.0" + resolved "https://registry.npmmirror.com/sax/-/sax-1.3.0.tgz#a5dbe77db3be05c9d1ee7785dbd3ea9de51593d0" + integrity sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA== + +scheduler@^0.23.0: + version "0.23.0" + resolved "https://registry.npmmirror.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" + integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== + dependencies: + loose-envify "^1.1.0" + +schema-utils@2.7.0: + version "2.7.0" + resolved "https://registry.npmmirror.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" + integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== + dependencies: + "@types/json-schema" "^7.0.4" + ajv "^6.12.2" + ajv-keywords "^3.4.1" + +schema-utils@^3.0.0, schema-utils@^3.1.1, schema-utils@^3.2.0: + version "3.3.0" + resolved "https://registry.npmmirror.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" + integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^4.0.0: + version "4.2.0" + resolved "https://registry.npmmirror.com/schema-utils/-/schema-utils-4.2.0.tgz#70d7c93e153a273a805801882ebd3bff20d89c8b" + integrity sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.9.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.1.0" + +section-matter@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/section-matter/-/section-matter-1.0.0.tgz#e9041953506780ec01d59f292a19c7b850b84167" + integrity sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA== + dependencies: + extend-shallow "^2.0.1" + kind-of "^6.0.0" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== + +selfsigned@^2.1.1: + version "2.4.1" + resolved "https://registry.npmmirror.com/selfsigned/-/selfsigned-2.4.1.tgz#560d90565442a3ed35b674034cec4e95dceb4ae0" + integrity sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q== + dependencies: + "@types/node-forge" "^1.3.0" + node-forge "^1" + +semver-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/semver-diff/-/semver-diff-4.0.0.tgz#3afcf5ed6d62259f5c72d0d5d50dffbdc9680df5" + integrity sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA== + dependencies: + semver "^7.3.5" + +semver@^6.3.1: + version "6.3.1" + resolved "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.3.2, semver@^7.3.5, semver@^7.3.7, semver@^7.5.4: + version "7.6.0" + resolved "https://registry.npmmirror.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" + integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== + dependencies: + lru-cache "^6.0.0" + +send@0.18.0: + version "0.18.0" + resolved "https://registry.npmmirror.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serialize-javascript@^6.0.0, serialize-javascript@^6.0.1: + version "6.0.2" + resolved "https://registry.npmmirror.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" + integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== + dependencies: + randombytes "^2.1.0" + +serve-handler@^6.1.5: + version "6.1.5" + resolved "https://registry.npmmirror.com/serve-handler/-/serve-handler-6.1.5.tgz#a4a0964f5c55c7e37a02a633232b6f0d6f068375" + integrity sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg== + dependencies: + bytes "3.0.0" + content-disposition "0.5.2" + fast-url-parser "1.1.3" + mime-types "2.1.18" + minimatch "3.1.2" + path-is-inside "1.0.2" + path-to-regexp "2.2.1" + range-parser "1.2.0" + +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.npmmirror.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw== + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.npmmirror.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +set-function-length@^1.2.1: + version "1.2.2" + resolved "https://registry.npmmirror.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.npmmirror.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + +shallowequal@^1.1.0: + version "1.1.0" + resolved "https://registry.npmmirror.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" + integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +shell-quote@^1.7.3, shell-quote@^1.8.1: + version "1.8.1" + resolved "https://registry.npmmirror.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680" + integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== + +shelljs@^0.8.5: + version "0.8.5" + resolved "https://registry.npmmirror.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" + integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + +side-channel@^1.0.4: + version "1.0.6" + resolved "https://registry.npmmirror.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" + integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + object-inspect "^1.13.1" + +signal-exit@^3.0.2, signal-exit@^3.0.3: + version "3.0.7" + resolved "https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +sirv@^2.0.3: + version "2.0.4" + resolved "https://registry.npmmirror.com/sirv/-/sirv-2.0.4.tgz#5dd9a725c578e34e449f332703eb2a74e46a29b0" + integrity sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ== + dependencies: + "@polka/url" "^1.0.0-next.24" + mrmime "^2.0.0" + totalist "^3.0.0" + +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.npmmirror.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + +sitemap@^7.1.1: + version "7.1.1" + resolved "https://registry.npmmirror.com/sitemap/-/sitemap-7.1.1.tgz#eeed9ad6d95499161a3eadc60f8c6dce4bea2bef" + integrity sha512-mK3aFtjz4VdJN0igpIJrinf3EO8U8mxOPsTBzSsy06UtjZQJ3YY3o3Xa7zSc5nMqcMrRwlChHZ18Kxg0caiPBg== + dependencies: + "@types/node" "^17.0.5" + "@types/sax" "^1.2.1" + arg "^5.0.0" + sax "^1.2.4" + +skin-tone@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/skin-tone/-/skin-tone-2.0.0.tgz#4e3933ab45c0d4f4f781745d64b9f4c208e41237" + integrity sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA== + dependencies: + unicode-emoji-modifier-base "^1.0.0" + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slash@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" + integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== + +sockjs@^0.3.24: + version "0.3.24" + resolved "https://registry.npmmirror.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" + integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== + dependencies: + faye-websocket "^0.11.3" + uuid "^8.3.2" + websocket-driver "^0.7.4" + +sort-css-media-queries@2.1.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/sort-css-media-queries/-/sort-css-media-queries-2.1.0.tgz#7c85e06f79826baabb232f5560e9745d7a78c4ce" + integrity sha512-IeWvo8NkNiY2vVYdPa27MCQiR0MN0M80johAYFVxWWXQ44KU84WNxjslwBHmc/7ZL2ccwkM7/e6S5aiKZXm7jA== + +source-map-js@^1.2.0: + version "1.2.0" + resolved "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af" + integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== + +source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0: + version "0.6.1" + resolved "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@^0.7.0: + version "0.7.4" + resolved "https://registry.npmmirror.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" + integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== + +space-separated-tokens@^2.0.0: + version "2.0.2" + resolved "https://registry.npmmirror.com/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz#1ecd9d2350a3844572c3f4a312bceb018348859f" + integrity sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q== + +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.2: + version "4.0.2" + resolved "https://registry.npmmirror.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" + integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + +srcset@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/srcset/-/srcset-4.0.0.tgz#336816b665b14cd013ba545b6fe62357f86e65f4" + integrity sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw== + +stable@^0.1.8: + version "0.1.8" + resolved "https://registry.npmmirror.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" + integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.npmmirror.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +"statuses@>= 1.4.0 < 2": + version "1.5.0" + resolved "https://registry.npmmirror.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + +std-env@^3.0.1: + version "3.7.0" + resolved "https://registry.npmmirror.com/std-env/-/std-env-3.7.0.tgz#c9f7386ced6ecf13360b6c6c55b8aaa4ef7481d2" + integrity sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg== + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.3" + resolved "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.npmmirror.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +stringify-entities@^4.0.0: + version "4.0.3" + resolved "https://registry.npmmirror.com/stringify-entities/-/stringify-entities-4.0.3.tgz#cfabd7039d22ad30f3cc435b0ca2c1574fc88ef8" + integrity sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g== + dependencies: + character-entities-html4 "^2.0.0" + character-entities-legacy "^3.0.0" + +stringify-object@^3.3.0: + version "3.3.0" + resolved "https://registry.npmmirror.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" + integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== + dependencies: + get-own-enumerable-property-symbols "^3.0.0" + is-obj "^1.0.1" + is-regexp "^1.0.0" + +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + +strip-bom-string@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/strip-bom-string/-/strip-bom-string-1.0.0.tgz#e5211e9224369fbb81d633a2f00044dc8cedad92" + integrity sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g== + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== + +style-to-object@^0.4.0: + version "0.4.4" + resolved "https://registry.npmmirror.com/style-to-object/-/style-to-object-0.4.4.tgz#266e3dfd56391a7eefb7770423612d043c3f33ec" + integrity sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg== + dependencies: + inline-style-parser "0.1.1" + +style-to-object@^1.0.0: + version "1.0.6" + resolved "https://registry.npmmirror.com/style-to-object/-/style-to-object-1.0.6.tgz#0c28aed8be1813d166c60d962719b2907c26547b" + integrity sha512-khxq+Qm3xEyZfKd/y9L3oIWQimxuc4STrQKtQn8aSDRHb8mFgpukgX1hdzfrMEW6JCjyJ8p89x+IUMVnCBI1PA== + dependencies: + inline-style-parser "0.2.3" + +stylehacks@^5.1.1: + version "5.1.1" + resolved "https://registry.npmmirror.com/stylehacks/-/stylehacks-5.1.1.tgz#7934a34eb59d7152149fa69d6e9e56f2fc34bcc9" + integrity sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw== + dependencies: + browserslist "^4.21.4" + postcss-selector-parser "^6.0.4" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.npmmirror.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +svg-parser@^2.0.4: + version "2.0.4" + resolved "https://registry.npmmirror.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" + integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== + +svgo@^2.7.0, svgo@^2.8.0: + version "2.8.0" + resolved "https://registry.npmmirror.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24" + integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg== + dependencies: + "@trysound/sax" "0.2.0" + commander "^7.2.0" + css-select "^4.1.3" + css-tree "^1.1.3" + csso "^4.2.0" + picocolors "^1.0.0" + stable "^0.1.8" + +tapable@^1.0.0: + version "1.1.3" + resolved "https://registry.npmmirror.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== + +tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1: + version "2.2.1" + resolved "https://registry.npmmirror.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +terser-webpack-plugin@^5.3.10, terser-webpack-plugin@^5.3.9: + version "5.3.10" + resolved "https://registry.npmmirror.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199" + integrity sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w== + dependencies: + "@jridgewell/trace-mapping" "^0.3.20" + jest-worker "^27.4.5" + schema-utils "^3.1.1" + serialize-javascript "^6.0.1" + terser "^5.26.0" + +terser@^5.10.0, terser@^5.15.1, terser@^5.26.0: + version "5.30.0" + resolved "https://registry.npmmirror.com/terser/-/terser-5.30.0.tgz#64cb2af71e16ea3d32153f84d990f9be0cdc22bf" + integrity sha512-Y/SblUl5kEyEFzhMAQdsxVHh+utAxd4IuRNJzKywY/4uzSogh3G219jqbDDxYu4MXO9CzY3tSEqmZvW6AoEDJw== + dependencies: + "@jridgewell/source-map" "^0.3.3" + acorn "^8.8.2" + commander "^2.20.0" + source-map-support "~0.5.20" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.npmmirror.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + +tiny-invariant@^1.0.2: + version "1.3.3" + resolved "https://registry.npmmirror.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127" + integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg== + +tiny-warning@^1.0.0: + version "1.0.3" + resolved "https://registry.npmmirror.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" + integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +totalist@^3.0.0: + version "3.0.1" + resolved "https://registry.npmmirror.com/totalist/-/totalist-3.0.1.tgz#ba3a3d600c915b1a97872348f79c127475f6acf8" + integrity sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ== + +trim-lines@^3.0.0: + version "3.0.1" + resolved "https://registry.npmmirror.com/trim-lines/-/trim-lines-3.0.1.tgz#d802e332a07df861c48802c04321017b1bd87338" + integrity sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg== + +trough@^2.0.0: + version "2.2.0" + resolved "https://registry.npmmirror.com/trough/-/trough-2.2.0.tgz#94a60bd6bd375c152c1df911a4b11d5b0256f50f" + integrity sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw== + +tslib@^2.0.3, tslib@^2.6.0: + version "2.6.2" + resolved "https://registry.npmmirror.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + +type-fest@^1.0.1: + version "1.4.0" + resolved "https://registry.npmmirror.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1" + integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA== + +type-fest@^2.13.0, type-fest@^2.5.0: + version "2.19.0" + resolved "https://registry.npmmirror.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" + integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.npmmirror.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.npmmirror.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + +typescript@~5.2.2: + version "5.2.2" + resolved "https://registry.npmmirror.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" + integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== + +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.npmmirror.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + +unicode-canonical-property-names-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" + integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== + +unicode-emoji-modifier-base@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz#dbbd5b54ba30f287e2a8d5a249da6c0cef369459" + integrity sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g== + +unicode-match-property-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" + integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== + dependencies: + unicode-canonical-property-names-ecmascript "^2.0.0" + unicode-property-aliases-ecmascript "^2.0.0" + +unicode-match-property-value-ecmascript@^2.1.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz#cb5fffdcd16a05124f5a4b0bf7c3770208acbbe0" + integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA== + +unicode-property-aliases-ecmascript@^2.0.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" + integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== + +unified@^11.0.0, unified@^11.0.3, unified@^11.0.4: + version "11.0.4" + resolved "https://registry.npmmirror.com/unified/-/unified-11.0.4.tgz#f4be0ac0fe4c88cb873687c07c64c49ed5969015" + integrity sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ== + dependencies: + "@types/unist" "^3.0.0" + bail "^2.0.0" + devlop "^1.0.0" + extend "^3.0.0" + is-plain-obj "^4.0.0" + trough "^2.0.0" + vfile "^6.0.0" + +unique-string@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/unique-string/-/unique-string-3.0.0.tgz#84a1c377aff5fd7a8bc6b55d8244b2bd90d75b9a" + integrity sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ== + dependencies: + crypto-random-string "^4.0.0" + +unist-util-is@^6.0.0: + version "6.0.0" + resolved "https://registry.npmmirror.com/unist-util-is/-/unist-util-is-6.0.0.tgz#b775956486aff107a9ded971d996c173374be424" + integrity sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw== + dependencies: + "@types/unist" "^3.0.0" + +unist-util-position-from-estree@^2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz#d94da4df596529d1faa3de506202f0c9a23f2200" + integrity sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ== + dependencies: + "@types/unist" "^3.0.0" + +unist-util-position@^5.0.0: + version "5.0.0" + resolved "https://registry.npmmirror.com/unist-util-position/-/unist-util-position-5.0.0.tgz#678f20ab5ca1207a97d7ea8a388373c9cf896be4" + integrity sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA== + dependencies: + "@types/unist" "^3.0.0" + +unist-util-remove-position@^5.0.0: + version "5.0.0" + resolved "https://registry.npmmirror.com/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz#fea68a25658409c9460408bc6b4991b965b52163" + integrity sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q== + dependencies: + "@types/unist" "^3.0.0" + unist-util-visit "^5.0.0" + +unist-util-stringify-position@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz#449c6e21a880e0855bf5aabadeb3a740314abac2" + integrity sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ== + dependencies: + "@types/unist" "^3.0.0" + +unist-util-visit-parents@^6.0.0: + version "6.0.1" + resolved "https://registry.npmmirror.com/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz#4d5f85755c3b8f0dc69e21eca5d6d82d22162815" + integrity sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw== + dependencies: + "@types/unist" "^3.0.0" + unist-util-is "^6.0.0" + +unist-util-visit@^5.0.0: + version "5.0.0" + resolved "https://registry.npmmirror.com/unist-util-visit/-/unist-util-visit-5.0.0.tgz#a7de1f31f72ffd3519ea71814cccf5fd6a9217d6" + integrity sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg== + dependencies: + "@types/unist" "^3.0.0" + unist-util-is "^6.0.0" + unist-util-visit-parents "^6.0.0" + +universalify@^2.0.0: + version "2.0.1" + resolved "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +update-browserslist-db@^1.0.13: + version "1.0.13" + resolved "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" + integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +update-notifier@^6.0.2: + version "6.0.2" + resolved "https://registry.npmmirror.com/update-notifier/-/update-notifier-6.0.2.tgz#a6990253dfe6d5a02bd04fbb6a61543f55026b60" + integrity sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og== + dependencies: + boxen "^7.0.0" + chalk "^5.0.1" + configstore "^6.0.0" + has-yarn "^3.0.0" + import-lazy "^4.0.0" + is-ci "^3.0.1" + is-installed-globally "^0.4.0" + is-npm "^6.0.0" + is-yarn-global "^0.4.0" + latest-version "^7.0.0" + pupa "^3.1.0" + semver "^7.3.7" + semver-diff "^4.0.0" + xdg-basedir "^5.1.0" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +url-loader@^4.1.1: + version "4.1.1" + resolved "https://registry.npmmirror.com/url-loader/-/url-loader-4.1.1.tgz#28505e905cae158cf07c92ca622d7f237e70a4e2" + integrity sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA== + dependencies: + loader-utils "^2.0.0" + mime-types "^2.1.27" + schema-utils "^3.0.0" + +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +utila@~0.4: + version "0.4.0" + resolved "https://registry.npmmirror.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" + integrity sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA== + +utility-types@^3.10.0: + version "3.11.0" + resolved "https://registry.npmmirror.com/utility-types/-/utility-types-3.11.0.tgz#607c40edb4f258915e901ea7995607fdf319424c" + integrity sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw== + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +value-equal@^1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c" + integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw== + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +vfile-location@^5.0.0: + version "5.0.2" + resolved "https://registry.npmmirror.com/vfile-location/-/vfile-location-5.0.2.tgz#220d9ca1ab6f8b2504a4db398f7ebc149f9cb464" + integrity sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg== + dependencies: + "@types/unist" "^3.0.0" + vfile "^6.0.0" + +vfile-message@^4.0.0: + version "4.0.2" + resolved "https://registry.npmmirror.com/vfile-message/-/vfile-message-4.0.2.tgz#c883c9f677c72c166362fd635f21fc165a7d1181" + integrity sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw== + dependencies: + "@types/unist" "^3.0.0" + unist-util-stringify-position "^4.0.0" + +vfile@^6.0.0, vfile@^6.0.1: + version "6.0.1" + resolved "https://registry.npmmirror.com/vfile/-/vfile-6.0.1.tgz#1e8327f41eac91947d4fe9d237a2dd9209762536" + integrity sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw== + dependencies: + "@types/unist" "^3.0.0" + unist-util-stringify-position "^4.0.0" + vfile-message "^4.0.0" + +watchpack@^2.4.1: + version "2.4.1" + resolved "https://registry.npmmirror.com/watchpack/-/watchpack-2.4.1.tgz#29308f2cac150fa8e4c92f90e0ec954a9fed7fff" + integrity sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.npmmirror.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + +web-namespaces@^2.0.0: + version "2.0.1" + resolved "https://registry.npmmirror.com/web-namespaces/-/web-namespaces-2.0.1.tgz#1010ff7c650eccb2592cebeeaf9a1b253fd40692" + integrity sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ== + +webpack-bundle-analyzer@^4.9.0: + version "4.10.1" + resolved "https://registry.npmmirror.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.1.tgz#84b7473b630a7b8c21c741f81d8fe4593208b454" + integrity sha512-s3P7pgexgT/HTUSYgxJyn28A+99mmLq4HsJepMPzu0R8ImJc52QNqaFYW1Z2z2uIb1/J3eYgaAWVpaC+v/1aAQ== + dependencies: + "@discoveryjs/json-ext" "0.5.7" + acorn "^8.0.4" + acorn-walk "^8.0.0" + commander "^7.2.0" + debounce "^1.2.1" + escape-string-regexp "^4.0.0" + gzip-size "^6.0.0" + html-escaper "^2.0.2" + is-plain-object "^5.0.0" + opener "^1.5.2" + picocolors "^1.0.0" + sirv "^2.0.3" + ws "^7.3.1" + +webpack-dev-middleware@^5.3.4: + version "5.3.4" + resolved "https://registry.npmmirror.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz#eb7b39281cbce10e104eb2b8bf2b63fce49a3517" + integrity sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q== + dependencies: + colorette "^2.0.10" + memfs "^3.4.3" + mime-types "^2.1.31" + range-parser "^1.2.1" + schema-utils "^4.0.0" + +webpack-dev-server@^4.15.1: + version "4.15.2" + resolved "https://registry.npmmirror.com/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz#9e0c70a42a012560860adb186986da1248333173" + integrity sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g== + dependencies: + "@types/bonjour" "^3.5.9" + "@types/connect-history-api-fallback" "^1.3.5" + "@types/express" "^4.17.13" + "@types/serve-index" "^1.9.1" + "@types/serve-static" "^1.13.10" + "@types/sockjs" "^0.3.33" + "@types/ws" "^8.5.5" + ansi-html-community "^0.0.8" + bonjour-service "^1.0.11" + chokidar "^3.5.3" + colorette "^2.0.10" + compression "^1.7.4" + connect-history-api-fallback "^2.0.0" + default-gateway "^6.0.3" + express "^4.17.3" + graceful-fs "^4.2.6" + html-entities "^2.3.2" + http-proxy-middleware "^2.0.3" + ipaddr.js "^2.0.1" + launch-editor "^2.6.0" + open "^8.0.9" + p-retry "^4.5.0" + rimraf "^3.0.2" + schema-utils "^4.0.0" + selfsigned "^2.1.1" + serve-index "^1.9.1" + sockjs "^0.3.24" + spdy "^4.0.2" + webpack-dev-middleware "^5.3.4" + ws "^8.13.0" + +webpack-merge@^5.9.0: + version "5.10.0" + resolved "https://registry.npmmirror.com/webpack-merge/-/webpack-merge-5.10.0.tgz#a3ad5d773241e9c682803abf628d4cd62b8a4177" + integrity sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA== + dependencies: + clone-deep "^4.0.1" + flat "^5.0.2" + wildcard "^2.0.0" + +webpack-sources@^3.2.2, webpack-sources@^3.2.3: + version "3.2.3" + resolved "https://registry.npmmirror.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" + integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== + +webpack@^5.88.1: + version "5.91.0" + resolved "https://registry.npmmirror.com/webpack/-/webpack-5.91.0.tgz#ffa92c1c618d18c878f06892bbdc3373c71a01d9" + integrity sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw== + dependencies: + "@types/eslint-scope" "^3.7.3" + "@types/estree" "^1.0.5" + "@webassemblyjs/ast" "^1.12.1" + "@webassemblyjs/wasm-edit" "^1.12.1" + "@webassemblyjs/wasm-parser" "^1.12.1" + acorn "^8.7.1" + acorn-import-assertions "^1.9.0" + browserslist "^4.21.10" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.16.0" + es-module-lexer "^1.2.1" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.11" + json-parse-even-better-errors "^2.3.1" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.2.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.3.10" + watchpack "^2.4.1" + webpack-sources "^3.2.3" + +webpackbar@^5.0.2: + version "5.0.2" + resolved "https://registry.npmmirror.com/webpackbar/-/webpackbar-5.0.2.tgz#d3dd466211c73852741dfc842b7556dcbc2b0570" + integrity sha512-BmFJo7veBDgQzfWXl/wwYXr/VFus0614qZ8i9znqcl9fnEdiVkdbi0TedLQ6xAK92HZHDJ0QmyQ0fmuZPAgCYQ== + dependencies: + chalk "^4.1.0" + consola "^2.15.3" + pretty-time "^1.1.0" + std-env "^3.0.1" + +websocket-driver@>=0.5.1, websocket-driver@^0.7.4: + version "0.7.4" + resolved "https://registry.npmmirror.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.npmmirror.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + +which@^1.3.1: + version "1.3.1" + resolved "https://registry.npmmirror.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.npmmirror.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +widest-line@^4.0.1: + version "4.0.1" + resolved "https://registry.npmmirror.com/widest-line/-/widest-line-4.0.1.tgz#a0fc673aaba1ea6f0a0d35b3c2795c9a9cc2ebf2" + integrity sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig== + dependencies: + string-width "^5.0.1" + +wildcard@^2.0.0: + version "2.0.1" + resolved "https://registry.npmmirror.com/wildcard/-/wildcard-2.0.1.tgz#5ab10d02487198954836b6349f74fff961e10f67" + integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ== + +wrap-ansi@^8.0.1, wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +write-file-atomic@^3.0.3: + version "3.0.3" + resolved "https://registry.npmmirror.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== + dependencies: + imurmurhash "^0.1.4" + is-typedarray "^1.0.0" + signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" + +ws@^7.3.1: + version "7.5.9" + resolved "https://registry.npmmirror.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" + integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== + +ws@^8.13.0: + version "8.16.0" + resolved "https://registry.npmmirror.com/ws/-/ws-8.16.0.tgz#d1cd774f36fbc07165066a60e40323eab6446fd4" + integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ== + +xdg-basedir@^5.0.1, xdg-basedir@^5.1.0: + version "5.1.0" + resolved "https://registry.npmmirror.com/xdg-basedir/-/xdg-basedir-5.1.0.tgz#1efba19425e73be1bc6f2a6ceb52a3d2c884c0c9" + integrity sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ== + +xml-js@^1.6.11: + version "1.6.11" + resolved "https://registry.npmmirror.com/xml-js/-/xml-js-1.6.11.tgz#927d2f6947f7f1c19a316dd8eea3614e8b18f8e9" + integrity sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g== + dependencies: + sax "^1.2.4" + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2: + version "1.10.2" + resolved "https://registry.npmmirror.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +yocto-queue@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-1.0.0.tgz#7f816433fb2cbc511ec8bf7d263c3b58a1a3c251" + integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g== + +zwitch@^2.0.0: + version "2.0.4" + resolved "https://registry.npmmirror.com/zwitch/-/zwitch-2.0.4.tgz#c827d4b0acb76fc3e685a4c6ec2902d51070e9d7" + integrity sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A== diff --git a/internal/controller/obcluster_controller.go b/internal/controller/obcluster_controller.go index bc5dde90c..5dd8d4105 100644 --- a/internal/controller/obcluster_controller.go +++ b/internal/controller/obcluster_controller.go @@ -76,7 +76,7 @@ func (r *OBClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( // obcluster not found, just return return ctrl.Result{}, nil } - logger.Error(err, "get obcluster error") + logger.Error(err, "Get obcluster error") return ctrl.Result{}, err } diff --git a/internal/controller/obparameter_controller.go b/internal/controller/obparameter_controller.go index 9fae484a6..b9d84f272 100644 --- a/internal/controller/obparameter_controller.go +++ b/internal/controller/obparameter_controller.go @@ -61,7 +61,7 @@ func (r *OBParameterReconciler) Reconcile(ctx context.Context, req ctrl.Request) // obparameter not found, just return return ctrl.Result{}, nil } - logger.Error(err, "get obparameter error") + logger.Error(err, "Get obparameter error") return ctrl.Result{}, err } diff --git a/internal/controller/obresourcerescue_controller.go b/internal/controller/obresourcerescue_controller.go index 9a5c58b5a..1a05348a1 100644 --- a/internal/controller/obresourcerescue_controller.go +++ b/internal/controller/obresourcerescue_controller.go @@ -78,13 +78,13 @@ func (r *OBResourceRescueReconciler) Reconcile(ctx context.Context, req ctrl.Req gvk := schema.FromAPIVersionAndKind(gvStr, rescue.Spec.TargetKind) mapping, err := r.Client.RESTMapper().RESTMapping(gvk.GroupKind(), gvk.Version) if err != nil { - logger.Error(err, "failed to get REST mapping", "gvk", gvk) + logger.Error(err, "Failed to get REST mapping", "gvk", gvk) return ctrl.Result{}, err } uns, err := r.Dynamic.Resource(mapping.Resource).Namespace(rescue.GetNamespace()).Get(ctx, rescue.Spec.TargetResName, metav1.GetOptions{}) if err != nil { - logger.Error(err, "failed to get the target resource", "resource kind", rescue.Spec.TargetKind, "resource name", rescue.Spec.TargetResName) + logger.Error(err, "Failed to get the target resource", "resource kind", rescue.Spec.TargetKind, "resource name", rescue.Spec.TargetResName) return ctrl.Result{}, err } @@ -93,13 +93,13 @@ func (r *OBResourceRescueReconciler) Reconcile(ctx context.Context, req ctrl.Req uns.SetFinalizers(nil) _, err := r.Dynamic.Resource(mapping.Resource).Namespace(rescue.GetNamespace()).Update(ctx, uns, metav1.UpdateOptions{}) if err != nil { - logger.Error(err, "failed to update finalizers of the target resource") + logger.Error(err, "Failed to update finalizers of the target resource") return ctrl.Result{}, err } if uns.GetDeletionTimestamp() == nil { err = r.Dynamic.Resource(mapping.Resource).Namespace(rescue.GetNamespace()).Delete(ctx, rescue.Spec.TargetResName, metav1.DeleteOptions{}) if err != nil { - logger.Error(err, "failed to delete the target resource") + logger.Error(err, "Failed to delete the target resource") return ctrl.Result{}, err } } @@ -109,12 +109,12 @@ func (r *OBResourceRescueReconciler) Reconcile(ctx context.Context, req ctrl.Req unstructured.SetNestedField(uns.Object, rescue.Spec.TargetStatus, "status", "status"), ) if err != nil { - logger.Error(err, "failed to reset fields of the target resource") + logger.Error(err, "Failed to reset fields of the target resource") return ctrl.Result{}, err } _, err = r.Dynamic.Resource(mapping.Resource).Namespace(rescue.GetNamespace()).UpdateStatus(ctx, uns, metav1.UpdateOptions{}) if err != nil { - logger.Error(err, "failed to update status of the target resource") + logger.Error(err, "Failed to update status of the target resource") return ctrl.Result{}, err } case "retry": @@ -122,20 +122,20 @@ func (r *OBResourceRescueReconciler) Reconcile(ctx context.Context, req ctrl.Req // operationContext.FailureRule.RetryCount = 0 context, exist, err := unstructured.NestedMap(uns.Object, "status", "operationContext") if err != nil { - logger.Error(err, "failed to get operationContext fields of the target resource") + logger.Error(err, "Failed to get operationContext fields of the target resource") return ctrl.Result{}, nil } if !exist { - logger.Info("operationContext not found", "resource kind", uns.GetKind(), "resource name", uns.GetName()) + logger.Info("OperationContext not found", "resource kind", uns.GetKind(), "resource name", uns.GetName()) return ctrl.Result{}, nil } _, exist, err = unstructured.NestedMap(context, "failureRule") if err != nil { - logger.Error(err, "failed to get failureStrategy field of the target resource") + logger.Error(err, "Failed to get failureStrategy field of the target resource") return ctrl.Result{}, nil } if !exist { - logger.Info("failureStrategy not found", "resource kind", uns.GetKind(), "resource name", uns.GetName()) + logger.Info("FailureStrategy not found", "resource kind", uns.GetKind(), "resource name", uns.GetName()) return ctrl.Result{}, nil } @@ -146,12 +146,12 @@ func (r *OBResourceRescueReconciler) Reconcile(ctx context.Context, req ctrl.Req unstructured.SetNestedField(uns.Object, retryCount, "status", "operationContext", "failureRule", "retryCount"), ) if err != nil { - logger.Error(err, "failed to set operationContext fields of the target resource") + logger.Error(err, "Failed to set operationContext fields of the target resource") return ctrl.Result{}, err } _, err = r.Dynamic.Resource(mapping.Resource).Namespace(rescue.GetNamespace()).UpdateStatus(ctx, uns, metav1.UpdateOptions{}) if err != nil { - logger.Error(err, "failed to update status of the target resource") + logger.Error(err, "Failed to update status of the target resource") return ctrl.Result{}, err } case "skip": @@ -159,21 +159,21 @@ func (r *OBResourceRescueReconciler) Reconcile(ctx context.Context, req ctrl.Req // When coordinator finds that the task status is `successful`, it will go on the following steps. _, exist, err := unstructured.NestedMap(uns.Object, "status", "operationContext") if err != nil { - logger.Error(err, "failed to get operationContext fields of the target resource") + logger.Error(err, "Failed to get operationContext fields of the target resource") return ctrl.Result{}, nil } if !exist { - logger.Info("operationContext not found", "resource kind", uns.GetKind(), "resource name", uns.GetName()) + logger.Info("OperationContext not found", "resource kind", uns.GetKind(), "resource name", uns.GetName()) return ctrl.Result{}, nil } err = unstructured.SetNestedField(uns.Object, taskstatus.Successful, "status", "operationContext", "taskStatus") if err != nil { - logger.Error(err, "failed to reset fields of the target resource") + logger.Error(err, "Failed to reset fields of the target resource") return ctrl.Result{}, err } _, err = r.Dynamic.Resource(mapping.Resource).Namespace(rescue.GetNamespace()).UpdateStatus(ctx, uns, metav1.UpdateOptions{}) if err != nil { - logger.Error(err, "failed to update status of the target resource") + logger.Error(err, "Failed to update status of the target resource") return ctrl.Result{}, err } case "ignore-deletion": @@ -185,7 +185,7 @@ func (r *OBResourceRescueReconciler) Reconcile(ctx context.Context, req ctrl.Req uns.SetAnnotations(annotations) _, err := r.Dynamic.Resource(mapping.Resource).Namespace(rescue.GetNamespace()).Update(ctx, uns, metav1.UpdateOptions{}) if err != nil { - logger.Error(err, "failed to update annotations of the target resource") + logger.Error(err, "Failed to update annotations of the target resource") return ctrl.Result{}, err } } diff --git a/internal/controller/observer_controller.go b/internal/controller/observer_controller.go index 46ad5131d..6032b7266 100644 --- a/internal/controller/observer_controller.go +++ b/internal/controller/observer_controller.go @@ -73,7 +73,7 @@ func (r *OBServerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c // observer not found, just return return ctrl.Result{}, nil } - logger.Error(err, "get observer error") + logger.Error(err, "Get observer error") return ctrl.Result{}, err } @@ -99,7 +99,7 @@ func (r *OBServerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c if needExecuteFinalizer { err = resobserver.DeleteOBServerInCluster(observerManager) if err != nil { - logger.Error(err, "delete observer failed") + logger.Error(err, "Delete observer failed") return ctrl.Result{}, errors.Wrapf(err, "delete observer %s failed", observer.Name) } } diff --git a/internal/controller/obtenant_controller.go b/internal/controller/obtenant_controller.go index 83be737ff..f917e7281 100644 --- a/internal/controller/obtenant_controller.go +++ b/internal/controller/obtenant_controller.go @@ -27,11 +27,10 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/log" + v1alpha1 "github.com/oceanbase/ob-operator/api/v1alpha1" resobtenant "github.com/oceanbase/ob-operator/internal/resource/obtenant" "github.com/oceanbase/ob-operator/internal/telemetry" "github.com/oceanbase/ob-operator/pkg/coordinator" - - v1alpha1 "github.com/oceanbase/ob-operator/api/v1alpha1" ) // OBTenantReconciler reconciles a OBTenant object @@ -67,7 +66,7 @@ func (r *OBTenantReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c // observer not found, just return return ctrl.Result{}, nil } - logger.Error(err, "get obtenant error") + logger.Error(err, "Get obtenant error") return ctrl.Result{}, err } @@ -77,7 +76,7 @@ func (r *OBTenantReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c controllerutil.AddFinalizer(obtenant, finalizerName) err := r.Client.Update(ctx, obtenant) if err != nil { - logger.Error(err, "got error when update finalizers") + logger.Error(err, "Got error when update finalizers") return ctrl.Result{}, err } } diff --git a/internal/controller/obzone_controller.go b/internal/controller/obzone_controller.go index 9d959814c..791c5976f 100644 --- a/internal/controller/obzone_controller.go +++ b/internal/controller/obzone_controller.go @@ -65,7 +65,7 @@ func (r *OBZoneReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr // obzone not found, just return return ctrl.Result{}, nil } - logger.Error(err, "get obzone error") + logger.Error(err, "Get obzone error") return ctrl.Result{}, err } diff --git a/internal/dashboard/business/metric/metric.go b/internal/dashboard/business/metric/metric.go index 869bb59e3..d897f1130 100644 --- a/internal/dashboard/business/metric/metric.go +++ b/internal/dashboard/business/metric/metric.go @@ -166,7 +166,7 @@ func QueryMetricData(queryParam *param.MetricQuery) []response.MetricData { go func(metric string, ch chan []response.MetricData) { defer wg.Done() expr := replaceQueryVariables(exprTemplate, queryParam.Labels, queryParam.GroupLabels, queryParam.QueryRange.Step) - logger.Infof("query with expr: %s, range: %v", expr, queryParam.QueryRange) + logger.Infof("Query with expr: %s, range: %v", expr, queryParam.QueryRange) queryRangeResp := &external.PrometheusQueryRangeResponse{} resp, err := client.R().SetQueryParams(map[string]string{ "start": strconv.FormatFloat(queryParam.QueryRange.StartTimestamp, 'f', 3, 64), diff --git a/internal/dashboard/business/oceanbase/obcluster.go b/internal/dashboard/business/oceanbase/obcluster.go index cd33ad7a4..cc39eed40 100644 --- a/internal/dashboard/business/oceanbase/obcluster.go +++ b/internal/dashboard/business/oceanbase/obcluster.go @@ -272,7 +272,7 @@ func ListOBClusters(ctx context.Context) ([]response.OBClusterOverview, error) { for _, obcluster := range obclusterList.Items { resp, err := buildOBClusterOverview(ctx, &obcluster) if err != nil { - logger.Errorf("failed to build obcluster response: %v", err) + logger.Errorf("Failed to build obcluster response: %v", err) } obclusters = append(obclusters, *resp) } diff --git a/internal/dashboard/generated/bindata/bindata.go b/internal/dashboard/generated/bindata/bindata.go index c1a063e45..7beac828f 100644 --- a/internal/dashboard/generated/bindata/bindata.go +++ b/internal/dashboard/generated/bindata/bindata.go @@ -200,11 +200,13 @@ var _bindata = map[string]func() (*asset, error){ // directory embedded in the file by go-bindata. // For example if you run go-bindata on data/... and data contains the // following hierarchy: -// data/ -// foo.txt -// img/ -// a.png -// b.png +// +// data/ +// foo.txt +// img/ +// a.png +// b.png +// // then AssetDir("data") would return []string{"foo.txt", "img"} // AssetDir("data/img") would return []string{"a.png", "b.png"} // AssetDir("foo.txt") and AssetDir("notexist") would return an error diff --git a/internal/dashboard/middleware/authentication.go b/internal/dashboard/middleware/authentication.go index d90f36dff..fa818ae16 100644 --- a/internal/dashboard/middleware/authentication.go +++ b/internal/dashboard/middleware/authentication.go @@ -62,7 +62,7 @@ func LoginRequired() gin.HandlerFunc { session.Options(sessions.Options{Path: "/", MaxAge: -1}) // this sets the cookie with a MaxAge of 0 err := session.Save() if err != nil { - log.Errorf("failed to save session: %v", err) + log.Errorf("Failed to save session: %v", err) c.AbortWithStatusJSON(500, gin.H{ "message": "failed to save session", }) @@ -88,7 +88,7 @@ func RefreshExpiration() gin.HandlerFunc { session.Set("expiration", expiration.Unix()) err := session.Save() if err != nil { - log.Errorf("failed to save session: %v", err) + log.Errorf("Failed to save session: %v", err) c.AbortWithStatusJSON(500, gin.H{ "message": "failed to save session", }) diff --git a/internal/resource/obcluster/obcluster_manager.go b/internal/resource/obcluster/obcluster_manager.go index e6d7a8469..ed3ec76ba 100644 --- a/internal/resource/obcluster/obcluster_manager.go +++ b/internal/resource/obcluster/obcluster_manager.go @@ -52,7 +52,7 @@ func (m *OBClusterManager) GetStatus() string { func (m *OBClusterManager) InitStatus() { m.Logger.Info("Newly created cluster, init status") - m.Recorder.Event(m.OBCluster, "Init", "", "newly created cluster, init status") + m.Recorder.Event(m.OBCluster, "Init", "", "Newly created cluster, init status") _, migrateAnnoExist := resourceutils.GetAnnotationField(m.OBCluster, oceanbaseconst.AnnotationsSourceClusterAddress) initialStatus := clusterstatus.New if migrateAnnoExist { @@ -287,7 +287,7 @@ func (m *OBClusterManager) PrintErrEvent(err error) { func (m *OBClusterManager) ArchiveResource() { m.Logger.Info("Archive obcluster", "obcluster", m.OBCluster.Name) - m.Recorder.Event(m.OBCluster, "Archive", "", "archive obcluster") + m.Recorder.Event(m.OBCluster, "Archive", "", "Archive obcluster") m.OBCluster.Status.Status = "Failed" m.OBCluster.Status.OperationContext = nil } diff --git a/internal/resource/obcluster/obcluster_task.go b/internal/resource/obcluster/obcluster_task.go index 850519314..d17d3de01 100644 --- a/internal/resource/obcluster/obcluster_task.go +++ b/internal/resource/obcluster/obcluster_task.go @@ -193,7 +193,7 @@ func CreateOBZone(m *OBClusterManager) tasktypes.TaskError { m.Logger.Info("Create obzone", "zone", zoneName) err := m.Client.Create(m.Ctx, obzone) if err != nil { - m.Logger.Error(err, "create obzone failed", "zone", zone.Zone) + m.Logger.Error(err, "Failed to create obzone", "zone", zone.Zone) return errors.Wrap(err, "create obzone") } m.Recorder.Event(m.OBCluster, "CreateOBZone", "", fmt.Sprintf("Create obzone %s successfully", zoneName)) @@ -389,7 +389,7 @@ func ValidateUpgradeInfo(m *OBClusterManager) tasktypes.TaskError { if jobObject.Status.Succeeded == 1 { m.Logger.V(oceanbaseconst.LogLevelDebug).Info("Job succeeded") } else { - m.Logger.V(oceanbaseconst.LogLevelDebug).Info("Job is failed", "job", jobName) + m.Logger.V(oceanbaseconst.LogLevelDebug).Info("Job failed", "job", jobName) return errors.Wrap(err, "Failed to run validate job") } return nil @@ -493,7 +493,7 @@ func ModifySysTenantReplica(m *OBClusterManager) tasktypes.TaskError { zoneList = append(zoneList, zone) } } - m.Logger.Info("Modify sys pool's zone list when add zone", "zone list", zoneList) + m.Logger.Info("Modify sys pool's zone list", "zone list", zoneList) err = oceanbaseOperationManager.AlterPool(&model.PoolParam{ PoolName: oceanbaseconst.SysTenantPool, ZoneList: zoneList, @@ -549,7 +549,7 @@ func ModifySysTenantReplica(m *OBClusterManager) tasktypes.TaskError { if !found { newReplicas := obutil.OmitZoneFromReplicas(replicas, r.Zone) locality = obutil.ConvertToLocalityStr(newReplicas) - m.Logger.Info("Modify sys tenant's locality when delete zone", "locality", locality) + m.Logger.Info("Modify sys tenant's locality when deleting zone", "locality", locality) err = oceanbaseOperationManager.SetTenant(model.TenantSQLParam{ TenantName: oceanbaseconst.SysTenant, Locality: locality, diff --git a/internal/resource/obcluster/utils.go b/internal/resource/obcluster/utils.go index 278a6a0af..5646b50ef 100644 --- a/internal/resource/obcluster/utils.go +++ b/internal/resource/obcluster/utils.go @@ -129,37 +129,32 @@ func (m *OBClusterManager) getOceanbaseOperationManager() (*operation.OceanbaseO } func (m *OBClusterManager) createUser(userName, secretName, privilege string) error { - m.Logger.V(oceanbaseconst.LogLevelDebug).Info("begin create user", "username", userName) + m.Logger.V(oceanbaseconst.LogLevelDebug).Info("Begin to create user", "username", userName) password, err := resourceutils.ReadPassword(m.Client, m.OBCluster.Namespace, secretName) if err != nil { return errors.Wrapf(err, "Get password from secret %s failed", secretName) } - m.Logger.V(oceanbaseconst.LogLevelDebug).Info("finish get password", "username", userName, "password", password) oceanbaseOperationManager, err := m.getOceanbaseOperationManager() if err != nil { m.Logger.Error(err, "Get oceanbase operation manager") return errors.Wrap(err, "Get oceanbase operation manager") } - m.Logger.V(oceanbaseconst.LogLevelDebug).Info("finish get operationmanager", "username", userName) err = oceanbaseOperationManager.CreateUser(userName) if err != nil { m.Logger.Error(err, "Create user") return errors.Wrapf(err, "Create user %s", userName) } - m.Logger.V(oceanbaseconst.LogLevelDebug).Info("finish create user", "username", userName) err = oceanbaseOperationManager.SetUserPassword(userName, password) if err != nil { m.Logger.Error(err, "Set user password") return errors.Wrapf(err, "Set password for user %s", userName) } - m.Logger.V(oceanbaseconst.LogLevelDebug).Info("finish set user password", "username", userName) object := "*.*" err = oceanbaseOperationManager.GrantPrivilege(privilege, object, userName) if err != nil { m.Logger.Error(err, "Grant privilege") return errors.Wrapf(err, "Grant privilege for user %s", userName) } - m.Logger.V(oceanbaseconst.LogLevelDebug).Info("finish grant user privilege", "username", userName) return nil } diff --git a/internal/resource/obparameter/obparameter_manager.go b/internal/resource/obparameter/obparameter_manager.go index 42a05ac11..92be8a5be 100644 --- a/internal/resource/obparameter/obparameter_manager.go +++ b/internal/resource/obparameter/obparameter_manager.go @@ -193,7 +193,7 @@ func (m *OBParameterManager) PrintErrEvent(err error) { func (m *OBParameterManager) ArchiveResource() { m.Logger.Info("Archive obparameter", "obparameter", m.OBParameter.Name) - m.Recorder.Event(m.OBParameter, "Archive", "", "archive obparameter") + m.Recorder.Event(m.OBParameter, "Archive", "", "Archive obparameter") m.OBParameter.Status.Status = "Failed" m.OBParameter.Status.OperationContext = nil } diff --git a/internal/resource/observer/observer_manager.go b/internal/resource/observer/observer_manager.go index b4f0c41a4..ba0b0f05b 100644 --- a/internal/resource/observer/observer_manager.go +++ b/internal/resource/observer/observer_manager.go @@ -292,7 +292,7 @@ func (m *OBServerManager) PrintErrEvent(err error) { func (m *OBServerManager) ArchiveResource() { m.Logger.Info("Archive observer", "observer", m.OBServer.Name) - m.Recorder.Event(m.OBServer, "Archive", "", "archive observer") + m.Recorder.Event(m.OBServer, "Archive", "", "Archive observer") m.OBServer.Status.Status = "Failed" m.OBServer.Status.OperationContext = nil } diff --git a/internal/resource/observer/observer_task.go b/internal/resource/observer/observer_task.go index d953f76b1..353608788 100644 --- a/internal/resource/observer/observer_task.go +++ b/internal/resource/observer/observer_task.go @@ -97,7 +97,7 @@ func WaitOBClusterBootstrapped(m *OBServerManager) tasktypes.TaskError { } func CreateOBPod(m *OBServerManager) tasktypes.TaskError { - m.Logger.V(oceanbaseconst.LogLevelDebug).Info("create observer pod") + m.Logger.V(oceanbaseconst.LogLevelDebug).Info("Create observer pod") obcluster, err := m.getOBCluster() if err != nil { return errors.Wrap(err, "Get obcluster from K8s") @@ -218,7 +218,7 @@ func CreateOBPVC(m *OBServerManager) tasktypes.TaskError { } func DeleteOBServerInCluster(m *OBServerManager) tasktypes.TaskError { - m.Logger.V(oceanbaseconst.LogLevelDebug).Info("delete observer in cluster") + m.Logger.V(oceanbaseconst.LogLevelDebug).Info("Delete observer in cluster") operationManager, err := m.getOceanbaseOperationManager() if err != nil { return errors.Wrapf(err, "Get oceanbase operation manager failed") @@ -233,16 +233,16 @@ func DeleteOBServerInCluster(m *OBServerManager) tasktypes.TaskError { } if observer != nil && observer.Status != "deleting" { if observer.Status == "deleting" { - m.Logger.Info("observer is deleting", "observer", observerInfo.Ip) + m.Logger.Info("OBServer is deleting", "observer", observerInfo.Ip) } else { - m.Logger.Info("need to delete observer") + m.Logger.Info("Need to delete observer") err = operationManager.DeleteServer(observerInfo) if err != nil { return errors.Wrapf(err, "Failed to delete observer %s", observerInfo.Ip) } } } else { - m.Logger.Info("observer already deleted", "observer", observerInfo.Ip) + m.Logger.Info("OBServer already deleted", "observer", observerInfo.Ip) } return nil } @@ -297,7 +297,7 @@ func WaitOBServerPodReady(m *OBServerManager) tasktypes.TaskError { } } if observerPodRestarted { - m.Logger.Info("observer pod restarted") + m.Logger.Info("OBServer pod restarted") break } time.Sleep(time.Second) @@ -312,7 +312,7 @@ func WaitOBServerActiveInCluster(m *OBServerManager) tasktypes.TaskError { if m.OBServer.SupportStaticIP() { return nil } - m.Logger.Info("wait observer active in cluster") + m.Logger.Info("Wait for observer to be active in cluster") observerInfo := &model.ServerInfo{ Ip: m.OBServer.Status.GetConnectAddr(), Port: oceanbaseconst.RpcPort, @@ -347,7 +347,7 @@ func WaitOBServerDeletedInCluster(m *OBServerManager) tasktypes.TaskError { if m.OBServer.SupportStaticIP() { return nil } - m.Logger.Info("wait observer deleted in cluster") + m.Logger.Info("Wait for observer to be deleted in cluster") observerInfo := &model.ServerInfo{ Ip: m.OBServer.Status.GetConnectAddr(), Port: oceanbaseconst.RpcPort, diff --git a/internal/resource/observer/utils.go b/internal/resource/observer/utils.go index 30b15358c..15f741141 100644 --- a/internal/resource/observer/utils.go +++ b/internal/resource/observer/utils.go @@ -132,7 +132,7 @@ func (m *OBServerManager) setRecoveryStatus() { m.Logger.Info("Current server can keep static ip address or the cluster runs as standalone, recover by recreating pod") m.OBServer.Status.Status = serverstatus.Recover } else { - m.Logger.Info("observer not recoverable, delete current observer and wait recreate") + m.Logger.Info("OBServer is not recoverable, delete current observer and wait recreate") m.OBServer.Status.Status = serverstatus.Unrecoverable } } @@ -481,7 +481,7 @@ func (m *OBServerManager) createOBServerContainer(obcluster *v1alpha1.OBCluster) svc, err := m.getSvc() if err != nil { if kubeerrors.IsNotFound(err) { - m.Logger.Info("svc not found") + m.Logger.Info("Svc not found") } else { m.Logger.Error(err, "Failed to get svc") } @@ -546,7 +546,7 @@ func (m *OBServerManager) generateStaticIpAnnotation() map[string]string { annotations[oceanbaseconst.AnnotationCalicoIpAddrs] = fmt.Sprintf("[\"%s\"]", m.OBServer.Status.PodIp) } default: - m.Logger.Info("static ip not supported, set empty annotation") + m.Logger.Info("Static ip not supported, set empty annotation") } return annotations } diff --git a/internal/resource/obtenant/obtenant_manager.go b/internal/resource/obtenant/obtenant_manager.go index cd0ba2cb0..e06b4ce0b 100644 --- a/internal/resource/obtenant/obtenant_manager.go +++ b/internal/resource/obtenant/obtenant_manager.go @@ -92,12 +92,12 @@ func (m *OBTenantManager) InitStatus() { if m.OBTenant.Spec.Source != nil && m.OBTenant.Spec.Source.Restore != nil { m.OBTenant.Status.Status = tenantstatus.Restoring - m.Recorder.Event(m.OBTenant, "InitRestore", "", "start restoring") + m.Recorder.Event(m.OBTenant, "InitRestore", "", "Start restoring") } else if m.OBTenant.Spec.Source != nil && m.OBTenant.Spec.Source.Tenant != nil { - m.Recorder.Event(m.OBTenant, "InitEmptyStandby", "", "start creating empty standby") + m.Recorder.Event(m.OBTenant, "InitEmptyStandby", "", "Start creating empty standby") m.OBTenant.Status.Status = tenantstatus.CreatingEmptyStandby } else { - m.Recorder.Event(m.OBTenant, "Init", "", "start creating") + m.Recorder.Event(m.OBTenant, "Init", "", "Start creating") m.OBTenant.Status.Status = tenantstatus.CreatingTenant } } @@ -301,7 +301,7 @@ func (m *OBTenantManager) PrintErrEvent(err error) { func (m *OBTenantManager) ArchiveResource() { m.Logger.Info("Archive obtenant", "obtenant", m.OBTenant.Name) - m.Recorder.Event(m.OBTenant, "Archive", "", "archive obtenant") + m.Recorder.Event(m.OBTenant, "Archive", "", "Archive obtenant") m.OBTenant.Status.OperationContext = nil m.OBTenant.Status.Status = "Failed" } @@ -320,7 +320,7 @@ func (m *OBTenantManager) getOBCluster() (*v1alpha1.OBCluster, error) { obcluster := &v1alpha1.OBCluster{} err := m.Client.Get(m.Ctx, m.generateNamespacedName(clusterName), obcluster) if err != nil { - m.Logger.Error(err, "get obcluster failed", "clusterName", clusterName, "namespaced", m.OBTenant.Namespace) + m.Logger.Error(err, "Failed to get obcluster", "clusterName", clusterName, "namespaced", m.OBTenant.Namespace) return nil, errors.Wrap(err, "get obcluster failed") } return obcluster, nil diff --git a/internal/resource/obtenant/obtenant_task.go b/internal/resource/obtenant/obtenant_task.go index 1f9649710..38414c3b0 100644 --- a/internal/resource/obtenant/obtenant_task.go +++ b/internal/resource/obtenant/obtenant_task.go @@ -345,13 +345,13 @@ func WatchRestoreJobToFinish(m *OBTenantManager) tasktypes.TaskError { if runningRestore.Status.Status == constants.RestoreJobSuccessful { break } else if runningRestore.Status.Status == constants.RestoreJobFailed { - m.Recorder.Event(m.OBTenant, "RestoreJobFailed", "", "restore job failed") + m.Recorder.Event(m.OBTenant, "RestoreJobFailed", "", "Restore job failed") return errors.New("Restore job failed") } time.Sleep(5 * time.Second) } tenantWhiteListMap.Store(m.OBTenant.Spec.TenantName, m.OBTenant.Spec.ConnectWhiteList) - m.Recorder.Event(m.OBTenant, "RestoreJobFinished", "", "restore job finished successfully") + m.Recorder.Event(m.OBTenant, "RestoreJobFinished", "", "Restore job finished successfully") return nil } diff --git a/internal/resource/obtenant/utils.go b/internal/resource/obtenant/utils.go index 2ea63fc59..8d2667980 100644 --- a/internal/resource/obtenant/utils.go +++ b/internal/resource/obtenant/utils.go @@ -68,7 +68,7 @@ func (m *OBTenantManager) createTenant() tasktypes.TaskError { } tenantWhiteListMap.Store(tenantName, m.OBTenant.Spec.ConnectWhiteList) // Create user or change password of root, do not return error - m.Recorder.Event(m.OBTenant, "Create", "", "create OBTenant successfully") + m.Recorder.Event(m.OBTenant, "Create", "", "Create OBTenant successfully") return nil } diff --git a/internal/resource/obtenantbackup/obtenantbackup_manager.go b/internal/resource/obtenantbackup/obtenantbackup_manager.go index a8b7450af..f4a4020a7 100644 --- a/internal/resource/obtenantbackup/obtenantbackup_manager.go +++ b/internal/resource/obtenantbackup/obtenantbackup_manager.go @@ -154,7 +154,7 @@ func (m *OBTenantBackupManager) PrintErrEvent(err error) { func (m *OBTenantBackupManager) ArchiveResource() { m.Logger.Info("Archive obtenant backup job", "obtenant backup job", m.Resource.Name) - m.Recorder.Event(m.Resource, "Archive", "", "archive obtenant backup job") + m.Recorder.Event(m.Resource, "Archive", "", "Archive obtenant backup job") m.Resource.Status.Status = "Failed" m.Resource.Status.OperationContext = nil } @@ -197,7 +197,7 @@ func (m *OBTenantBackupManager) maintainRunningBackupJob() error { job := m.Resource con, err := m.getObOperationClient() if err != nil { - logger.Error(err, "failed to get ob operation client") + logger.Error(err, "Failed to get ob operation client") return err } var targetJob *model.OBBackupJob @@ -243,13 +243,13 @@ func (m *OBTenantBackupManager) maintainRunningBackupCleanJob() error { job := m.Resource con, err := m.getObOperationClient() if err != nil { - logger.Error(err, "failed to get ob operation client") + logger.Error(err, "Failed to get ob operation client") return err } latest, err := con.GetLatestBackupCleanJob() if err != nil { - logger.Error(err, "failed to query latest backup clean job") + logger.Error(err, "Failed to query latest backup clean job") return err } if latest != nil { @@ -277,13 +277,13 @@ func (m *OBTenantBackupManager) maintainRunningArchiveLogJob() error { job := m.Resource con, err := m.getObOperationClient() if err != nil { - logger.Error(err, "failed to get ob operation client") + logger.Error(err, "Failed to get ob operation client") return err } latest, err := con.GetLatestArchiveLogJob() if err != nil { - logger.Error(err, "failed to query latest archive log job") + logger.Error(err, "Failed to query latest archive log job") return err } if latest != nil { diff --git a/internal/resource/obtenantbackup/obtenantbackup_task.go b/internal/resource/obtenantbackup/obtenantbackup_task.go index 8f7e395ee..0e5d6dce6 100644 --- a/internal/resource/obtenantbackup/obtenantbackup_task.go +++ b/internal/resource/obtenantbackup/obtenantbackup_task.go @@ -50,6 +50,6 @@ func CreateBackupJobInOB(m *OBTenantBackupManager) tasktypes.TaskError { } // job.Status.BackupJob = latest - m.Recorder.Event(job, "Create", "", "create backup job successfully") + m.Recorder.Event(job, "Create", "", "Create backup job successfully") return nil } diff --git a/internal/resource/obtenantbackuppolicy/obtenantbackuppolicy_manager.go b/internal/resource/obtenantbackuppolicy/obtenantbackuppolicy_manager.go index 6f2451132..a3395b195 100644 --- a/internal/resource/obtenantbackuppolicy/obtenantbackuppolicy_manager.go +++ b/internal/resource/obtenantbackuppolicy/obtenantbackuppolicy_manager.go @@ -118,7 +118,7 @@ func (m *ObTenantBackupPolicyManager) InitStatus() { m.BackupPolicy.Status = v1alpha1.OBTenantBackupPolicyStatus{ Status: constants.BackupPolicyStatusPreparing, } - m.Recorder.Event(m.BackupPolicy, "Init", "", "init status") + m.Recorder.Event(m.BackupPolicy, "Init", "", "Init status") err = m.syncTenantInformation() if err != nil { m.PrintErrEvent(err) @@ -362,7 +362,7 @@ func (m *ObTenantBackupPolicyManager) PrintErrEvent(err error) { func (m *ObTenantBackupPolicyManager) ArchiveResource() { m.Logger.Info("Archive obtenant backup policy", "obtenant backup policy", m.BackupPolicy.Name) - m.Recorder.Event(m.BackupPolicy, "Archive", "", "archive obtenant backup policy") + m.Recorder.Event(m.BackupPolicy, "Archive", "", "Archive obtenant backup policy") m.BackupPolicy.Status.Status = "Failed" m.BackupPolicy.Status.OperationContext = nil } @@ -375,7 +375,7 @@ func (m *ObTenantBackupPolicyManager) getOBCluster() (*v1alpha1.OBCluster, error Name: clusterName, }, obcluster) if err != nil { - m.Logger.Error(err, "get obcluster failed", "clusterName", clusterName, "namespaced", m.BackupPolicy.Namespace) + m.Logger.Error(err, "Failed to get obcluster", "clusterName", clusterName, "namespaced", m.BackupPolicy.Namespace) return nil, errors.Wrap(err, "get obcluster failed") } return obcluster, nil @@ -397,7 +397,7 @@ func (m *ObTenantBackupPolicyManager) getOBTenantCR() (*v1alpha1.OBTenant, error }, tenant) if err != nil { if !kubeerrors.IsNotFound(err) { - m.Logger.Error(err, "get obtenant failed", "tenantCRName", tenantCRName, "namespaced", m.BackupPolicy.Namespace) + m.Logger.Error(err, "Failed to get obtenant", "tenantCRName", tenantCRName, "namespaced", m.BackupPolicy.Namespace) } return nil, err } diff --git a/internal/resource/obtenantoperation/obtenantoperation_manager.go b/internal/resource/obtenantoperation/obtenantoperation_manager.go index 0fe091d60..7e37c12f2 100644 --- a/internal/resource/obtenantoperation/obtenantoperation_manager.go +++ b/internal/resource/obtenantoperation/obtenantoperation_manager.go @@ -170,7 +170,7 @@ func (m *ObTenantOperationManager) UpdateStatus() error { func (m *ObTenantOperationManager) ArchiveResource() { m.Logger.Info("Archive obtenant operation", "obtenant operation", m.Resource.Name) - m.Recorder.Event(m.Resource, "Archive", "", "archive obtenant operation") + m.Recorder.Event(m.Resource, "Archive", "", "Archive obtenant operation") m.Resource.Status.Status = "Failed" m.Resource.Status.OperationContext = nil } diff --git a/internal/resource/obtenantrestore/obtenantrestore_manager.go b/internal/resource/obtenantrestore/obtenantrestore_manager.go index e52397696..6d9bc637a 100644 --- a/internal/resource/obtenantrestore/obtenantrestore_manager.go +++ b/internal/resource/obtenantrestore/obtenantrestore_manager.go @@ -220,7 +220,7 @@ func (m *ObTenantRestoreManager) PrintErrEvent(err error) { func (m *ObTenantRestoreManager) ArchiveResource() { m.Logger.Info("Archive obtenant restore job", "obtenant restore job", m.Resource.Name) - m.Recorder.Event(m.Resource, "Archive", "", "archive obtenant restore job") + m.Recorder.Event(m.Resource, "Archive", "", "Archive obtenant restore job") m.Resource.Status.Status = "Failed" m.Resource.Status.OperationContext = nil } diff --git a/internal/resource/obzone/obzone_manager.go b/internal/resource/obzone/obzone_manager.go index f765d661c..bbc6166f8 100644 --- a/internal/resource/obzone/obzone_manager.go +++ b/internal/resource/obzone/obzone_manager.go @@ -175,7 +175,7 @@ func (m *OBZoneManager) CheckAndUpdateFinalizers() error { func (m *OBZoneManager) ArchiveResource() { m.Logger.Info("Archive obzone", "obzone", m.OBZone.Name) - m.Recorder.Event(m.OBZone, "Archive", "", "archive obzone") + m.Recorder.Event(m.OBZone, "Archive", "", "Archive obzone") m.OBZone.Status.Status = "Failed" m.OBZone.Status.OperationContext = nil } diff --git a/internal/resource/obzone/obzone_task.go b/internal/resource/obzone/obzone_task.go index 2eb53b497..9812a39dc 100644 --- a/internal/resource/obzone/obzone_task.go +++ b/internal/resource/obzone/obzone_task.go @@ -119,7 +119,7 @@ func CreateOBServer(m *OBZoneManager) tasktypes.TaskError { m.Logger.Info("Create observer", "server", serverName) err := m.Client.Create(m.Ctx, observer) if err != nil { - m.Logger.Error(err, "create observer failed", "server", serverName) + m.Logger.Error(err, "Create observer failed", "server", serverName) return errors.Wrap(err, "create observer") } m.Recorder.Event(m.OBZone, "CreateObServer", "CreateObserver", fmt.Sprintf("Create observer %s", serverName)) @@ -178,6 +178,7 @@ func WaitReplicaMatch(m *OBZoneManager) tasktypes.TaskError { obzone, err := m.getOBZone() if err != nil { m.Logger.Error(err, "Get obzone from K8s failed") + return nil } else if m.OBZone.Spec.Topology.Replica == len(obzone.Status.OBServerStatus) { m.Logger.Info("OBZone replica matched") matched = true diff --git a/internal/resource/utils/util.go b/internal/resource/utils/util.go index ad6b6c920..74de8a277 100644 --- a/internal/resource/utils/util.go +++ b/internal/resource/utils/util.go @@ -232,15 +232,15 @@ func RunJob(c client.Client, logger *logr.Logger, namespace string, jobName stri // return errors.Wrapf(err, "Failed to get run upgrade script job for obcluster %s", obcluster.Name) } if jobObject.Status.Succeeded == 0 && jobObject.Status.Failed == 0 { - logger.V(oceanbaseconst.LogLevelDebug).Info("job is still running") + logger.V(oceanbaseconst.LogLevelDebug).Info("Job is still running") } else { - logger.V(oceanbaseconst.LogLevelDebug).Info("job finished") + logger.V(oceanbaseconst.LogLevelDebug).Info("Job finished") break } time.Sleep(time.Second * oceanbaseconst.CheckJobInterval) } if jobObject.Status.Succeeded == 1 { - logger.V(oceanbaseconst.LogLevelDebug).Info("job succeeded", "job", fullJobName) + logger.V(oceanbaseconst.LogLevelDebug).Info("Job succeeded", "job", fullJobName) clientSet := k8sclient.GetClient() podList, err := clientSet.ClientSet.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{ LabelSelector: fmt.Sprintf("job-name=%s", fullJobName), @@ -254,18 +254,18 @@ func RunJob(c client.Client, logger *logr.Logger, namespace string, jobName stri res := clientSet.ClientSet.CoreV1().Pods(namespace).GetLogs(pod.Name, &podLogOpts) logs, err := res.Stream(context.TODO()) if err != nil { - logger.Error(err, "failed to get job logs") + logger.Error(err, "Failed to get job logs") } else { defer logs.Close() _, err = io.Copy(&outputBuffer, logs) if err != nil { - logger.Error(err, "failed to copy logs") + logger.Error(err, "Failed to copy logs") } output = outputBuffer.String() } } else { - logger.V(oceanbaseconst.LogLevelDebug).Info("job failed", "job", fullJobName) - return "", errors.Wrapf(err, "failed to run job %s", fullJobName) + logger.V(oceanbaseconst.LogLevelDebug).Info("Job failed", "job", fullJobName) + return "", errors.Wrapf(err, "Failed to run job %s", fullJobName) } return output, nil } @@ -330,17 +330,17 @@ func ExecuteUpgradeScript(c client.Client, logger *logr.Logger, obcluster *v1alp // return errors.Wrapf(err, "Failed to get run upgrade script job for obcluster %s", obcluster.Name) } if jobObject.Status.Succeeded == 0 && jobObject.Status.Failed == 0 { - logger.V(oceanbaseconst.LogLevelDebug).Info("job is still running") + logger.V(oceanbaseconst.LogLevelDebug).Info("Job is still running") } else { - logger.V(oceanbaseconst.LogLevelDebug).Info("job finished") + logger.V(oceanbaseconst.LogLevelDebug).Info("Job finished") break } time.Sleep(time.Second * oceanbaseconst.CheckJobInterval) } if jobObject.Status.Succeeded == 1 { - logger.V(oceanbaseconst.LogLevelDebug).Info("job succeeded") + logger.V(oceanbaseconst.LogLevelDebug).Info("Job succeeded") } else { - logger.V(oceanbaseconst.LogLevelDebug).Info("job failed", "job", jobName) + logger.V(oceanbaseconst.LogLevelDebug).Info("Job failed", "job", jobName) return errors.Wrap(err, "Failed to run upgrade script job") } return nil diff --git a/internal/telemetry/throttler.go b/internal/telemetry/throttler.go index 2409e2ab3..aea71d690 100644 --- a/internal/telemetry/throttler.go +++ b/internal/telemetry/throttler.go @@ -44,7 +44,7 @@ func getThrottler() *throttler { throttlerSingleton.client = *http.DefaultClient throttlerSingleton.startWorkers() - getLogger().Println("telemetry throttler started", "#worker:", DefaultThrottlerWorkerCount) + getLogger().Println("Telemetry throttler started", "#worker:", DefaultThrottlerWorkerCount) }) return throttlerSingleton } @@ -92,15 +92,18 @@ func (t *throttler) startWorkers() { return } res, err := t.sendTelemetryRecord(record) - if debugMode { - if err != nil { - getLogger().Printf("send telemetry record error: %v\n", err) + if err == nil && res != nil && res.Body != nil { + if debugMode { + bts, err := io.ReadAll(res.Body) + if err != nil { + getLogger().Printf("Read response body error: %v\n", err) + } else { + getLogger().Printf("[Event %s.%s] %s\n", record.ResourceType, record.EventType, string(bts)) + } + } else { + _, _ = io.Copy(io.Discard, res.Body) } - bts, err := io.ReadAll(res.Body) - if err != nil { - getLogger().Printf("read response body error: %v\n", err) - } - getLogger().Printf("[Event %s.%s] %s\n", record.ResourceType, record.EventType, string(bts)) + _ = res.Body.Close() } case <-ctx.Done(): getLogger().Println(ctx.Err()) diff --git a/pkg/helper/upgrade.go b/pkg/helper/upgrade.go index 90371c915..2b6d19943 100644 --- a/pkg/helper/upgrade.go +++ b/pkg/helper/upgrade.go @@ -61,7 +61,7 @@ func GetOBUpgradeRoute(param *OBUpgradeRouteParam) ([]VersionDep, error) { if os.IsNotExist(err) { return nil, errors.New(fmt.Sprint("cannot find file: ", filePath)) } - log.Info("cat not read file: ", filePath, err) + log.Info("Can not read file: ", filePath, err) return nil, err } var versionDep []VersionDep @@ -177,7 +177,7 @@ func FindShortestUpgradePath(nodeMap map[string]*VersionDep, startVersionFull, t v.Precursor = node queue = append(queue, v) visited.Add(v) - log.Println("visited", v.Version, len(v.Next)) + log.Println("Visited", v.Version, len(v.Next)) } } } diff --git a/pkg/oceanbase-sdk/const/config/bootstrap.go b/pkg/oceanbase-sdk/const/config/bootstrap.go index d1f5295e8..00e637b69 100644 --- a/pkg/oceanbase-sdk/const/config/bootstrap.go +++ b/pkg/oceanbase-sdk/const/config/bootstrap.go @@ -17,5 +17,5 @@ import ( ) const ( - BootstrapTimeout = 600 * time.Second + BootstrapTimeout = 1800 * time.Second ) diff --git a/pkg/oceanbase-sdk/operation/parameter.go b/pkg/oceanbase-sdk/operation/parameter.go index 624a5b815..079138016 100644 --- a/pkg/oceanbase-sdk/operation/parameter.go +++ b/pkg/oceanbase-sdk/operation/parameter.go @@ -38,7 +38,7 @@ func (m *OceanbaseOperationManager) SetParameter(name string, value any, scope * return m.ExecWithDefaultTimeout(setParameterSql, value) } setParameterSql := fmt.Sprintf(sql.SetParameterWithScope, name, scope.Name) - m.Logger.Info("setParameterSql statement", "statement", setParameterSql) + m.Logger.Info("SetParameterSql statement", "statement", setParameterSql) return m.ExecWithDefaultTimeout(setParameterSql, value, scope.Value) } diff --git a/pkg/oceanbase-sdk/operation/tenant.go b/pkg/oceanbase-sdk/operation/tenant.go index 076785d14..d0e0bb65d 100644 --- a/pkg/oceanbase-sdk/operation/tenant.go +++ b/pkg/oceanbase-sdk/operation/tenant.go @@ -280,14 +280,14 @@ func (m *OceanbaseOperationManager) WaitTenantLocalityChangeFinished(name string m.Logger.Error(err, "Failed to get tenant info") } if tenant.PreviousLocality == "" { - m.Logger.V(oceanbaseconst.LogLevelTrace).Info("tenant locality change finished", "tenant name", name) + m.Logger.V(oceanbaseconst.LogLevelTrace).Info("Tenant locality change finished", "tenant name", name) finished = true break } time.Sleep(1 * time.Second) } if !finished { - return errors.Errorf("tenant %s locality change still not finished after %d seconds", name, timeoutSeconds) + return errors.Errorf("Tenant %s locality change still not finished after %d seconds", name, timeoutSeconds) } return nil } diff --git a/pkg/oceanbase-sdk/operation/zone.go b/pkg/oceanbase-sdk/operation/zone.go index 1a49a32f2..97418a8eb 100644 --- a/pkg/oceanbase-sdk/operation/zone.go +++ b/pkg/oceanbase-sdk/operation/zone.go @@ -24,7 +24,7 @@ func (m *OceanbaseOperationManager) AddZone(zoneName string) error { _, err := m.GetZone(zoneName) // TODO verify it's a not found error if err == nil { - m.Logger.Info("Obzone already exists in observer, skip add", "zone", zoneName) + m.Logger.Info("OBZone already exists in observer, skip add", "zone", zoneName) return nil } err = m.ExecWithDefaultTimeout(sql.AddZone, zoneName) @@ -42,8 +42,8 @@ func (m *OceanbaseOperationManager) DeleteZone(zoneName string) error { return errors.Wrapf(err, "Query obzone %s failed", zoneName) } if obzone.Status != zonestatus.Inactive { - m.Logger.Info("Obzone is not inactive, stop it before delete", "zone", zoneName) - return errors.Errorf("Obzone %s is not inactive, stop it before delete", zoneName) + m.Logger.Info("OBZone is not inactive, stop it before delete", "zone", zoneName) + return errors.Errorf("OBZone %s is not inactive, stop it before delete", zoneName) } err = m.ExecWithDefaultTimeout(sql.DeleteZone, zoneName) if err != nil { @@ -80,7 +80,7 @@ func (m *OceanbaseOperationManager) StartZone(zoneName string) error { return errors.Wrapf(err, "Query obzone %s failed", zoneName) } if obzone.Status == zonestatus.Active { - m.Logger.Info("Obzone already active", "zone", zoneName) + m.Logger.Info("OBZone already active", "zone", zoneName) return nil } err = m.ExecWithDefaultTimeout(sql.StartZone, zoneName) @@ -98,7 +98,7 @@ func (m *OceanbaseOperationManager) StopZone(zoneName string) error { return errors.Wrapf(err, "Query obzone %s failed", zoneName) } if obzone.Status == zonestatus.Inactive { - m.Logger.Info("Obzone already inactive", "zone", zoneName) + m.Logger.Info("OBZone already inactive", "zone", zoneName) return nil } err = m.ExecWithDefaultTimeout(sql.StopZone, zoneName) diff --git a/ui/config/routes.ts b/ui/config/routes.ts index 98faddf81..f9074a909 100644 --- a/ui/config/routes.ts +++ b/ui/config/routes.ts @@ -5,120 +5,127 @@ export default [ routes: [ { path: '/', - component: 'Layouts/BasicLayout', + component: 'Layouts/StatisticsLayout', name: '系统布局', routes: [ - { - path: 'cluster', - component: 'Cluster', - name: '集群页', - }, - { - path:'cluster/new', - component:'Cluster/New', - name: '创建集群', - }, - { - path:'tenant', - component:'Tenant', - name:'租户页' - }, - { - path:'tenant/new', - component:'Tenant/New', - name:'创建租户' - }, - { - path: 'overview', - component: 'Overview', - name: '系统概览页', - }, { path: '/', - redirect: 'overview', - name: '系统概览页', - }, - ], - }, - { - path: 'cluster/:clusterId', - component: 'Cluster/Detail', - name: '集群详情', - routes: [ - { - path: 'overview', - component: 'Cluster/Detail/Overview', - name: '概览页', - }, - { - path: 'topo', - component: 'Cluster/Detail/Topo', - name: '集群拓扑图', - }, - { - path:'monitor', - component:'Cluster/Detail/Monitor', - name:'集群详情监控' - }, - { - path:'tenant', - component:'Cluster/Detail/Tenant', - name:'集群下的租户' - }, - { - path: '/cluster/:clusterId', - redirect: 'overview', - name: '概览页', - }, - { - path: '/cluster/:clusterId/connection', - component: 'Cluster/Detail/Connection', - name: '集群连接', + component: 'Layouts/BasicLayout', + name: '概览布局', + routes: [ + { + path: 'cluster', + component: 'Cluster', + name: '集群页', + }, + { + path: 'cluster/new', + component: 'Cluster/New', + name: '创建集群', + }, + { + path: 'tenant', + component: 'Tenant', + name: '租户页', + }, + { + path: 'tenant/new', + component: 'Tenant/New', + name: '创建租户', + }, + { + path: 'overview', + component: 'Overview', + name: '系统概览页', + }, + { + path: '/', + redirect: 'overview', + name: '系统概览页', + }, + ], + }, + { + path: 'cluster/:clusterId', + component: 'Cluster/Detail', + name: '集群详情', + routes: [ + { + path: 'overview', + component: 'Cluster/Detail/Overview', + name: '概览页', + }, + { + path: 'topo', + component: 'Cluster/Detail/Topo', + name: '集群拓扑图', + }, + { + path: 'monitor', + component: 'Cluster/Detail/Monitor', + name: '集群详情监控', + }, + { + path: 'tenant', + component: 'Cluster/Detail/Tenant', + name: '集群下的租户', + }, + { + path: '/cluster/:clusterId', + redirect: 'overview', + name: '概览页', + }, + { + path: '/cluster/:clusterId/connection', + component: 'Cluster/Detail/Connection', + name: '集群连接', + }, + ], + }, + { + path: 'tenant/:tenantId', + component: 'Tenant/Detail', + name: '租户详情', + routes: [ + { + path: 'overview', + component: 'Tenant/Detail/Overview', + name: '概览页', + }, + { + path: 'topo', + component: 'Tenant/Detail/Topo', + name: '租户拓扑图', + }, + { + path: 'backup', + component: 'Tenant/Detail/Backup', + name: '租户备份', + }, + { + path: 'backup/new', + component: 'Tenant/Detail/NewBackup', + name: '新建租户备份', + }, + { + path: 'monitor', + component: 'Tenant/Detail/Monitor', + name: '租户详情监控', + }, + { + path: '/tenant/:tenantId', + redirect: 'overview', + name: '概览页', + }, + { + path: '/tenant/:tenantId/connection', + component: 'Tenant/Detail/Connection', + name: '租户连接', + }, + ], }, ], }, - { - path:'tenant/:tenantId', - component:'Tenant/Detail', - name:'租户详情', - routes:[ - { - path: 'overview', - component: 'Tenant/Detail/Overview', - name: '概览页', - }, - { - path: 'topo', - component: 'Tenant/Detail/Topo', - name: '租户拓扑图', - }, - { - path: 'backup', - component: 'Tenant/Detail/Backup', - name: '租户备份', - }, - { - path: 'backup/new', - component: 'Tenant/Detail/NewBackup', - name: '新建租户备份', - }, - { - path:'monitor', - component:'Tenant/Detail/Monitor', - name:'租户详情监控' - }, - { - path: '/tenant/:tenantId', - redirect: 'overview', - name: '概览页', - }, - { - path: '/tenant/:tenantId/connection', - component: 'Tenant/Detail/Connection', - name: '租户连接', - }, - ] - }, { path: '/login', component: 'Login', diff --git a/ui/src/components/TopoComponent/constants.ts b/ui/src/components/TopoComponent/constants.ts index 8a115e785..e965487a1 100644 --- a/ui/src/components/TopoComponent/constants.ts +++ b/ui/src/components/TopoComponent/constants.ts @@ -1,4 +1,5 @@ import { intl } from '@/utils/intl'; +import type { GraphNodeType } from './helper'; type OperateTypeLabel = { value: string; label: string; disabled?: boolean }[]; const clusterOperate: OperateTypeLabel = [ @@ -39,6 +40,7 @@ const zoneOperate: OperateTypeLabel = [ id: 'dashboard.Detail.Topo.constants.DeleteZone', defaultMessage: '删除zone', }), + disabled: false, }, ]; @@ -78,7 +80,7 @@ const clusterOperateOfTenant: OperateTypeLabel = [ const getZoneOperateOfTenant = ( haveResourcePool: boolean, - tenantReplicas: API.ReplicaDetailType[] + tenantReplicas: API.ReplicaDetailType[], ): OperateTypeLabel => { return haveResourcePool ? [ @@ -88,7 +90,7 @@ const getZoneOperateOfTenant = ( id: 'Dashboard.components.TopoComponent.constants.EditResourcePool', defaultMessage: '编辑资源池', }), - disabled: false + disabled: false, }, { value: 'deleteResourcePool', @@ -96,7 +98,7 @@ const getZoneOperateOfTenant = ( id: 'Dashboard.components.TopoComponent.constants.DeleteAResourcePool', defaultMessage: '删除资源池', }), - disabled: tenantReplicas.length <= 2 + disabled: tenantReplicas.length <= 2, }, ] : [ @@ -106,14 +108,26 @@ const getZoneOperateOfTenant = ( id: 'Dashboard.components.TopoComponent.constants.AddAResourcePool', defaultMessage: '新增资源池', }), - disabled: false + disabled: false, }, ]; }; +const getZoneOperateOfCluster = ( + topoData: GraphNodeType | undefined, +): OperateTypeLabel => { + if (!topoData) return []; + const isDisabled = topoData?.children?.length <= 2; + zoneOperate.forEach((operate) => { + if (operate.value === 'deleteZone') operate.disabled = isDisabled; + }); + return zoneOperate; +}; + export { clusterOperate, clusterOperateOfTenant, + getZoneOperateOfCluster, getZoneOperateOfTenant, serverOperate, zoneOperate, diff --git a/ui/src/components/TopoComponent/helper.ts b/ui/src/components/TopoComponent/helper.ts index 3c9d1ea48..b27739e8b 100644 --- a/ui/src/components/TopoComponent/helper.ts +++ b/ui/src/components/TopoComponent/helper.ts @@ -33,7 +33,7 @@ type TooltipInfo = { minIops: number; }; -type GraphNodeType = { +export type GraphNodeType = { id: string; label: string; status: string; diff --git a/ui/src/components/TopoComponent/index.tsx b/ui/src/components/TopoComponent/index.tsx index cd8c2b93c..357325096 100644 --- a/ui/src/components/TopoComponent/index.tsx +++ b/ui/src/components/TopoComponent/index.tsx @@ -6,13 +6,15 @@ import { useRequest,useUpdateEffect } from 'ahooks'; import { message } from 'antd'; import _ from 'lodash'; import { ReactElement,useEffect,useMemo,useRef,useState } from 'react'; +import { useModel } from '@umijs/max'; import showDeleteConfirm from '@/components/customModal/DeleteModal'; import OperateModal from '@/components/customModal/OperateModal'; import { RESULT_STATUS } from '@/constants'; import BasicInfo from '@/pages/Cluster/Detail/Overview/BasicInfo'; -import { getClusterFromTenant,getOriginResourceUsages,getZonesOptions } from '@/pages/Tenant/helper'; -import { deleteObcluster,deleteObzone,getClusterDetailReq } from '@/services'; +import { getClusterFromTenant, getOriginResourceUsages, getZonesOptions } from '@/pages/Tenant/helper'; +import { getClusterDetailReq } from '@/services'; +import { deleteClusterReportWrap, deleteObzoneReportWrap } from '@/services/reportRequest/clusterReportReq'; import { deleteObtenantPool } from '@/services/tenant'; import { getNSName } from '../../pages/Cluster/Detail/Overview/helper'; import { ReactNode,config } from './G6register'; @@ -21,8 +23,8 @@ import { clusterOperate, clusterOperateOfTenant, getZoneOperateOfTenant, +getZoneOperateOfCluster, serverOperate, -zoneOperate, } from './constants'; import { appenAutoShapeListener,checkIsSame,getServerNumber,haveDisabledOperate } from './helper'; @@ -105,7 +107,7 @@ export default function TopoComponent({ getZoneOperateOfTenant(haveResourcePool, tenantReplicas), ); } else { - setOprateList(zoneOperate); + setOprateList(getZoneOperateOfCluster(originTopoData?.topoData)); } chooseZoneName.current = zone; break; @@ -121,7 +123,7 @@ export default function TopoComponent({ }; //delete cluster const clusterDelete = async () => { - const res = await deleteObcluster({ ns, name }); + const res = await deleteClusterReportWrap({ ns, name }); if (res.successful) { message.success(res.message); getTopoData({ ns, name, useFor: 'topo', tenantReplicas }); @@ -129,7 +131,7 @@ export default function TopoComponent({ }; //delete zone const zoneDelete = async () => { - const res = await deleteObzone({ + const res = await deleteObzoneReportWrap({ ns, name, zoneName: chooseZoneName.current, diff --git a/ui/src/components/customModal/ActivateTenantModal.tsx b/ui/src/components/customModal/ActivateTenantModal.tsx index d6643197a..27b715c9b 100644 --- a/ui/src/components/customModal/ActivateTenantModal.tsx +++ b/ui/src/components/customModal/ActivateTenantModal.tsx @@ -23,13 +23,13 @@ export default function ActivateTenantModal({ }), ); setVisible(false); - successCallback(); + if(successCallback)successCallback(); } }, }); const handleSubmit = async () => { const [ns, name] = getNSName(); - await activateTenant({ ns, name }); + await activateTenant({ ns, name, failover: true }); }; const handleCancel = () => setVisible(false); diff --git a/ui/src/components/customModal/AddNSModal.tsx b/ui/src/components/customModal/AddNSModal.tsx index 7c3c27030..a787dafc8 100644 --- a/ui/src/components/customModal/AddNSModal.tsx +++ b/ui/src/components/customModal/AddNSModal.tsx @@ -25,7 +25,7 @@ export default function AddNSModal({ }), ); setVisible(false); - successCallback(newNamespace.current); + if(successCallback)successCallback(newNamespace.current); } }, }); diff --git a/ui/src/components/customModal/AddZoneModal.tsx b/ui/src/components/customModal/AddZoneModal.tsx index a3b448d19..e39bd5d0e 100644 --- a/ui/src/components/customModal/AddZoneModal.tsx +++ b/ui/src/components/customModal/AddZoneModal.tsx @@ -3,7 +3,7 @@ import { Form, Input, message } from 'antd'; import { RULER_ZONE } from '@/constants/rules'; import { getNSName } from '@/pages/Cluster/Detail/Overview/helper'; -import { addObzone } from '@/services'; +import { addObzoneReportWrap } from '@/services/reportRequest/clusterReportReq'; import InputNumber from '../InputNumber'; import type { CommonModalType } from '.'; import CustomModal from '.'; @@ -19,7 +19,6 @@ export default function AddZoneModal({ successCallback, }: CommonModalType) { const [form] = Form.useForm(); - const handleSubmit = async () => { try { await form.validateFields(); @@ -33,10 +32,10 @@ export default function AddZoneModal({ } const onFinish = async (values: any) => { const [namespace, name] = getNSName(); - const res = await addObzone({ namespace, name, ...values }); + const res = await addObzoneReportWrap({ namespace, name, ...values}); if (res.successful) { message.success(res.message); - successCallback(); + if(successCallback) successCallback(); form.resetFields(); setVisible(false); } diff --git a/ui/src/components/customModal/LogReplayModal.tsx b/ui/src/components/customModal/LogReplayModal.tsx index 0586726cf..922300e44 100644 --- a/ui/src/components/customModal/LogReplayModal.tsx +++ b/ui/src/components/customModal/LogReplayModal.tsx @@ -29,7 +29,7 @@ export default function LogReplayModal({ const res = await replayLogOfTenant({ namespace, name, ...values }); if (res.successful) { message.success(res.message); - successCallback(); + if(successCallback) successCallback(); form.resetFields(); setVisible(false); } diff --git a/ui/src/components/customModal/ModifyPasswordModal.tsx b/ui/src/components/customModal/ModifyPasswordModal.tsx index bf0f29f67..69b13e69c 100644 --- a/ui/src/components/customModal/ModifyPasswordModal.tsx +++ b/ui/src/components/customModal/ModifyPasswordModal.tsx @@ -36,7 +36,7 @@ export default function ModifyPasswordModal({ }); if (res.successful) { message.success(res.message); - successCallback(); + if(successCallback) successCallback(); form.resetFields(); setVisible(false); } diff --git a/ui/src/components/customModal/ModifyUnitDetailModal.tsx b/ui/src/components/customModal/ModifyUnitDetailModal.tsx index 51258ef7c..d2b48b3ea 100644 --- a/ui/src/components/customModal/ModifyUnitDetailModal.tsx +++ b/ui/src/components/customModal/ModifyUnitDetailModal.tsx @@ -12,7 +12,10 @@ import { findMinParameter, modifyZoneCheckedStatus, } from '@/pages/Tenant/helper'; -import { createObtenantPool,patchObtenantPool } from '@/services/tenant'; +import { +patchObtenantPoolReportWrap, +createTenantReportWrap +} from '@/services/reportRequest/tenantReportReq'; import { formatPatchPoolData } from '@/utils/helper'; import { intl } from '@/utils/intl'; import { useEffect,useState } from 'react'; @@ -90,8 +93,8 @@ export default function ModifyUnitDetailModal({ ); const selectZone = Form.useWatch('selectZone', form); const obtenantPoolReq = newResourcePool - ? createObtenantPool - : patchObtenantPool; + ? createTenantReportWrap + : patchObtenantPoolReportWrap; const handleSubmit = async () => { try { diff --git a/ui/src/components/customModal/ModifyUnitModal.tsx b/ui/src/components/customModal/ModifyUnitModal.tsx index 8f7e89dc8..3e082fd25 100644 --- a/ui/src/components/customModal/ModifyUnitModal.tsx +++ b/ui/src/components/customModal/ModifyUnitModal.tsx @@ -1,5 +1,5 @@ import { getNSName } from '@/pages/Cluster/Detail/Overview/helper'; -import { patchTenantConfiguration } from '@/services/tenant'; +import { modifyUnitNumReportWrap } from '@/services/reportRequest/tenantReportReq'; import { intl } from '@/utils/intl'; import { Form,InputNumber,message } from 'antd'; import { useEffect } from 'react'; @@ -30,7 +30,7 @@ export default function ModifyUnitModal({ const handleCancel = () => setVisible(false); const onFinish = async (values: any) => { const [namespace, name] = getNSName(); - const res = await patchTenantConfiguration({ + const res = await modifyUnitNumReportWrap({ ns: namespace, name, ...values, @@ -43,7 +43,7 @@ export default function ModifyUnitModal({ defaultMessage: '修改成功', }), ); - successCallback(); + if(successCallback) successCallback(); form.resetFields(); setVisible(false); } diff --git a/ui/src/components/customModal/ScaleModal.tsx b/ui/src/components/customModal/ScaleModal.tsx index 22b29de46..2bc90b3d6 100644 --- a/ui/src/components/customModal/ScaleModal.tsx +++ b/ui/src/components/customModal/ScaleModal.tsx @@ -3,7 +3,7 @@ import { Form, InputNumber, message } from 'antd'; import CustomModal from '.'; import { getNSName } from '@/pages/Cluster/Detail/Overview/helper'; -import { scaleObserver } from '@/services'; +import { scaleObserverReportWrap } from '@/services/reportRequest/clusterReportReq'; import { useEffect } from 'react'; import type { CommonModalType } from '.'; @@ -32,7 +32,7 @@ export default function ScaleModal({ const onFinish = async (val: any) => { if (!zoneName) throw new Error('zoneName is not defined'); const [namespace, name] = getNSName(); - const res = await scaleObserver({ + const res = await scaleObserverReportWrap({ namespace, name, zoneName, @@ -40,7 +40,7 @@ export default function ScaleModal({ }); if (res.successful) { message.success(res.message); - successCallback(); + if(successCallback) successCallback(); form.resetFields(); setVisible(false); } diff --git a/ui/src/components/customModal/SwitchTenantModal.tsx b/ui/src/components/customModal/SwitchTenantModal.tsx index 402f1870b..b5ffb43e3 100644 --- a/ui/src/components/customModal/SwitchTenantModal.tsx +++ b/ui/src/components/customModal/SwitchTenantModal.tsx @@ -16,20 +16,15 @@ export default function SwitchTenantModal({ manual: true, onSuccess: ({ successful }) => { if (successful) { - message.success( - intl.formatMessage({ - id: 'Dashboard.components.customModal.SwitchTenantModal.TheStandbyTenantHasBeen', - defaultMessage: '激活备租户成功', - }), - ); + message.success('操作成功'); setVisible(false); - successCallback(); + if(successCallback) successCallback(); } }, }); const handleSubmit = async () => { const [ns, name] = getNSName(); - await activateTenant({ ns, name }); + await activateTenant({ ns, name, switchover: true }); }; const handleCancel = () => setVisible(false); diff --git a/ui/src/components/customModal/UpgradeModal.tsx b/ui/src/components/customModal/UpgradeModal.tsx index 754e67ed2..ef145912e 100644 --- a/ui/src/components/customModal/UpgradeModal.tsx +++ b/ui/src/components/customModal/UpgradeModal.tsx @@ -2,7 +2,7 @@ import { intl } from '@/utils/intl'; import { Form, Input, message } from 'antd'; import { getNSName } from '@/pages/Cluster/Detail/Overview/helper'; -import { upgradeObcluster } from '@/services'; +import { upgradeClusterReportWrap } from '@/services/reportRequest/clusterReportReq'; import type { CommonModalType } from '.'; import CustomModal from '.'; @@ -15,7 +15,6 @@ export default function UpgradeModal({ successCallback, }: CommonModalType) { const [form] = Form.useForm(); - const handleSubmit = async () => { try { await form.validateFields(); @@ -26,10 +25,10 @@ export default function UpgradeModal({ const handleCancel = () => setVisible(false); const onFinish = async ({ image }: any) => { const [ns, name] = getNSName(); - const res = await upgradeObcluster({ ns, name, image }); + const res = await upgradeClusterReportWrap({ ns, name, image }); if (res.successful) { message.success(res.message); - successCallback(); + if(successCallback) successCallback(); form.resetFields(); setVisible(false); } diff --git a/ui/src/components/customModal/UpgradeTenantModal.tsx b/ui/src/components/customModal/UpgradeTenantModal.tsx index 583cd1beb..8140c1423 100644 --- a/ui/src/components/customModal/UpgradeTenantModal.tsx +++ b/ui/src/components/customModal/UpgradeTenantModal.tsx @@ -3,7 +3,7 @@ import { useRequest } from 'ahooks'; import { message } from 'antd'; import { getNSName } from '@/pages/Cluster/Detail/Overview/helper'; -import { changeTenantRole } from '@/services/tenant'; +import { upgradeTenantCompatibilityVersion } from '@/services/tenant'; import type { CommonModalType } from '.'; import CustomModal from '.'; @@ -12,7 +12,7 @@ export default function UpgradeTenantModal({ setVisible, successCallback, }: CommonModalType) { - const { run: activateTenant } = useRequest(changeTenantRole, { + const { run: upgradeTenant } = useRequest(upgradeTenantCompatibilityVersion, { manual: true, onSuccess: ({ successful }) => { if (successful) { @@ -23,13 +23,13 @@ export default function UpgradeTenantModal({ }), ); setVisible(false); - successCallback(); + if(successCallback) successCallback(); } }, }); const handleSubmit = async () => { const [ns, name] = getNSName(); - await activateTenant({ ns, name }); + await upgradeTenant({ ns, name }); }; const handleCancel = () => setVisible(false); diff --git a/ui/src/constants/index.ts b/ui/src/constants/index.ts index 63502c651..c63af7442 100644 --- a/ui/src/constants/index.ts +++ b/ui/src/constants/index.ts @@ -49,6 +49,12 @@ const REFRESH_FREQUENCY = 15; // Number of monitoring points const POINT_NUMBER = 15; +// two minutes +const CHECK_STORAGE_INTERVAL = 1000 * 120; + +// three hours +const STATISTICS_INTERVAL = 1000 * 60 * 60 * 3; + const SUFFIX_UNIT = 'GB'; const MINIMAL_CONFIG = { @@ -150,6 +156,7 @@ const MODE_MAP = new Map([ export { BACKUP_RESULT_STATUS, BADGE_IMG_MAP, + CHECK_STORAGE_INTERVAL, CLUSTER_IMG_MAP, CLUSTER_INFO_CONFIG, COLOR_MAP, @@ -163,6 +170,7 @@ export { RESOURCE_NAME_REG, RESULT_STATUS, SERVER_IMG_MAP, + STATISTICS_INTERVAL, STATUS, SUFFIX_UNIT, TOPO_INFO_CONFIG, diff --git a/ui/src/hook/usePublicKey.ts b/ui/src/hook/usePublicKey.ts index d6cd77638..4a09d4e47 100644 --- a/ui/src/hook/usePublicKey.ts +++ b/ui/src/hook/usePublicKey.ts @@ -1,13 +1,13 @@ import React, { useEffect } from 'react'; -import { infoReq } from '@/services'; +import { getAppInfoFromStorage } from '@/utils/helper'; import JSEncrypt from 'jsencrypt'; export const usePublicKey = () => { const [publicKey, setPublicKey] = React.useState(''); useEffect(() => { - infoReq().then((res) => { - setPublicKey(res.data.publicKey); + getAppInfoFromStorage().then((appInfo) => { + setPublicKey(appInfo.publicKey); }).catch((err) => { console.log(err) }); diff --git a/ui/src/models/global.ts b/ui/src/models/global.ts index 4e4ac88e5..668be4713 100644 --- a/ui/src/models/global.ts +++ b/ui/src/models/global.ts @@ -1,16 +1,15 @@ -import { useState } from 'react'; +import { useRef, useState } from 'react'; // Global shared data export default () => { const [chooseClusterName, setChooseClusterName] = useState(''); const [userName, setUsername] = useState(); - const [appInfo, setAppInfo] = useState({}); + const reportDataInterval = useRef(); return { chooseClusterName, setChooseClusterName, userName, setUsername, - appInfo, - setAppInfo, + reportDataInterval, }; }; diff --git a/ui/src/pages/Cluster/Detail/Overview/ZoneTable.tsx b/ui/src/pages/Cluster/Detail/Overview/ZoneTable.tsx index bc022d915..5f8197435 100644 --- a/ui/src/pages/Cluster/Detail/Overview/ZoneTable.tsx +++ b/ui/src/pages/Cluster/Detail/Overview/ZoneTable.tsx @@ -4,7 +4,7 @@ import type { ColumnType } from 'antd/es/table'; import showDeleteConfirm from '@/components/customModal/DeleteModal'; import { COLOR_MAP } from '@/constants'; -import { deleteObzone } from '@/services'; +import { deleteObzoneReportWrap } from '@/services/reportRequest/clusterReportReq'; import { getNSName } from './helper'; interface ZoneTableProps { @@ -86,7 +86,7 @@ export default function ZoneTable({ return ( <>